]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospfd.c
*: auto-convert to SPDX License IDs
[mirror_frr.git] / ospfd / ospfd.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
718e3744 2/* OSPF version 2 daemon program.
896014f4 3 * Copyright (C) 1999, 2000 Toshiaki Takada
896014f4 4 */
718e3744 5
6#include <zebra.h>
7
8#include "thread.h"
9#include "vty.h"
10#include "command.h"
11#include "linklist.h"
12#include "prefix.h"
13#include "table.h"
14#include "if.h"
15#include "memory.h"
16#include "stream.h"
17#include "log.h"
d62a17ae 18#include "sockunion.h" /* for inet_aton () */
718e3744 19#include "zclient.h"
ded42248 20#include "routemap.h"
718e3744 21#include "plist.h"
f102e75f 22#include "sockopt.h"
567b877d 23#include "bfd.h"
8879bd22 24#include "libfrr.h"
8efe88ea 25#include "defaults.h"
313d7993 26#include "lib_errors.h"
132a782e 27#include "ldp_sync.h"
718e3744 28
29#include "ospfd/ospfd.h"
659f4e40 30#include "ospfd/ospf_bfd.h"
718e3744 31#include "ospfd/ospf_network.h"
32#include "ospfd/ospf_interface.h"
33#include "ospfd/ospf_ism.h"
34#include "ospfd/ospf_asbr.h"
35#include "ospfd/ospf_lsa.h"
36#include "ospfd/ospf_lsdb.h"
37#include "ospfd/ospf_neighbor.h"
38#include "ospfd/ospf_nsm.h"
39#include "ospfd/ospf_spf.h"
40#include "ospfd/ospf_packet.h"
41#include "ospfd/ospf_dump.h"
19c0412a 42#include "ospfd/ospf_route.h"
718e3744 43#include "ospfd/ospf_zebra.h"
44#include "ospfd/ospf_abr.h"
45#include "ospfd/ospf_flood.h"
718e3744 46#include "ospfd/ospf_ase.h"
132a782e 47#include "ospfd/ospf_ldp_sync.h"
cd52c44c 48#include "ospfd/ospf_gr.h"
44038c7a 49#include "ospfd/ospf_apiserver.h"
718e3744 50
6b0655a2 51
96244aca 52DEFINE_QOBJ_TYPE(ospf);
edd7c245 53
020709f9 54/* OSPF process wide configuration. */
55static struct ospf_master ospf_master;
56
57/* OSPF process wide configuration pointer to export. */
58struct ospf_master *om;
718e3744 59
409f98ab
IR
60unsigned short ospf_instance;
61
718e3744 62extern struct zclient *zclient;
63
6b0655a2 64
d62a17ae 65static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
66static void ospf_network_free(struct ospf *, struct ospf_network *);
67static void ospf_area_free(struct ospf_area *);
68static void ospf_network_run(struct prefix *, struct ospf_area *);
69static void ospf_network_run_interface(struct ospf *, struct interface *,
70 struct prefix *, struct ospf_area *);
71static void ospf_network_run_subnet(struct ospf *, struct connected *,
72 struct prefix *, struct ospf_area *);
73static int ospf_network_match_iface(const struct connected *,
74 const struct prefix *);
75static void ospf_finish_final(struct ospf *);
718e3744 76
594f80c8 77/* API to clean refresh queues and LSAs */
78static void ospf_free_refresh_queue(struct ospf *ospf)
79{
80 for (int i = 0; i < OSPF_LSA_REFRESHER_SLOTS; i++) {
81 struct list *list = ospf->lsa_refresh_queue.qs[i];
82 struct listnode *node, *nnode;
83 struct ospf_lsa *lsa;
84
85 if (list) {
86 for (ALL_LIST_ELEMENTS(list, node, nnode, lsa)) {
87 listnode_delete(list, lsa);
88 lsa->refresh_list = -1;
89 ospf_lsa_unlock(&lsa);
90 }
91 list_delete(&list);
92 ospf->lsa_refresh_queue.qs[i] = NULL;
93 }
94 }
95}
718e3744 96#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
6b0655a2 97
7fd0729f
G
98int p_spaces_compare_func(const struct p_space *a, const struct p_space *b)
99{
385a1e07
G
100 if (a->protected_resource->type == OSPF_TI_LFA_LINK_PROTECTION
101 && b->protected_resource->type == OSPF_TI_LFA_LINK_PROTECTION)
102 return (a->protected_resource->link->link_id.s_addr
103 - b->protected_resource->link->link_id.s_addr);
104
105 if (a->protected_resource->type == OSPF_TI_LFA_NODE_PROTECTION
106 && b->protected_resource->type == OSPF_TI_LFA_NODE_PROTECTION)
107 return (a->protected_resource->router_id.s_addr
108 - b->protected_resource->router_id.s_addr);
109
110 /* This should not happen */
111 return 0;
7fd0729f
G
112}
113
114int q_spaces_compare_func(const struct q_space *a, const struct q_space *b)
115{
116 return (a->root->id.s_addr - b->root->id.s_addr);
117}
118
119DECLARE_RBTREE_UNIQ(p_spaces, struct p_space, p_spaces_item,
960b9a53 120 p_spaces_compare_func);
7fd0729f 121
f91ce319 122void ospf_process_refresh_data(struct ospf *ospf, bool reset)
718e3744 123{
f4e14fdb 124 struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
d62a17ae 125 struct in_addr router_id, router_id_old;
126 struct ospf_interface *oi;
127 struct interface *ifp;
f91ce319
MR
128 struct listnode *node, *nnode;
129 struct ospf_area *area;
130 bool rid_change = false;
2c19a6ec 131
d62a17ae 132 if (!ospf->oi_running) {
133 if (IS_DEBUG_OSPF_EVENT)
134 zlog_debug(
135 "Router ospf not configured -- Router-ID update postponed");
136 return;
25a346eb 137 }
718e3744 138
d62a17ae 139 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
140 zlog_debug("Router-ID[OLD:%pI4]: Update",
141 &ospf->router_id);
d62a17ae 142
143 router_id_old = ospf->router_id;
144
145 /* Select the router ID based on these priorities:
146 1. Statically assigned router ID is always the first choice.
147 2. If there is no statically assigned router ID, then try to stick
148 with the most recent value, since changing router ID's is very
149 disruptive.
150 3. Last choice: just go with whatever the zebra daemon recommends.
151 */
3a6290bd 152 if (ospf->router_id_static.s_addr != INADDR_ANY)
d62a17ae 153 router_id = ospf->router_id_static;
3a6290bd 154 else if (ospf->router_id.s_addr != INADDR_ANY)
d62a17ae 155 router_id = ospf->router_id;
156 else
6021c6c0 157 router_id = ospf->router_id_zebra;
d62a17ae 158
b5a8894d 159 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
160 zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4",
161 &ospf->router_id, &router_id);
d62a17ae 162
f91ce319
MR
163 rid_change = !(IPV4_ADDR_SAME(&router_id_old, &router_id));
164 if (rid_change || (reset)) {
d62a17ae 165 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
166 /* Some nbrs are identified by router_id, these needs
167 * to be rebuilt. Possible optimization would be to do
168 * oi->nbr_self->router_id = router_id for
169 * !(virtual | ptop) links
170 */
171 ospf_nbr_self_reset(oi, router_id);
7e0274f8
DS
172
173 /*
174 * If the old router id was not set, but now it
175 * is and the interface is operative and the
176 * state is ISM_Down we should kick the state
177 * machine as that we processed the interfaces
178 * based upon the network statement( or intf config )
179 * but could not start it at that time.
180 */
181 if (if_is_operative(oi->ifp) && oi->state == ISM_Down
182 && router_id_old.s_addr == INADDR_ANY)
183 ospf_if_up(oi);
d62a17ae 184 }
185
f91ce319
MR
186 /* Flush (inline) all the self originated LSAs */
187 ospf_flush_self_originated_lsas_now(ospf);
d62a17ae 188
189 ospf->router_id = router_id;
190 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
191 zlog_debug("Router-ID[NEW:%pI4]: Update",
192 &ospf->router_id);
d62a17ae 193
194 /* Flush (inline) all external LSAs which now match the new
195 router-id,
0437e105 196 need to adjust the OSPF_LSA_SELF flag, so the flush doesn't
d62a17ae 197 hit
198 asserts in ospf_refresher_unregister_lsa(). This step is
199 needed
b72aae2e 200 because the current frr code does look-up for
d62a17ae 201 self-originated LSAs
202 based on the self router-id alone but expects OSPF_LSA_SELF
203 to be
204 properly set */
205 if (ospf->lsdb) {
206 struct route_node *rn;
207 struct ospf_lsa *lsa;
208
044506e7 209 LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
d62a17ae 210 /* AdvRouter and Router ID is the same. */
211 if (IPV4_ADDR_SAME(&lsa->data->adv_router,
f91ce319 212 &ospf->router_id) && rid_change) {
d62a17ae 213 SET_FLAG(lsa->flags,
214 OSPF_LSA_SELF_CHECKED);
215 SET_FLAG(lsa->flags, OSPF_LSA_SELF);
216 ospf_lsa_flush_schedule(ospf, lsa);
217 }
f91ce319
MR
218 /* The above flush will send immediately
219 * So discard the LSA to originate new
220 */
221 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
d62a17ae 222 }
f91ce319
MR
223
224 LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
225 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
226
227 ospf_lsdb_delete_all(ospf->lsdb);
d62a17ae 228 }
229
8fb693a4
MR
230 /* Since the LSAs are deleted, need reset the aggr flag */
231 ospf_unset_all_aggr_flag(ospf);
232
f91ce319
MR
233 /* Delete the LSDB */
234 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
235 ospf_area_lsdb_discard_delete(area);
236
d62a17ae 237 /* update router-lsa's for each area */
238 ospf_router_lsa_update(ospf);
239
240 /* update ospf_interface's */
f91ce319
MR
241 FOR_ALL_INTERFACES (vrf, ifp) {
242 if (reset)
243 ospf_if_reset(ifp);
244 else
245 ospf_if_update(ospf, ifp);
246 }
fa3c7c7e
DL
247
248 ospf_external_lsa_rid_change(ospf);
44038c7a
CH
249
250#ifdef SUPPORT_OSPF_API
251 ospf_apiserver_clients_notify_router_id_change(router_id);
252#endif
718e3744 253 }
f91ce319
MR
254
255 ospf->inst_shutdown = 0;
256}
257
258void ospf_router_id_update(struct ospf *ospf)
259{
260 ospf_process_refresh_data(ospf, false);
261}
262
263void ospf_process_reset(struct ospf *ospf)
264{
265 ospf_process_refresh_data(ospf, true);
266}
267
268void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
269 const char *nbr_str)
270{
271 struct route_node *rn;
272 struct ospf_neighbor *nbr;
273 struct ospf_interface *oi;
274 struct listnode *node;
275
276 /* Clear only a particular nbr with nbr router id as nbr_id */
277 if (nbr_str != NULL) {
278 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
279 nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &nbr_id);
280 if (nbr)
281 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
282 }
283 return;
284 }
285
286 /* send Neighbor event KillNbr to all associated neighbors. */
287 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
288 for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
289 nbr = rn->info;
290 if (nbr && (nbr != oi->nbr_self))
291 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
292 }
293 }
718e3744 294}
6b0655a2 295
718e3744 296/* For OSPF area sort by area id. */
d62a17ae 297static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2)
718e3744 298{
d62a17ae 299 if (ntohl(a1->area_id.s_addr) > ntohl(a2->area_id.s_addr))
300 return 1;
301 if (ntohl(a1->area_id.s_addr) < ntohl(a2->area_id.s_addr))
302 return -1;
303 return 0;
718e3744 304}
305
5bd78355
IR
306static void ospf_add(struct ospf *ospf)
307{
308 listnode_add(om->ospf, ospf);
309}
310
311static void ospf_delete(struct ospf *ospf)
312{
313 listnode_delete(om->ospf, ospf);
314}
315
7fd0729f 316struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
718e3744 317{
d62a17ae 318 int i;
b5a8894d 319 struct vrf *vrf = NULL;
718e3744 320
d62a17ae 321 struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
718e3744 322
d62a17ae 323 new->instance = instance;
324 new->router_id.s_addr = htonl(0);
325 new->router_id_static.s_addr = htonl(0);
ac2cb9bf
IR
326
327 vrf = vrf_lookup_by_name(name);
328 if (vrf)
329 new->vrf_id = vrf->vrf_id;
330 else
331 new->vrf_id = VRF_UNKNOWN;
332
333 /* Freed in ospf_finish_final */
334 new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
335 if (IS_DEBUG_OSPF_EVENT)
336 zlog_debug(
337 "%s: Create new ospf instance with vrf_name %s vrf_id %u",
338 __func__, name, new->vrf_id);
a2d7fdfe 339
340 if (vrf)
341 ospf_vrf_link(new, vrf);
342
b5a8894d
CS
343 ospf_zebra_vrf_register(new);
344
d62a17ae 345 new->abr_type = OSPF_ABR_DEFAULT;
346 new->oiflist = list_new();
347 new->vlinks = list_new();
348 new->areas = list_new();
349 new->areas->cmp = (int (*)(void *, void *))ospf_area_id_cmp;
350 new->networks = route_table_init();
351 new->nbr_nbma = route_table_init();
718e3744 352
d62a17ae 353 new->lsdb = ospf_lsdb_new();
718e3744 354
d62a17ae 355 new->default_originate = DEFAULT_ORIGINATE_NONE;
718e3744 356
d62a17ae 357 new->passive_interface_default = OSPF_IF_ACTIVE;
4ba4fc85 358
d62a17ae 359 new->new_external_route = route_table_init();
360 new->old_external_route = route_table_init();
361 new->external_lsas = route_table_init();
362
363 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
364 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
365 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
366
367 /* Distribute parameter init. */
368 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
369 new->dtag[i] = 0;
370 }
371 new->default_metric = -1;
372 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
373
374 /* LSA timers */
375 new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
376 new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
377
378 /* SPF timer value init. */
379 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
380 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
381 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
382 new->spf_hold_multiplier = 1;
383
384 /* MaxAge init. */
385 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
386 new->maxage_lsa = route_table_init();
387 new->t_maxage_walker = NULL;
5bd78355
IR
388 thread_add_timer(master, ospf_lsa_maxage_walker, new,
389 OSPF_LSA_MAXAGE_CHECK_INTERVAL, &new->t_maxage_walker);
d62a17ae 390
3d5b9855 391 /* Max paths initialization */
392 new->max_multipath = MULTIPATH_NUM;
393
d62a17ae 394 /* Distance table init. */
395 new->distance_table = route_table_init();
396
397 new->lsa_refresh_queue.index = 0;
398 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
b345a3d9 399 new->lsa_refresh_timer = OSPF_LS_REFRESH_TIME;
d62a17ae 400 new->t_lsa_refresher = NULL;
5bd78355
IR
401 thread_add_timer(master, ospf_lsa_refresh_walker, new,
402 new->lsa_refresh_interval, &new->t_lsa_refresher);
d62a17ae 403 new->lsa_refresher_started = monotime(NULL);
404
266469eb
DS
405 new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1);
406
d62a17ae 407 new->t_read = NULL;
d62a17ae 408 new->oi_write_q = list_new();
409 new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
410
a92706bb
JU
411 new->proactive_arp = OSPF_PROACTIVE_ARP_DEFAULT;
412
51f8588e 413 ospf_gr_helper_instance_init(new);
06bc3110 414
ad7222b7 415 ospf_asbr_external_aggregator_init(new);
416
5bd78355
IR
417 ospf_opaque_type11_lsa_init(new);
418
d62a17ae 419 QOBJ_REG(new, ospf);
ae19c240 420
3c0eb8fa 421 new->fd = -1;
7fd0729f
G
422
423 return new;
424}
425
426/* Allocate new ospf structure. */
427static struct ospf *ospf_new(unsigned short instance, const char *name)
428{
429 struct ospf *new;
430
431 new = ospf_new_alloc(instance, name);
5bd78355
IR
432 ospf_add(new);
433
434 if (new->vrf_id == VRF_UNKNOWN)
435 return new;
7fd0729f 436
3c0eb8fa 437 if ((ospf_sock_init(new)) < 0) {
5bd78355
IR
438 flog_err(EC_LIB_SOCKET,
439 "%s: ospf_sock_init is unable to open a socket",
440 __func__);
3c0eb8fa
PG
441 return new;
442 }
7fd0729f 443
3c0eb8fa
PG
444 thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
445
5bd78355
IR
446 new->oi_running = 1;
447 ospf_router_id_update(new);
448
10514170
RW
449 /*
450 * Read from non-volatile memory whether this instance is performing a
451 * graceful restart or not.
452 */
453 ospf_gr_nvm_read(new);
454
d62a17ae 455 return new;
718e3744 456}
457
d7c0a89a 458struct ospf *ospf_lookup_instance(unsigned short instance)
7c8ff89e 459{
d62a17ae 460 struct ospf *ospf;
461 struct listnode *node, *nnode;
7c8ff89e 462
d62a17ae 463 if (listcount(om->ospf) == 0)
464 return NULL;
7c8ff89e 465
d62a17ae 466 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
467 if ((ospf->instance == 0 && instance == 0)
468 || (ospf->instance && instance
469 && ospf->instance == instance))
470 return ospf;
7c8ff89e 471
d62a17ae 472 return NULL;
7c8ff89e
DS
473}
474
d62a17ae 475static int ospf_is_ready(struct ospf *ospf)
52c62ab8 476{
d62a17ae 477 /* OSPF must be on and Router-ID must be configured. */
975a328e 478 if (!ospf || ospf->router_id.s_addr == INADDR_ANY)
d62a17ae 479 return 0;
480
481 return 1;
52c62ab8
JAG
482}
483
d7c0a89a 484struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
b5a8894d
CS
485{
486 struct ospf *ospf = NULL;
487 struct listnode *node, *nnode;
488
489 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
996c9314
LB
490 if ((ospf->instance == instance)
491 && ((ospf->name == NULL && name == NULL)
492 || (ospf->name && name
493 && strcmp(ospf->name, name) == 0)))
b5a8894d
CS
494 return ospf;
495 }
496 return NULL;
497}
498
409f98ab 499struct ospf *ospf_lookup(unsigned short instance, const char *name)
c3391da1
IR
500{
501 struct ospf *ospf;
502
409f98ab
IR
503 if (ospf_instance) {
504 ospf = ospf_lookup_instance(instance);
505 } else {
b5a8894d 506 ospf = ospf_lookup_by_inst_name(instance, name);
d62a17ae 507 }
7c8ff89e 508
d62a17ae 509 return ospf;
7c8ff89e
DS
510}
511
409f98ab 512struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
7c8ff89e 513{
d62a17ae 514 struct ospf *ospf;
7c8ff89e 515
409f98ab
IR
516 ospf = ospf_lookup(instance, name);
517
c572fbfe 518 *created = (ospf == NULL);
5bd78355 519 if (ospf == NULL)
409f98ab 520 ospf = ospf_new(instance, name);
68980084 521
d62a17ae 522 return ospf;
718e3744 523}
6b0655a2 524
b5a8894d
CS
525struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
526{
527 struct vrf *vrf = NULL;
528
529 vrf = vrf_lookup_by_id(vrf_id);
530 if (!vrf)
531 return NULL;
532 return (vrf->info) ? (struct ospf *)vrf->info : NULL;
b5a8894d
CS
533}
534
cbf32f74
IR
535uint32_t ospf_count_area_params(struct ospf *ospf)
536{
537 struct vrf *vrf;
538 struct interface *ifp;
539 uint32_t count = 0;
540
541 if (ospf->vrf_id != VRF_UNKNOWN) {
542 vrf = vrf_lookup_by_id(ospf->vrf_id);
543
544 FOR_ALL_INTERFACES (vrf, ifp) {
545 count += ospf_if_count_area_params(ifp);
546 }
547 }
548
549 return count;
550}
551
43b8d1d8
CS
552/* It should only be used when processing incoming info update from zebra.
553 * Other situations, it is not sufficient to lookup the ospf instance by
554 * vrf_name only without using the instance number.
555 */
556static struct ospf *ospf_lookup_by_name(const char *vrf_name)
b5a8894d
CS
557{
558 struct ospf *ospf = NULL;
559 struct listnode *node, *nnode;
560
561 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
43b8d1d8 562 if ((ospf->name == NULL && vrf_name == NULL)
996c9314
LB
563 || (ospf->name && vrf_name
564 && strcmp(ospf->name, vrf_name) == 0))
b5a8894d
CS
565 return ospf;
566 return NULL;
567}
568
c9c93d50 569/* Handle the second half of deferred shutdown. This is called either
570 * from the deferred-shutdown timer thread, or directly through
571 * ospf_deferred_shutdown_check.
88d6cf37 572 *
573 * Function is to cleanup G-R state, if required then call ospf_finish_final
574 * to complete shutdown of this ospf instance. Possibly exit if the
575 * whole process is being shutdown and this was the last OSPF instance.
576 */
d62a17ae 577static void ospf_deferred_shutdown_finish(struct ospf *ospf)
578{
579 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
cccd44f3 580 THREAD_OFF(ospf->t_deferred_shutdown);
d62a17ae 581
582 ospf_finish_final(ospf);
583
584 /* *ospf is now invalid */
88d6cf37 585
d62a17ae 586 /* ospfd being shut-down? If so, was this the last ospf instance? */
587 if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)
588 && (listcount(om->ospf) == 0)) {
e15a935c 589 frr_fini();
d62a17ae 590 exit(0);
591 }
592
593 return;
88d6cf37 594}
595
596/* Timer thread for G-R */
cc9f21da 597static void ospf_deferred_shutdown_timer(struct thread *t)
88d6cf37 598{
d62a17ae 599 struct ospf *ospf = THREAD_ARG(t);
600
601 ospf_deferred_shutdown_finish(ospf);
88d6cf37 602}
603
c9c93d50 604/* Check whether deferred-shutdown must be scheduled, otherwise call
88d6cf37 605 * down directly into second-half of instance shutdown.
606 */
d62a17ae 607static void ospf_deferred_shutdown_check(struct ospf *ospf)
608{
609 unsigned long timeout;
610 struct listnode *ln;
611 struct ospf_area *area;
612
613 /* deferred shutdown already running? */
614 if (ospf->t_deferred_shutdown)
615 return;
616
617 /* Should we try push out max-metric LSAs? */
618 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) {
619 for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
620 SET_FLAG(area->stub_router_state,
621 OSPF_AREA_ADMIN_STUB_ROUTED);
622
623 if (!CHECK_FLAG(area->stub_router_state,
624 OSPF_AREA_IS_STUB_ROUTED))
625 ospf_router_lsa_update_area(area);
626 }
627 timeout = ospf->stub_router_shutdown_time;
628 } else {
629 /* No timer needed */
630 ospf_deferred_shutdown_finish(ospf);
631 return;
632 }
633
634 OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
635 timeout);
636 return;
88d6cf37 637}
6b0655a2 638
88d6cf37 639/* Shut down the entire process */
d62a17ae 640void ospf_terminate(void)
641{
642 struct ospf *ospf;
643 struct listnode *node, *nnode;
644
645 /* shutdown already in progress */
646 if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
647 return;
648
649 SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN);
650
41b21bfa 651 /* Skip some steps if OSPF not actually running */
d62a17ae 652 if (listcount(om->ospf) == 0)
41b21bfa 653 goto done;
d62a17ae 654
d62a17ae 655 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
656 ospf_finish(ospf);
657
51f8588e
RW
658 /* Cleanup GR */
659 ospf_gr_helper_stop();
660
ded42248 661 /* Cleanup route maps */
ded42248
CS
662 route_map_finish();
663
664 /* reverse prefix_list_init */
665 prefix_list_add_hook(NULL);
666 prefix_list_delete_hook(NULL);
667 prefix_list_reset();
668
669 /* Cleanup vrf info */
670 ospf_vrf_terminate();
671
d62a17ae 672 /* Deliberately go back up, hopefully to thread scheduler, as
673 * One or more ospf_finish()'s may have deferred shutdown to a timer
674 * thread
675 */
676 zclient_stop(zclient);
677 zclient_free(zclient);
8879bd22 678
41b21bfa 679done:
8879bd22 680 frr_fini();
d62a17ae 681}
682
683void ospf_finish(struct ospf *ospf)
684{
685 /* let deferred shutdown decide */
686 ospf_deferred_shutdown_check(ospf);
687
688 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
689 * deferred to expiry of G-S timer thread. Return back up, hopefully
690 * to thread scheduler.
691 */
692 return;
88d6cf37 693}
694
695/* Final cleanup of ospf instance */
d62a17ae 696static void ospf_finish_final(struct ospf *ospf)
718e3744 697{
1113a2fb 698 struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
d62a17ae 699 struct route_node *rn;
700 struct ospf_nbr_nbma *nbr_nbma;
701 struct ospf_lsa *lsa;
d62a17ae 702 struct ospf_interface *oi;
703 struct ospf_area *area;
704 struct ospf_vl_data *vl_data;
705 struct listnode *node, *nnode;
ca187fd3 706 struct ospf_redist *red;
d62a17ae 707 int i;
7c8ff89e 708
d62a17ae 709 QOBJ_UNREG(ospf);
7c8ff89e 710
d62a17ae 711 ospf_opaque_type11_lsa_term(ospf);
953cde65 712
bcf4475e
OD
713 ospf_opaque_finish();
714
10514170
RW
715 if (!ospf->gr_info.prepare_in_progress)
716 ospf_flush_self_originated_lsas_now(ospf);
953cde65 717
d62a17ae 718 /* Unregister redistribution */
719 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
720 struct list *red_list;
718e3744 721
d62a17ae 722 red_list = ospf->redist[i];
723 if (!red_list)
724 continue;
718e3744 725
1d753551 726 for (ALL_LIST_ELEMENTS(red_list, node, nnode, red)) {
d62a17ae 727 ospf_redistribute_unset(ospf, i, red->instance);
1d753551
DS
728 ospf_redist_del(ospf, i, red->instance);
729 }
d62a17ae 730 }
ca187fd3
IR
731 red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
732 if (red) {
733 ospf_routemap_unset(red);
734 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
735 ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE, 0, 0);
736 }
718e3744 737
d62a17ae 738 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
739 ospf_remove_vls_through_area(ospf, area);
718e3744 740
d62a17ae 741 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
742 ospf_vl_delete(ospf, vl_data);
718e3744 743
6a154c88 744 list_delete(&ospf->vlinks);
718e3744 745
132a782e 746 /* shutdown LDP-Sync */
747 if (ospf->vrf_id == VRF_DEFAULT)
748 ospf_ldp_sync_gbl_exit(ospf, true);
749
d62a17ae 750 /* Reset interface. */
751 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
752 ospf_if_free(oi);
6a154c88 753 list_delete(&ospf->oiflist);
c32eba04 754 ospf->oi_running = 0;
718e3744 755
b5a8894d
CS
756 /* De-Register VRF */
757 ospf_zebra_vrf_deregister(ospf);
758
d62a17ae 759 /* Clear static neighbors */
760 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
761 if ((nbr_nbma = rn->info)) {
cccd44f3 762 THREAD_OFF(nbr_nbma->t_poll);
718e3744 763
d62a17ae 764 if (nbr_nbma->nbr) {
765 nbr_nbma->nbr->nbr_nbma = NULL;
766 nbr_nbma->nbr = NULL;
767 }
768
769 if (nbr_nbma->oi) {
770 listnode_delete(nbr_nbma->oi->nbr_nbma,
771 nbr_nbma);
772 nbr_nbma->oi = NULL;
773 }
774
775 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
776 }
777
778 route_table_finish(ospf->nbr_nbma);
779
780 /* Clear networks and Areas. */
781 for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
782 struct ospf_network *network;
783
784 if ((network = rn->info) != NULL) {
785 ospf_network_free(ospf, network);
786 rn->info = NULL;
787 route_unlock_node(rn);
788 }
91e6a0e5 789 }
7f586094 790 route_table_finish(ospf->networks);
718e3744 791
d62a17ae 792 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
793 listnode_delete(ospf->areas, area);
794 ospf_area_free(area);
795 }
718e3744 796
d62a17ae 797 /* Cancel all timers. */
cccd44f3
DS
798 THREAD_OFF(ospf->t_read);
799 THREAD_OFF(ospf->t_write);
800 THREAD_OFF(ospf->t_spf_calc);
801 THREAD_OFF(ospf->t_ase_calc);
802 THREAD_OFF(ospf->t_maxage);
803 THREAD_OFF(ospf->t_maxage_walker);
804 THREAD_OFF(ospf->t_abr_task);
805 THREAD_OFF(ospf->t_asbr_check);
806 THREAD_OFF(ospf->t_asbr_nssa_redist_update);
807 THREAD_OFF(ospf->t_distribute_update);
808 THREAD_OFF(ospf->t_lsa_refresher);
809 THREAD_OFF(ospf->t_opaque_lsa_self);
810 THREAD_OFF(ospf->t_sr_update);
811 THREAD_OFF(ospf->t_default_routemap_timer);
812 THREAD_OFF(ospf->t_external_aggr);
813 THREAD_OFF(ospf->gr_info.t_grace_period);
d62a17ae 814
996c9314 815 LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
044506e7 816 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
996c9314 817 LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
044506e7 818 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
d62a17ae 819
820 ospf_lsdb_delete_all(ospf->lsdb);
821 ospf_lsdb_free(ospf->lsdb);
822
823 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
d62a17ae 824 if ((lsa = rn->info) != NULL) {
825 ospf_lsa_unlock(&lsa);
826 rn->info = NULL;
69843e81 827 route_unlock_node(rn);
d62a17ae 828 }
d62a17ae 829 }
830 route_table_finish(ospf->maxage_lsa);
831
832 if (ospf->old_table)
833 ospf_route_table_free(ospf->old_table);
834 if (ospf->new_table) {
10514170
RW
835 if (!ospf->gr_info.prepare_in_progress)
836 ospf_route_delete(ospf, ospf->new_table);
d62a17ae 837 ospf_route_table_free(ospf->new_table);
838 }
9bf19426
RZ
839 if (ospf->oall_rtrs)
840 ospf_rtrs_free(ospf->oall_rtrs);
841 if (ospf->all_rtrs)
842 ospf_rtrs_free(ospf->all_rtrs);
d62a17ae 843 if (ospf->old_rtrs)
844 ospf_rtrs_free(ospf->old_rtrs);
845 if (ospf->new_rtrs)
846 ospf_rtrs_free(ospf->new_rtrs);
847 if (ospf->new_external_route) {
10514170
RW
848 if (!ospf->gr_info.prepare_in_progress)
849 ospf_route_delete(ospf, ospf->new_external_route);
d62a17ae 850 ospf_route_table_free(ospf->new_external_route);
851 }
852 if (ospf->old_external_route) {
10514170
RW
853 if (!ospf->gr_info.prepare_in_progress)
854 ospf_route_delete(ospf, ospf->old_external_route);
d62a17ae 855 ospf_route_table_free(ospf->old_external_route);
856 }
857 if (ospf->external_lsas) {
858 ospf_ase_external_lsas_finish(ospf->external_lsas);
859 }
718e3744 860
d62a17ae 861 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
862 struct list *ext_list;
d62a17ae 863 struct ospf_external *ext;
864
de1ac5fd 865 ext_list = ospf->external[i];
d62a17ae 866 if (!ext_list)
867 continue;
868
76fdc7f4 869 for (ALL_LIST_ELEMENTS(ext_list, node, nnode, ext)) {
d62a17ae 870 if (ext->external_info)
871 for (rn = route_top(ext->external_info); rn;
872 rn = route_next(rn)) {
873 if (rn->info == NULL)
874 continue;
875
876 XFREE(MTYPE_OSPF_EXTERNAL_INFO,
877 rn->info);
878 rn->info = NULL;
879 route_unlock_node(rn);
880 }
1d753551
DS
881
882 ospf_external_del(ospf, i, ext->instance);
d62a17ae 883 }
884 }
718e3744 885
d62a17ae 886 ospf_distance_reset(ospf);
887 route_table_finish(ospf->distance_table);
7c8ff89e 888
ad7222b7 889 /* Release extrenal Aggregator table */
890 for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
891 struct ospf_external_aggr_rt *aggr;
892
893 aggr = rn->info;
894
895 if (aggr) {
896 ospf_external_aggregator_free(aggr);
897 rn->info = NULL;
898 route_unlock_node(rn);
899 }
900 }
901
902 route_table_finish(ospf->rt_aggr_tbl);
903
904
594f80c8 905 ospf_free_refresh_queue(ospf);
906
c32eba04
CS
907 list_delete(&ospf->areas);
908 list_delete(&ospf->oi_write_q);
909
06bc3110 910 /* Reset GR helper data structers */
51f8588e 911 ospf_gr_helper_instance_stop(ospf);
06bc3110 912
c32eba04
CS
913 close(ospf->fd);
914 stream_free(ospf->ibuf);
915 ospf->fd = -1;
3d5b9855 916 ospf->max_multipath = MULTIPATH_NUM;
d62a17ae 917 ospf_delete(ospf);
7c8ff89e 918
1113a2fb 919 if (vrf)
920 ospf_vrf_unlink(ospf, vrf);
b5a8894d 921
ac2cb9bf 922 XFREE(MTYPE_OSPF_TOP, ospf->name);
d62a17ae 923 XFREE(MTYPE_OSPF_TOP, ospf);
718e3744 924}
925
6b0655a2 926
718e3744 927/* allocate new OSPF Area object */
7fd0729f 928struct ospf_area *ospf_area_new(struct ospf *ospf, struct in_addr area_id)
718e3744 929{
d62a17ae 930 struct ospf_area *new;
718e3744 931
d62a17ae 932 /* Allocate new config_network. */
933 new = XCALLOC(MTYPE_OSPF_AREA, sizeof(struct ospf_area));
718e3744 934
d62a17ae 935 new->ospf = ospf;
718e3744 936
d62a17ae 937 new->area_id = area_id;
938 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
718e3744 939
d62a17ae 940 new->external_routing = OSPF_AREA_DEFAULT;
941 new->default_cost = 1;
942 new->auth_type = OSPF_AUTH_NULL;
718e3744 943
d62a17ae 944 /* New LSDB init. */
945 new->lsdb = ospf_lsdb_new();
718e3744 946
d62a17ae 947 /* Self-originated LSAs initialize. */
948 new->router_lsa_self = NULL;
718e3744 949
d62a17ae 950 ospf_opaque_type10_lsa_init(new);
718e3744 951
d62a17ae 952 new->oiflist = list_new();
953 new->ranges = route_table_init();
718e3744 954
d62a17ae 955 if (area_id.s_addr == OSPF_AREA_BACKBONE)
956 ospf->backbone = new;
957
958 return new;
718e3744 959}
960
f91ce319 961void ospf_area_lsdb_discard_delete(struct ospf_area *area)
718e3744 962{
d62a17ae 963 struct route_node *rn;
964 struct ospf_lsa *lsa;
965
996c9314 966 LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
044506e7 967 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 968 LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
044506e7 969 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 970 LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
044506e7 971 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 972 LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
044506e7 973 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
68980084 974
996c9314 975 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
044506e7 976 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 977 LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
044506e7 978 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 979 LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
044506e7 980 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
718e3744 981
d62a17ae 982 ospf_lsdb_delete_all(area->lsdb);
f91ce319
MR
983}
984
985static void ospf_area_free(struct ospf_area *area)
986{
987 ospf_opaque_type10_lsa_term(area);
988
989 /* Free LSDBs. */
990 ospf_area_lsdb_discard_delete(area);
991
d62a17ae 992 ospf_lsdb_free(area->lsdb);
718e3744 993
d62a17ae 994 ospf_lsa_unlock(&area->router_lsa_self);
718e3744 995
d62a17ae 996 route_table_finish(area->ranges);
6a154c88 997 list_delete(&area->oiflist);
718e3744 998
d62a17ae 999 if (EXPORT_NAME(area))
1000 free(EXPORT_NAME(area));
718e3744 1001
d62a17ae 1002 if (IMPORT_NAME(area))
1003 free(IMPORT_NAME(area));
718e3744 1004
d62a17ae 1005 /* Cancel timer. */
cccd44f3
DS
1006 THREAD_OFF(area->t_stub_router);
1007 THREAD_OFF(area->t_opaque_lsa_self);
718e3744 1008
d62a17ae 1009 if (OSPF_IS_AREA_BACKBONE(area))
1010 area->ospf->backbone = NULL;
1011
1012 XFREE(MTYPE_OSPF_AREA, area);
718e3744 1013}
1014
d62a17ae 1015void ospf_area_check_free(struct ospf *ospf, struct in_addr area_id)
718e3744 1016{
d62a17ae 1017 struct ospf_area *area;
718e3744 1018
d62a17ae 1019 area = ospf_area_lookup_by_area_id(ospf, area_id);
1020 if (area && listcount(area->oiflist) == 0 && area->ranges->top == NULL
19ce7d5e 1021 && !ospf_vl_count(ospf, area)
d62a17ae 1022 && area->shortcut_configured == OSPF_SHORTCUT_DEFAULT
1023 && area->external_routing == OSPF_AREA_DEFAULT
1024 && area->no_summary == 0 && area->default_cost == 1
1025 && EXPORT_NAME(area) == NULL && IMPORT_NAME(area) == NULL
1026 && area->auth_type == OSPF_AUTH_NULL) {
1027 listnode_delete(ospf->areas, area);
1028 ospf_area_free(area);
1029 }
718e3744 1030}
1031
d62a17ae 1032struct ospf_area *ospf_area_get(struct ospf *ospf, struct in_addr area_id)
718e3744 1033{
d62a17ae 1034 struct ospf_area *area;
1035
1036 area = ospf_area_lookup_by_area_id(ospf, area_id);
1037 if (!area) {
1038 area = ospf_area_new(ospf, area_id);
1039 listnode_add_sort(ospf->areas, area);
1040 ospf_check_abr_status(ospf);
1041 if (ospf->stub_router_admin_set
1042 == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) {
1043 SET_FLAG(area->stub_router_state,
1044 OSPF_AREA_ADMIN_STUB_ROUTED);
1045 }
1046 }
718e3744 1047
d62a17ae 1048 return area;
718e3744 1049}
1050
d62a17ae 1051struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *ospf,
1052 struct in_addr area_id)
718e3744 1053{
d62a17ae 1054 struct ospf_area *area;
1055 struct listnode *node;
718e3744 1056
d62a17ae 1057 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
1058 if (IPV4_ADDR_SAME(&area->area_id, &area_id))
1059 return area;
718e3744 1060
d62a17ae 1061 return NULL;
718e3744 1062}
1063
d62a17ae 1064void ospf_area_add_if(struct ospf_area *area, struct ospf_interface *oi)
718e3744 1065{
d62a17ae 1066 listnode_add(area->oiflist, oi);
718e3744 1067}
1068
d62a17ae 1069void ospf_area_del_if(struct ospf_area *area, struct ospf_interface *oi)
718e3744 1070{
d62a17ae 1071 listnode_delete(area->oiflist, oi);
718e3744 1072}
1073
52c62ab8 1074
7fd0729f
G
1075struct ospf_interface *add_ospf_interface(struct connected *co,
1076 struct ospf_area *area)
953cde65 1077{
d62a17ae 1078 struct ospf_interface *oi;
953cde65 1079
d62a17ae 1080 oi = ospf_if_new(area->ospf, co->ifp, co->address);
1081 oi->connected = co;
953cde65 1082
d62a17ae 1083 oi->area = area;
953cde65 1084
d62a17ae 1085 oi->params = ospf_lookup_if_params(co->ifp, oi->address->u.prefix4);
1086 oi->output_cost = ospf_if_get_output_cost(oi);
953cde65 1087
d62a17ae 1088 /* Relate ospf interface to ospf instance. */
1089 oi->ospf = area->ospf;
953cde65 1090
d62a17ae 1091 /* update network type as interface flag */
1092 /* If network type is specified previously,
1093 skip network type setting. */
1094 oi->type = IF_DEF_PARAMS(co->ifp)->type;
bc97889b 1095 oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn;
953cde65 1096
d62a17ae 1097 /* Add pseudo neighbor. */
1098 ospf_nbr_self_reset(oi, oi->ospf->router_id);
953cde65 1099
d62a17ae 1100 ospf_area_add_if(oi->area, oi);
52c62ab8 1101
132a782e 1102 /* if LDP-IGP Sync is configured globally inherit config */
1103 ospf_ldp_sync_if_init(oi);
1104
d62a17ae 1105 /*
1461559c 1106 * if router_id is not configured, don't bring up
d62a17ae 1107 * interfaces.
1108 * ospf_router_id_update() will call ospf_if_update
1109 * whenever r-id is configured instead.
1110 */
975a328e
DA
1111 if ((area->ospf->router_id.s_addr != INADDR_ANY)
1112 && if_is_operative(co->ifp))
d62a17ae 1113 ospf_if_up(oi);
7fd0729f
G
1114
1115 return oi;
953cde65
JT
1116}
1117
1118static void update_redistributed(struct ospf *ospf, int add_to_ospf)
1119{
d62a17ae 1120 struct route_node *rn;
1121 struct external_info *ei;
1122 struct ospf_external *ext;
1123
de1ac5fd
CS
1124 if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) {
1125 ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0);
1126 if ((ext) && EXTERNAL_INFO(ext)) {
d62a17ae 1127 for (rn = route_top(EXTERNAL_INFO(ext)); rn;
1128 rn = route_next(rn)) {
de1ac5fd
CS
1129 ei = rn->info;
1130 if (ei == NULL)
1131 continue;
1132
1133 if (add_to_ospf) {
996c9314
LB
1134 if (ospf_external_info_find_lsa(ospf,
1135 &ei->p))
e474c143
MR
1136 if (!ospf_redistribute_check(
1137 ospf, ei, NULL))
de1ac5fd 1138 ospf_external_lsa_flush(
996c9314 1139 ospf, ei->type,
de1ac5fd
CS
1140 &ei->p,
1141 ei->ifindex /*, ei->nexthop */);
1142 } else {
1143 if (!ospf_external_info_find_lsa(
1144 ospf, &ei->p))
e474c143
MR
1145 if (ospf_redistribute_check(
1146 ospf, ei, NULL))
de1ac5fd 1147 ospf_external_lsa_originate(
996c9314 1148 ospf, ei);
d62a17ae 1149 }
1150 }
1151 }
de1ac5fd 1152 }
953cde65
JT
1153}
1154
718e3744 1155/* Config network statement related functions. */
d62a17ae 1156static struct ospf_network *ospf_network_new(struct in_addr area_id)
718e3744 1157{
d62a17ae 1158 struct ospf_network *new;
1159 new = XCALLOC(MTYPE_OSPF_NETWORK, sizeof(struct ospf_network));
718e3744 1160
d62a17ae 1161 new->area_id = area_id;
1162 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
1163
1164 return new;
718e3744 1165}
1166
d62a17ae 1167static void ospf_network_free(struct ospf *ospf, struct ospf_network *network)
718e3744 1168{
d62a17ae 1169 ospf_area_check_free(ospf, network->area_id);
1170 ospf_schedule_abr_task(ospf);
1171 XFREE(MTYPE_OSPF_NETWORK, network);
718e3744 1172}
1173
d62a17ae 1174int ospf_network_set(struct ospf *ospf, struct prefix_ipv4 *p,
1175 struct in_addr area_id, int df)
718e3744 1176{
d62a17ae 1177 struct ospf_network *network;
1178 struct ospf_area *area;
1179 struct route_node *rn;
718e3744 1180
d62a17ae 1181 rn = route_node_get(ospf->networks, (struct prefix *)p);
1182 if (rn->info) {
2b0a905a 1183 network = rn->info;
d62a17ae 1184 route_unlock_node(rn);
2b0a905a
DW
1185
1186 if (IPV4_ADDR_SAME(&area_id, &network->area_id)) {
1187 return 1;
1188 } else {
1189 /* There is already same network statement. */
1190 return 0;
1191 }
d62a17ae 1192 }
718e3744 1193
d62a17ae 1194 rn->info = network = ospf_network_new(area_id);
1195 network->area_id_fmt = df;
1196 area = ospf_area_get(ospf, area_id);
1197 ospf_area_display_format_set(ospf, area, df);
718e3744 1198
d62a17ae 1199 /* Run network config now. */
1200 ospf_network_run((struct prefix *)p, area);
718e3744 1201
d62a17ae 1202 /* Update connected redistribute. */
1203 update_redistributed(ospf, 1); /* interfaces possibly added */
718e3744 1204
d62a17ae 1205 ospf_area_check_free(ospf, area_id);
718e3744 1206
d62a17ae 1207 return 1;
718e3744 1208}
1209
d62a17ae 1210int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
1211 struct in_addr area_id)
718e3744 1212{
d62a17ae 1213 struct route_node *rn;
1214 struct ospf_network *network;
1215 struct listnode *node, *nnode;
1216 struct ospf_interface *oi;
718e3744 1217
d62a17ae 1218 rn = route_node_lookup(ospf->networks, (struct prefix *)p);
1219 if (rn == NULL)
1220 return 0;
718e3744 1221
d62a17ae 1222 network = rn->info;
1223 route_unlock_node(rn);
1224 if (!IPV4_ADDR_SAME(&area_id, &network->area_id))
1225 return 0;
718e3744 1226
d62a17ae 1227 ospf_network_free(ospf, rn->info);
1228 rn->info = NULL;
1229 route_unlock_node(rn); /* initial reference */
718e3744 1230
30c0daa4 1231 /* Find interfaces that are not configured already. */
d62a17ae 1232 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
30c0daa4 1233
996c9314
LB
1234 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
1235 continue;
30c0daa4 1236
996c9314 1237 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
d62a17ae 1238 }
953cde65 1239
d62a17ae 1240 /* Update connected redistribute. */
1241 update_redistributed(ospf, 0); /* interfaces possibly removed */
1242 ospf_area_check_free(ospf, area_id);
1243
1244 return 1;
953cde65
JT
1245}
1246
52c62ab8
JAG
1247/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means
1248 * there might not be any 'router ospf' config.
1249 *
1250 * Otherwise, doesn't do anything different to ospf_if_update for now
1251 */
b5a8894d 1252void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
953cde65 1253{
b5a8894d
CS
1254 if (!ospf)
1255 return;
d62a17ae 1256
1257 ospf_if_update(ospf, ifp);
1258 /* if_update does a update_redistributed */
1259
1260 return;
953cde65
JT
1261}
1262
b5a8894d 1263void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
953cde65 1264{
d62a17ae 1265 struct route_node *rn_oi;
953cde65 1266
d62a17ae 1267 if (!ospf)
1268 return; /* Ospf not ready yet */
953cde65 1269
d62a17ae 1270 /* Find interfaces that may need to be removed. */
1271 for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
1272 rn_oi = route_next(rn_oi)) {
b5a8894d 1273 struct ospf_interface *oi = NULL;
d62a17ae 1274
1275 if ((oi = rn_oi->info) == NULL)
1276 continue;
1277
1278 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
1279 continue;
1280
1281 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
1282 }
953cde65 1283
d62a17ae 1284 /* Update connected redistribute. */
1285 update_redistributed(ospf, 0); /* interfaces possibly removed */
718e3744 1286}
1287
570f7598 1288/* Check whether interface matches given network
1289 * returns: 1, true. 0, false
1290 */
d62a17ae 1291static int ospf_network_match_iface(const struct connected *co,
1292 const struct prefix *net)
570f7598 1293{
d62a17ae 1294 /* new approach: more elegant and conceptually clean */
1295 return prefix_match_network_statement(net, CONNECTED_PREFIX(co));
570f7598 1296}
1297
d62a17ae 1298static void ospf_update_interface_area(struct connected *co,
1299 struct ospf_area *area)
52c62ab8 1300{
d62a17ae 1301 struct ospf_interface *oi = ospf_if_table_lookup(co->ifp, co->address);
1302
1303 /* nothing to be done case */
1304 if (oi && oi->area == area) {
1305 return;
1306 }
1307
1308 if (oi)
1309 ospf_if_free(oi);
1310
1311 add_ospf_interface(co, area);
52c62ab8
JAG
1312}
1313
1314/* Run OSPF for the given subnet, taking into account the following
1315 * possible sources of area configuration, in the given order of preference:
1316 *
1317 * - Whether there is interface+address specific area configuration
1318 * - Whether there is a default area for the interface
1319 * - Whether there is an area given as a parameter.
1320 * - If no specific network prefix/area is supplied, whether there's
1321 * a matching network configured.
1322 */
d62a17ae 1323static void ospf_network_run_subnet(struct ospf *ospf, struct connected *co,
1324 struct prefix *p,
1325 struct ospf_area *given_area)
1326{
1327 struct ospf_interface *oi;
1328 struct ospf_if_params *params;
1329 struct ospf_area *area = NULL;
1330 struct route_node *rn;
1331 int configed = 0;
1332
1333 if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
1334 return;
1335
1336 if (co->address->family != AF_INET)
1337 return;
1338
1339 /* Try determine the appropriate area for this interface + address
1340 * Start by checking interface config
1341 */
1342 params = ospf_lookup_if_params(co->ifp, co->address->u.prefix4);
1343 if (params && OSPF_IF_PARAM_CONFIGURED(params, if_area))
1344 area = ospf_area_get(ospf, params->if_area);
1345 else {
1346 params = IF_DEF_PARAMS(co->ifp);
1347 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
1348 area = ospf_area_get(ospf, params->if_area);
1349 }
52c62ab8 1350
d62a17ae 1351 /* If we've found an interface and/or addr specific area, then we're
1352 * done
1353 */
1354 if (area) {
1355 ospf_update_interface_area(co, area);
1356 return;
1357 }
718e3744 1358
d62a17ae 1359 /* Otherwise, only remaining possibility is a matching network statement
1360 */
1361 if (p) {
1362 assert(given_area != NULL);
1363
1364 /* Which either was supplied as a parameter.. (e.g. cause a new
1365 * network/area was just added)..
1366 */
1367 if (p->family == co->address->family
1368 && ospf_network_match_iface(co, p))
1369 ospf_update_interface_area(co, given_area);
1370
1371 return;
1372 }
1373
1374 /* Else we have to search the existing network/area config to see
1375 * if any match..
1376 */
1377 for (rn = route_top(ospf->networks); rn; rn = route_next(rn))
1378 if (rn->info != NULL && ospf_network_match_iface(co, &rn->p)) {
1379 struct ospf_network *network =
1380 (struct ospf_network *)rn->info;
1381 area = ospf_area_get(ospf, network->area_id);
1382 ospf_update_interface_area(co, area);
1383 configed = 1;
1384 }
1385
1386 /* If the subnet isn't in any area, deconfigure */
1387 if (!configed && (oi = ospf_if_table_lookup(co->ifp, co->address)))
1388 ospf_if_free(oi);
718e3744 1389}
1390
d62a17ae 1391static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp,
1392 struct prefix *p,
1393 struct ospf_area *given_area)
718e3744 1394{
d62a17ae 1395 struct listnode *cnode;
1396 struct connected *co;
1397
1398 if (memcmp(ifp->name, "VLINK", 5) == 0)
1399 return;
718e3744 1400
d62a17ae 1401 /* Network prefix without area is nonsensical */
1402 if (p)
1403 assert(given_area != NULL);
1404
1405 /* if interface prefix is match specified prefix,
1406 then create socket and join multicast group. */
1407 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co))
1408 ospf_network_run_subnet(ospf, co, p, given_area);
718e3744 1409}
1410
d62a17ae 1411static void ospf_network_run(struct prefix *p, struct ospf_area *area)
718e3744 1412{
f4e14fdb 1413 struct vrf *vrf = vrf_lookup_by_id(area->ospf->vrf_id);
d62a17ae 1414 struct interface *ifp;
d62a17ae 1415
1416 /* Schedule Router ID Update. */
975a328e 1417 if (area->ospf->router_id.s_addr == INADDR_ANY)
d62a17ae 1418 ospf_router_id_update(area->ospf);
718e3744 1419
d62a17ae 1420 /* Get target interface. */
451fda4f 1421 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1422 ospf_network_run_interface(area->ospf, ifp, p, area);
718e3744 1423}
1424
d62a17ae 1425void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
1426{
1427 struct route_node *rn;
1428 struct listnode *node, *nnode;
1429 struct list *lst;
1430 struct ospf_lsa *lsa;
1431
1432 /* empty ls update queue */
1433 for (rn = route_top(oi->ls_upd_queue); rn; rn = route_next(rn))
1434 if ((lst = (struct list *)rn->info)) {
1435 for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa))
1436 ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */
6a154c88 1437 list_delete(&lst);
d62a17ae 1438 rn->info = NULL;
1439 }
1440
1441 /* remove update event */
bc1f09de 1442 THREAD_OFF(oi->t_ls_upd_event);
d62a17ae 1443}
6b0655a2 1444
d62a17ae 1445void ospf_if_update(struct ospf *ospf, struct interface *ifp)
718e3744 1446{
43b8d1d8 1447
d62a17ae 1448 if (!ospf)
43b8d1d8 1449 return;
b5a8894d
CS
1450
1451 if (IS_DEBUG_OSPF_EVENT)
996c9314 1452 zlog_debug(
096f7609
IR
1453 "%s: interface %s vrf %s(%u) ospf vrf %s vrf_id %u router_id %pI4",
1454 __func__, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
996c9314 1455 ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
96b663a3 1456 &ospf->router_id);
d62a17ae 1457
1458 /* OSPF must be ready. */
1459 if (!ospf_is_ready(ospf))
1460 return;
1461
1462 ospf_network_run_interface(ospf, ifp, NULL, NULL);
1463
1464 /* Update connected redistribute. */
1465 update_redistributed(ospf, 1);
ef7bd2a3 1466
d62a17ae 1467}
718e3744 1468
d62a17ae 1469void ospf_remove_vls_through_area(struct ospf *ospf, struct ospf_area *area)
718e3744 1470{
d62a17ae 1471 struct listnode *node, *nnode;
1472 struct ospf_vl_data *vl_data;
718e3744 1473
d62a17ae 1474 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
1475 if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1476 ospf_vl_delete(ospf, vl_data);
1477}
718e3744 1478
718e3744 1479
d62a17ae 1480static const struct message ospf_area_type_msg[] = {
1481 {OSPF_AREA_DEFAULT, "Default"},
1482 {OSPF_AREA_STUB, "Stub"},
1483 {OSPF_AREA_NSSA, "NSSA"},
1484 {0}};
718e3744 1485
d62a17ae 1486static void ospf_area_type_set(struct ospf_area *area, int type)
1487{
1488 struct listnode *node;
1489 struct ospf_interface *oi;
1490
1491 if (area->external_routing == type) {
1492 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
1493 zlog_debug("Area[%pI4]: Types are the same, ignored.",
1494 &area->area_id);
d62a17ae 1495 return;
1496 }
718e3744 1497
d62a17ae 1498 area->external_routing = type;
1499
1500 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
1501 zlog_debug("Area[%pI4]: Configured as %s",
1502 &area->area_id,
d62a17ae 1503 lookup_msg(ospf_area_type_msg, type, NULL));
1504
1505 switch (area->external_routing) {
1506 case OSPF_AREA_DEFAULT:
1507 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1508 if (oi->nbr_self != NULL) {
1509 UNSET_FLAG(oi->nbr_self->options,
1510 OSPF_OPTION_NP);
1511 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
1512 }
1513 break;
1514 case OSPF_AREA_STUB:
1515 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1516 if (oi->nbr_self != NULL) {
1517 if (IS_DEBUG_OSPF_EVENT)
1518 zlog_debug(
1519 "setting options on %s accordingly",
1520 IF_NAME(oi));
1521 UNSET_FLAG(oi->nbr_self->options,
1522 OSPF_OPTION_NP);
1523 UNSET_FLAG(oi->nbr_self->options,
1524 OSPF_OPTION_E);
1525 if (IS_DEBUG_OSPF_EVENT)
1526 zlog_debug("options set on %s: %x",
1527 IF_NAME(oi), OPTIONS(oi));
1528 }
1529 break;
1530 case OSPF_AREA_NSSA:
1531 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1532 if (oi->nbr_self != NULL) {
1533 zlog_debug(
1534 "setting nssa options on %s accordingly",
1535 IF_NAME(oi));
1536 UNSET_FLAG(oi->nbr_self->options,
1537 OSPF_OPTION_E);
1538 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP);
1539 zlog_debug("options set on %s: %x", IF_NAME(oi),
1540 OPTIONS(oi));
1541 }
1542 break;
1543 default:
1544 break;
1545 }
1546
1547 ospf_router_lsa_update_area(area);
1548 ospf_schedule_abr_task(area->ospf);
718e3744 1549}
1550
d62a17ae 1551int ospf_area_shortcut_set(struct ospf *ospf, struct ospf_area *area, int mode)
718e3744 1552{
d62a17ae 1553 if (area->shortcut_configured == mode)
1554 return 0;
718e3744 1555
d62a17ae 1556 area->shortcut_configured = mode;
1557 ospf_router_lsa_update_area(area);
1558 ospf_schedule_abr_task(ospf);
718e3744 1559
d62a17ae 1560 ospf_area_check_free(ospf, area->area_id);
718e3744 1561
d62a17ae 1562 return 1;
718e3744 1563}
1564
d62a17ae 1565int ospf_area_shortcut_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1566{
d62a17ae 1567 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1568 ospf_router_lsa_update_area(area);
1569 ospf_area_check_free(ospf, area->area_id);
1570 ospf_schedule_abr_task(ospf);
718e3744 1571
d62a17ae 1572 return 1;
718e3744 1573}
1574
d62a17ae 1575static int ospf_area_vlink_count(struct ospf *ospf, struct ospf_area *area)
718e3744 1576{
d62a17ae 1577 struct ospf_vl_data *vl;
1578 struct listnode *node;
1579 int count = 0;
718e3744 1580
d62a17ae 1581 for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl))
1582 if (IPV4_ADDR_SAME(&vl->vl_area_id, &area->area_id))
1583 count++;
718e3744 1584
d62a17ae 1585 return count;
718e3744 1586}
1587
d62a17ae 1588int ospf_area_display_format_set(struct ospf *ospf, struct ospf_area *area,
1589 int df)
86573dcb 1590{
d62a17ae 1591 area->area_id_fmt = df;
86573dcb 1592
d62a17ae 1593 return 1;
86573dcb
QY
1594}
1595
d62a17ae 1596int ospf_area_stub_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1597{
d62a17ae 1598 struct ospf_area *area;
718e3744 1599
d62a17ae 1600 area = ospf_area_get(ospf, area_id);
1601 if (ospf_area_vlink_count(ospf, area))
1602 return 0;
718e3744 1603
d62a17ae 1604 if (area->external_routing != OSPF_AREA_STUB)
1605 ospf_area_type_set(area, OSPF_AREA_STUB);
718e3744 1606
d62a17ae 1607 return 1;
718e3744 1608}
1609
d62a17ae 1610int ospf_area_stub_unset(struct ospf *ospf, struct in_addr area_id)
718e3744 1611{
d62a17ae 1612 struct ospf_area *area;
718e3744 1613
d62a17ae 1614 area = ospf_area_lookup_by_area_id(ospf, area_id);
1615 if (area == NULL)
1616 return 1;
718e3744 1617
d62a17ae 1618 if (area->external_routing == OSPF_AREA_STUB)
1619 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
718e3744 1620
d62a17ae 1621 ospf_area_check_free(ospf, area_id);
718e3744 1622
d62a17ae 1623 return 1;
718e3744 1624}
1625
d62a17ae 1626int ospf_area_no_summary_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1627{
d62a17ae 1628 struct ospf_area *area;
718e3744 1629
d62a17ae 1630 area = ospf_area_get(ospf, area_id);
1631 area->no_summary = 1;
718e3744 1632
d62a17ae 1633 return 1;
718e3744 1634}
1635
d62a17ae 1636int ospf_area_no_summary_unset(struct ospf *ospf, struct in_addr area_id)
718e3744 1637{
d62a17ae 1638 struct ospf_area *area;
718e3744 1639
d62a17ae 1640 area = ospf_area_lookup_by_area_id(ospf, area_id);
1641 if (area == NULL)
1642 return 0;
718e3744 1643
d62a17ae 1644 area->no_summary = 0;
1645 ospf_area_check_free(ospf, area_id);
718e3744 1646
d62a17ae 1647 return 1;
718e3744 1648}
1649
7ef56a73 1650int ospf_area_nssa_no_summary_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1651{
d62a17ae 1652 struct ospf_area *area;
718e3744 1653
d62a17ae 1654 area = ospf_area_get(ospf, area_id);
1655 if (ospf_area_vlink_count(ospf, area))
1656 return 0;
718e3744 1657
d62a17ae 1658 if (area->external_routing != OSPF_AREA_NSSA) {
1659 ospf_area_type_set(area, OSPF_AREA_NSSA);
1660 ospf->anyNSSA++;
7ef56a73 1661 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
d62a17ae 1662 }
718e3744 1663
7ef56a73 1664 ospf_area_no_summary_set(ospf, area_id);
084c7844 1665
d62a17ae 1666 return 1;
718e3744 1667}
1668
7ef56a73
CS
1669int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id)
1670{
1671 struct ospf_area *area;
1672
1673 area = ospf_area_get(ospf, area_id);
1674 if (ospf_area_vlink_count(ospf, area))
1675 return 0;
1676
1677 if (area->external_routing != OSPF_AREA_NSSA) {
1678 ospf_area_type_set(area, OSPF_AREA_NSSA);
1679 ospf->anyNSSA++;
1680
1681 /* set NSSA area defaults */
1682 area->no_summary = 0;
c317eddb 1683 area->suppress_fa = 0;
7ef56a73
CS
1684 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1685 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
1686 area->NSSATranslatorStabilityInterval =
1687 OSPF_NSSA_TRANS_STABLE_DEFAULT;
1688 }
1689 return 1;
1690}
1691
1692int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
718e3744 1693{
d62a17ae 1694 struct ospf_area *area;
718e3744 1695
d62a17ae 1696 area = ospf_area_lookup_by_area_id(ospf, area_id);
1697 if (area == NULL)
1698 return 0;
718e3744 1699
7ef56a73
CS
1700 /* argc < 5 -> 'no area x nssa' */
1701 if (argc < 5 && area->external_routing == OSPF_AREA_NSSA) {
d62a17ae 1702 ospf->anyNSSA--;
7ef56a73
CS
1703 /* set NSSA area defaults */
1704 area->no_summary = 0;
c317eddb 1705 area->suppress_fa = 0;
7ef56a73
CS
1706 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1707 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
1708 area->NSSATranslatorStabilityInterval =
1709 OSPF_NSSA_TRANS_STABLE_DEFAULT;
d62a17ae 1710 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
7ef56a73 1711 } else {
a987fe6b 1712 ospf_area_nssa_translator_role_set(ospf, area_id,
1713 OSPF_NSSA_ROLE_CANDIDATE);
d62a17ae 1714 }
718e3744 1715
d62a17ae 1716 ospf_area_check_free(ospf, area_id);
718e3744 1717
d62a17ae 1718 return 1;
718e3744 1719}
1720
c317eddb 1721int ospf_area_nssa_suppress_fa_set(struct ospf *ospf, struct in_addr area_id)
1722{
1723 struct ospf_area *area;
1724
1725 area = ospf_area_lookup_by_area_id(ospf, area_id);
1726 if (area == NULL)
1727 return 0;
1728
1729 area->suppress_fa = 1;
1730
1731 return 1;
1732}
1733
1734int ospf_area_nssa_suppress_fa_unset(struct ospf *ospf, struct in_addr area_id)
1735{
1736 struct ospf_area *area;
1737
1738 area = ospf_area_lookup_by_area_id(ospf, area_id);
1739 if (area == NULL)
1740 return 0;
1741
1742 area->suppress_fa = 0;
1743
1744 return 1;
1745}
1746
d62a17ae 1747int ospf_area_nssa_translator_role_set(struct ospf *ospf,
1748 struct in_addr area_id, int role)
718e3744 1749{
d62a17ae 1750 struct ospf_area *area;
718e3744 1751
d62a17ae 1752 area = ospf_area_lookup_by_area_id(ospf, area_id);
1753 if (area == NULL)
1754 return 0;
718e3744 1755
a987fe6b 1756 if (role != area->NSSATranslatorRole) {
1757 if ((area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)
1758 || (role == OSPF_NSSA_ROLE_ALWAYS)) {
1759 /* RFC 3101 3.1
1760 * if new role is OSPF_NSSA_ROLE_ALWAYS we need to set
1761 * Nt bit, if the role was OSPF_NSSA_ROLE_ALWAYS we need
1762 * to clear Nt bit
1763 */
1764 area->NSSATranslatorRole = role;
1765 ospf_router_lsa_update_area(area);
1766 } else
1767 area->NSSATranslatorRole = role;
1768 }
718e3744 1769
d62a17ae 1770 return 1;
718e3744 1771}
1772
d62a17ae 1773int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area,
1774 const char *list_name)
718e3744 1775{
d62a17ae 1776 struct access_list *list;
1777 list = access_list_lookup(AFI_IP, list_name);
718e3744 1778
d62a17ae 1779 EXPORT_LIST(area) = list;
718e3744 1780
d62a17ae 1781 if (EXPORT_NAME(area))
1782 free(EXPORT_NAME(area));
718e3744 1783
d62a17ae 1784 EXPORT_NAME(area) = strdup(list_name);
1785 ospf_schedule_abr_task(ospf);
718e3744 1786
d62a17ae 1787 return 1;
718e3744 1788}
1789
d62a17ae 1790int ospf_area_export_list_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1791{
1792
d62a17ae 1793 EXPORT_LIST(area) = 0;
718e3744 1794
d62a17ae 1795 if (EXPORT_NAME(area))
1796 free(EXPORT_NAME(area));
718e3744 1797
d62a17ae 1798 EXPORT_NAME(area) = NULL;
718e3744 1799
d62a17ae 1800 ospf_area_check_free(ospf, area->area_id);
718e3744 1801
d62a17ae 1802 ospf_schedule_abr_task(ospf);
1803
1804 return 1;
718e3744 1805}
1806
d62a17ae 1807int ospf_area_import_list_set(struct ospf *ospf, struct ospf_area *area,
1808 const char *name)
718e3744 1809{
d62a17ae 1810 struct access_list *list;
1811 list = access_list_lookup(AFI_IP, name);
718e3744 1812
d62a17ae 1813 IMPORT_LIST(area) = list;
718e3744 1814
d62a17ae 1815 if (IMPORT_NAME(area))
1816 free(IMPORT_NAME(area));
718e3744 1817
d62a17ae 1818 IMPORT_NAME(area) = strdup(name);
1819 ospf_schedule_abr_task(ospf);
718e3744 1820
d62a17ae 1821 return 1;
718e3744 1822}
1823
d62a17ae 1824int ospf_area_import_list_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1825{
d62a17ae 1826 IMPORT_LIST(area) = 0;
718e3744 1827
d62a17ae 1828 if (IMPORT_NAME(area))
1829 free(IMPORT_NAME(area));
718e3744 1830
d62a17ae 1831 IMPORT_NAME(area) = NULL;
1832 ospf_area_check_free(ospf, area->area_id);
718e3744 1833
d62a17ae 1834 ospf_schedule_abr_task(ospf);
718e3744 1835
d62a17ae 1836 return 1;
718e3744 1837}
1838
d62a17ae 1839int ospf_timers_refresh_set(struct ospf *ospf, int interval)
718e3744 1840{
d62a17ae 1841 int time_left;
718e3744 1842
d62a17ae 1843 if (ospf->lsa_refresh_interval == interval)
1844 return 1;
718e3744 1845
d62a17ae 1846 time_left = ospf->lsa_refresh_interval
1847 - (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1848
d62a17ae 1849 if (time_left > interval) {
cccd44f3 1850 THREAD_OFF(ospf->t_lsa_refresher);
d62a17ae 1851 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
1852 interval, &ospf->t_lsa_refresher);
1853 }
1854 ospf->lsa_refresh_interval = interval;
1855
1856 return 1;
718e3744 1857}
1858
d62a17ae 1859int ospf_timers_refresh_unset(struct ospf *ospf)
718e3744 1860{
d62a17ae 1861 int time_left;
718e3744 1862
d62a17ae 1863 time_left = ospf->lsa_refresh_interval
1864 - (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1865
d62a17ae 1866 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) {
cccd44f3 1867 THREAD_OFF(ospf->t_lsa_refresher);
d62a17ae 1868 ospf->t_lsa_refresher = NULL;
1869 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
1870 OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
1871 &ospf->t_lsa_refresher);
1872 }
718e3744 1873
d62a17ae 1874 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
718e3744 1875
d62a17ae 1876 return 1;
718e3744 1877}
1878
6b0655a2 1879
d62a17ae 1880static struct ospf_nbr_nbma *ospf_nbr_nbma_new(void)
718e3744 1881{
d62a17ae 1882 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1883
d62a17ae 1884 nbr_nbma = XCALLOC(MTYPE_OSPF_NEIGHBOR_STATIC,
1885 sizeof(struct ospf_nbr_nbma));
718e3744 1886
d62a17ae 1887 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1888 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
718e3744 1889
d62a17ae 1890 return nbr_nbma;
718e3744 1891}
1892
d62a17ae 1893static void ospf_nbr_nbma_free(struct ospf_nbr_nbma *nbr_nbma)
718e3744 1894{
d62a17ae 1895 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
718e3744 1896}
1897
d62a17ae 1898static void ospf_nbr_nbma_delete(struct ospf *ospf,
1899 struct ospf_nbr_nbma *nbr_nbma)
718e3744 1900{
d62a17ae 1901 struct route_node *rn;
1902 struct prefix_ipv4 p;
718e3744 1903
d62a17ae 1904 p.family = AF_INET;
1905 p.prefix = nbr_nbma->addr;
1906 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1907
d62a17ae 1908 rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
1909 if (rn) {
1910 ospf_nbr_nbma_free(rn->info);
1911 rn->info = NULL;
1912 route_unlock_node(rn);
1913 route_unlock_node(rn);
1914 }
718e3744 1915}
1916
d62a17ae 1917static void ospf_nbr_nbma_down(struct ospf_nbr_nbma *nbr_nbma)
718e3744 1918{
cccd44f3 1919 THREAD_OFF(nbr_nbma->t_poll);
718e3744 1920
d62a17ae 1921 if (nbr_nbma->nbr) {
1922 nbr_nbma->nbr->nbr_nbma = NULL;
1923 OSPF_NSM_EVENT_EXECUTE(nbr_nbma->nbr, NSM_KillNbr);
1924 }
718e3744 1925
d62a17ae 1926 if (nbr_nbma->oi)
1927 listnode_delete(nbr_nbma->oi->nbr_nbma, nbr_nbma);
718e3744 1928}
1929
d62a17ae 1930static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma,
1931 struct ospf_interface *oi)
718e3744 1932{
d62a17ae 1933 struct ospf_neighbor *nbr;
1934 struct route_node *rn;
1935 struct prefix p;
718e3744 1936
d62a17ae 1937 if (oi->type != OSPF_IFTYPE_NBMA)
1938 return;
718e3744 1939
d62a17ae 1940 if (nbr_nbma->nbr != NULL)
1941 return;
718e3744 1942
d62a17ae 1943 if (IPV4_ADDR_SAME(&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1944 return;
718e3744 1945
d62a17ae 1946 nbr_nbma->oi = oi;
1947 listnode_add(oi->nbr_nbma, nbr_nbma);
718e3744 1948
d62a17ae 1949 /* Get neighbor information from table. */
1950 p.family = AF_INET;
1951 p.prefixlen = IPV4_MAX_BITLEN;
1952 p.u.prefix4 = nbr_nbma->addr;
718e3744 1953
c4efd0f4 1954 rn = route_node_get(oi->nbrs, &p);
d62a17ae 1955 if (rn->info) {
1956 nbr = rn->info;
1957 nbr->nbr_nbma = nbr_nbma;
1958 nbr_nbma->nbr = nbr;
718e3744 1959
d62a17ae 1960 route_unlock_node(rn);
1961 } else {
1962 nbr = rn->info = ospf_nbr_new(oi);
1963 nbr->state = NSM_Down;
1964 nbr->src = nbr_nbma->addr;
1965 nbr->nbr_nbma = nbr_nbma;
1966 nbr->priority = nbr_nbma->priority;
1967 nbr->address = p;
718e3744 1968
d62a17ae 1969 nbr_nbma->nbr = nbr;
1970
659f4e40
RZ
1971 /* Configure BFD if interface has it. */
1972 ospf_neighbor_bfd_apply(nbr);
1973
d62a17ae 1974 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start);
1975 }
718e3744 1976}
1977
d62a17ae 1978void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi)
718e3744 1979{
d62a17ae 1980 struct ospf_nbr_nbma *nbr_nbma;
1981 struct route_node *rn;
1982 struct prefix_ipv4 p;
718e3744 1983
d62a17ae 1984 if (oi->type != OSPF_IFTYPE_NBMA)
1985 return;
718e3744 1986
d62a17ae 1987 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
1988 if ((nbr_nbma = rn->info))
1989 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL) {
1990 p.family = AF_INET;
1991 p.prefix = nbr_nbma->addr;
1992 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1993
d62a17ae 1994 if (prefix_match(oi->address,
1995 (struct prefix *)&p))
1996 ospf_nbr_nbma_add(nbr_nbma, oi);
1997 }
718e3744 1998}
1999
d62a17ae 2000struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *ospf,
2001 struct in_addr nbr_addr)
718e3744 2002{
d62a17ae 2003 struct route_node *rn;
2004 struct prefix_ipv4 p;
718e3744 2005
d62a17ae 2006 p.family = AF_INET;
2007 p.prefix = nbr_addr;
2008 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 2009
d62a17ae 2010 rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
2011 if (rn) {
2012 route_unlock_node(rn);
2013 return rn->info;
2014 }
2015 return NULL;
718e3744 2016}
2017
d62a17ae 2018int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 2019{
d62a17ae 2020 struct ospf_nbr_nbma *nbr_nbma;
2021 struct ospf_interface *oi;
2022 struct prefix_ipv4 p;
2023 struct route_node *rn;
2024 struct listnode *node;
718e3744 2025
d62a17ae 2026 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2027 if (nbr_nbma)
2028 return 0;
718e3744 2029
d62a17ae 2030 nbr_nbma = ospf_nbr_nbma_new();
2031 nbr_nbma->addr = nbr_addr;
718e3744 2032
d62a17ae 2033 p.family = AF_INET;
2034 p.prefix = nbr_addr;
2035 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 2036
d62a17ae 2037 rn = route_node_get(ospf->nbr_nbma, (struct prefix *)&p);
2038 if (rn->info)
2039 route_unlock_node(rn);
2040 rn->info = nbr_nbma;
718e3744 2041
d62a17ae 2042 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
2043 if (oi->type == OSPF_IFTYPE_NBMA)
2044 if (prefix_match(oi->address, (struct prefix *)&p)) {
2045 ospf_nbr_nbma_add(nbr_nbma, oi);
2046 break;
2047 }
2048 }
718e3744 2049
d62a17ae 2050 return 1;
718e3744 2051}
2052
d62a17ae 2053int ospf_nbr_nbma_unset(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 2054{
d62a17ae 2055 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2056
d62a17ae 2057 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2058 if (nbr_nbma == NULL)
2059 return 0;
718e3744 2060
d62a17ae 2061 ospf_nbr_nbma_down(nbr_nbma);
2062 ospf_nbr_nbma_delete(ospf, nbr_nbma);
718e3744 2063
d62a17ae 2064 return 1;
718e3744 2065}
2066
d62a17ae 2067int ospf_nbr_nbma_priority_set(struct ospf *ospf, struct in_addr nbr_addr,
d7c0a89a 2068 uint8_t priority)
718e3744 2069{
d62a17ae 2070 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2071
d62a17ae 2072 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2073 if (nbr_nbma == NULL)
2074 return 0;
718e3744 2075
d62a17ae 2076 if (nbr_nbma->priority != priority)
2077 nbr_nbma->priority = priority;
718e3744 2078
d62a17ae 2079 return 1;
718e3744 2080}
2081
d62a17ae 2082int ospf_nbr_nbma_priority_unset(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 2083{
d62a17ae 2084 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2085
d62a17ae 2086 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2087 if (nbr_nbma == NULL)
2088 return 0;
718e3744 2089
d62a17ae 2090 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
2091 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
718e3744 2092
d62a17ae 2093 return 1;
718e3744 2094}
2095
d62a17ae 2096int ospf_nbr_nbma_poll_interval_set(struct ospf *ospf, struct in_addr nbr_addr,
2097 unsigned int interval)
718e3744 2098{
d62a17ae 2099 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2100
d62a17ae 2101 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2102 if (nbr_nbma == NULL)
2103 return 0;
718e3744 2104
d62a17ae 2105 if (nbr_nbma->v_poll != interval) {
2106 nbr_nbma->v_poll = interval;
2107 if (nbr_nbma->oi && ospf_if_is_up(nbr_nbma->oi)) {
cccd44f3 2108 THREAD_OFF(nbr_nbma->t_poll);
d62a17ae 2109 OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer,
2110 nbr_nbma->v_poll);
2111 }
718e3744 2112 }
718e3744 2113
d62a17ae 2114 return 1;
718e3744 2115}
2116
d62a17ae 2117int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
718e3744 2118{
d62a17ae 2119 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2120
d62a17ae 2121 nbr_nbma = ospf_nbr_nbma_lookup(ospf, addr);
2122 if (nbr_nbma == NULL)
2123 return 0;
718e3744 2124
d62a17ae 2125 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
2126 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
718e3744 2127
d62a17ae 2128 return 1;
718e3744 2129}
2130
d62a17ae 2131void ospf_master_init(struct thread_master *master)
718e3744 2132{
6006b807 2133 memset(&ospf_master, 0, sizeof(ospf_master));
020709f9 2134
d62a17ae 2135 om = &ospf_master;
2136 om->ospf = list_new();
2137 om->master = master;
020709f9 2138}
b5a8894d
CS
2139
2140/* Link OSPF instance to VRF. */
2141void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
2142{
2143 ospf->vrf_id = vrf->vrf_id;
2144 if (vrf->info != (void *)ospf)
2145 vrf->info = (void *)ospf;
2146}
2147
2148/* Unlink OSPF instance from VRF. */
2149void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
2150{
2151 if (vrf->info == (void *)ospf)
2152 vrf->info = NULL;
2153 ospf->vrf_id = VRF_UNKNOWN;
2154}
2155
2156/* This is hook function for vrf create called as part of vrf_init */
2157static int ospf_vrf_new(struct vrf *vrf)
2158{
2159 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2160 zlog_debug("%s: VRF Created: %s(%u)", __func__, vrf->name,
2161 vrf->vrf_id);
b5a8894d
CS
2162
2163 return 0;
2164}
2165
2166/* This is hook function for vrf delete call as part of vrf_init */
2167static int ospf_vrf_delete(struct vrf *vrf)
2168{
2169 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2170 zlog_debug("%s: VRF Deletion: %s(%u)", __func__, vrf->name,
2171 vrf->vrf_id);
b5a8894d
CS
2172
2173 return 0;
2174}
2175
de11c1bc 2176static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf, bool set)
3d9f7302
PZ
2177{
2178 int type;
2179 struct list *red_list;
2180
2181 for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
2182 red_list = ospf->redist[type];
2183 if (!red_list)
2184 continue;
2185 if (IS_DEBUG_OSPF_EVENT)
2186 zlog_debug(
2187 "%s: setting redist vrf %d bitmap for type %d",
2188 __func__, ospf->vrf_id, type);
de11c1bc
IR
2189 if (set)
2190 vrf_bitmap_set(zclient->redist[AFI_IP][type],
2191 ospf->vrf_id);
2192 else
2193 vrf_bitmap_unset(zclient->redist[AFI_IP][type],
2194 ospf->vrf_id);
3d9f7302 2195 }
b46538c4
IR
2196
2197 red_list = ospf->redist[DEFAULT_ROUTE];
2198 if (red_list) {
2199 if (set)
2200 vrf_bitmap_set(zclient->default_information[AFI_IP],
2201 ospf->vrf_id);
2202 else
2203 vrf_bitmap_unset(zclient->default_information[AFI_IP],
2204 ospf->vrf_id);
2205 }
3d9f7302
PZ
2206}
2207
b5a8894d
CS
2208/* Enable OSPF VRF instance */
2209static int ospf_vrf_enable(struct vrf *vrf)
2210{
2211 struct ospf *ospf = NULL;
7d206035 2212 vrf_id_t old_vrf_id;
3c0eb8fa 2213 int ret = 0;
b5a8894d
CS
2214
2215 if (IS_DEBUG_OSPF_EVENT)
5e81f5dd
DS
2216 zlog_debug("%s: VRF %s id %u enabled", __func__, vrf->name,
2217 vrf->vrf_id);
b5a8894d
CS
2218
2219 ospf = ospf_lookup_by_name(vrf->name);
2220 if (ospf) {
2221 old_vrf_id = ospf->vrf_id;
2222 /* We have instance configured, link to VRF and make it "up". */
2223 ospf_vrf_link(ospf, vrf);
2224 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
2225 zlog_debug(
2226 "%s: ospf linked to vrf %s vrf_id %u (old id %u)",
5e81f5dd 2227 __func__, vrf->name, ospf->vrf_id, old_vrf_id);
b5a8894d
CS
2228
2229 if (old_vrf_id != ospf->vrf_id) {
de11c1bc 2230 ospf_set_redist_vrf_bitmaps(ospf, true);
3d9f7302 2231
de11c1bc
IR
2232 /* start zebra redist to us for new vrf */
2233 ospf_zebra_vrf_register(ospf);
313d7993 2234
de11c1bc 2235 ret = ospf_sock_init(ospf);
3c0eb8fa
PG
2236 if (ret < 0 || ospf->fd <= 0)
2237 return 0;
996c9314
LB
2238 thread_add_read(master, ospf_read, ospf, ospf->fd,
2239 &ospf->t_read);
b5a8894d
CS
2240 ospf->oi_running = 1;
2241 ospf_router_id_update(ospf);
2242 }
2243 }
2244
2245 return 0;
2246}
2247
2248/* Disable OSPF VRF instance */
2249static int ospf_vrf_disable(struct vrf *vrf)
2250{
2251 struct ospf *ospf = NULL;
2252 vrf_id_t old_vrf_id = VRF_UNKNOWN;
2253
2254 if (vrf->vrf_id == VRF_DEFAULT)
2255 return 0;
2256
2257 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2258 zlog_debug("%s: VRF %s id %d disabled.", __func__, vrf->name,
2259 vrf->vrf_id);
b5a8894d
CS
2260
2261 ospf = ospf_lookup_by_name(vrf->name);
2262 if (ospf) {
2263 old_vrf_id = ospf->vrf_id;
2264
de11c1bc
IR
2265 ospf_zebra_vrf_deregister(ospf);
2266
2267 ospf_set_redist_vrf_bitmaps(ospf, false);
2268
b5a8894d
CS
2269 /* We have instance configured, unlink
2270 * from VRF and make it "down".
2271 */
2272 ospf_vrf_unlink(ospf, vrf);
2273 ospf->oi_running = 0;
2274 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2275 zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__,
2276 old_vrf_id);
bc1f09de 2277 THREAD_OFF(ospf->t_read);
3c0eb8fa
PG
2278 close(ospf->fd);
2279 ospf->fd = -1;
b5a8894d
CS
2280 }
2281
2282 /* Note: This is a callback, the VRF will be deleted by the caller. */
2283 return 0;
2284}
2285
2286void ospf_vrf_init(void)
2287{
996c9314 2288 vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
ac2cb9bf 2289 ospf_vrf_delete);
b5a8894d
CS
2290}
2291
2292void ospf_vrf_terminate(void)
2293{
2294 vrf_terminate();
2295}
2296
2297const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
2298{
2299 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
2300
2301 return vrf ? vrf->name : "NIL";
2302}
88b6b28e
DS
2303
2304const char *ospf_get_name(const struct ospf *ospf)
2305{
2306 if (ospf->name)
2307 return ospf->name;
2308 else
2309 return VRF_DEFAULT_NAME;
2310}