]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospfd.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[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
6f7bbc0c
MN
455 new->fr_configured = false;
456
d62a17ae 457 return new;
718e3744 458}
459
d7c0a89a 460struct ospf *ospf_lookup_instance(unsigned short instance)
7c8ff89e 461{
d62a17ae 462 struct ospf *ospf;
463 struct listnode *node, *nnode;
7c8ff89e 464
d62a17ae 465 if (listcount(om->ospf) == 0)
466 return NULL;
7c8ff89e 467
d62a17ae 468 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
469 if ((ospf->instance == 0 && instance == 0)
470 || (ospf->instance && instance
471 && ospf->instance == instance))
472 return ospf;
7c8ff89e 473
d62a17ae 474 return NULL;
7c8ff89e
DS
475}
476
d62a17ae 477static int ospf_is_ready(struct ospf *ospf)
52c62ab8 478{
d62a17ae 479 /* OSPF must be on and Router-ID must be configured. */
975a328e 480 if (!ospf || ospf->router_id.s_addr == INADDR_ANY)
d62a17ae 481 return 0;
482
483 return 1;
52c62ab8
JAG
484}
485
d7c0a89a 486struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
b5a8894d
CS
487{
488 struct ospf *ospf = NULL;
489 struct listnode *node, *nnode;
490
491 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
996c9314
LB
492 if ((ospf->instance == instance)
493 && ((ospf->name == NULL && name == NULL)
494 || (ospf->name && name
495 && strcmp(ospf->name, name) == 0)))
b5a8894d
CS
496 return ospf;
497 }
498 return NULL;
499}
500
409f98ab 501struct ospf *ospf_lookup(unsigned short instance, const char *name)
c3391da1
IR
502{
503 struct ospf *ospf;
504
409f98ab
IR
505 if (ospf_instance) {
506 ospf = ospf_lookup_instance(instance);
507 } else {
b5a8894d 508 ospf = ospf_lookup_by_inst_name(instance, name);
d62a17ae 509 }
7c8ff89e 510
d62a17ae 511 return ospf;
7c8ff89e
DS
512}
513
409f98ab 514struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
7c8ff89e 515{
d62a17ae 516 struct ospf *ospf;
7c8ff89e 517
409f98ab
IR
518 ospf = ospf_lookup(instance, name);
519
c572fbfe 520 *created = (ospf == NULL);
5bd78355 521 if (ospf == NULL)
409f98ab 522 ospf = ospf_new(instance, name);
68980084 523
d62a17ae 524 return ospf;
718e3744 525}
6b0655a2 526
b5a8894d
CS
527struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
528{
529 struct vrf *vrf = NULL;
530
531 vrf = vrf_lookup_by_id(vrf_id);
532 if (!vrf)
533 return NULL;
534 return (vrf->info) ? (struct ospf *)vrf->info : NULL;
b5a8894d
CS
535}
536
cbf32f74
IR
537uint32_t ospf_count_area_params(struct ospf *ospf)
538{
539 struct vrf *vrf;
540 struct interface *ifp;
541 uint32_t count = 0;
542
543 if (ospf->vrf_id != VRF_UNKNOWN) {
544 vrf = vrf_lookup_by_id(ospf->vrf_id);
545
546 FOR_ALL_INTERFACES (vrf, ifp) {
547 count += ospf_if_count_area_params(ifp);
548 }
549 }
550
551 return count;
552}
553
43b8d1d8
CS
554/* It should only be used when processing incoming info update from zebra.
555 * Other situations, it is not sufficient to lookup the ospf instance by
556 * vrf_name only without using the instance number.
557 */
558static struct ospf *ospf_lookup_by_name(const char *vrf_name)
b5a8894d
CS
559{
560 struct ospf *ospf = NULL;
561 struct listnode *node, *nnode;
562
563 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
43b8d1d8 564 if ((ospf->name == NULL && vrf_name == NULL)
996c9314
LB
565 || (ospf->name && vrf_name
566 && strcmp(ospf->name, vrf_name) == 0))
b5a8894d
CS
567 return ospf;
568 return NULL;
569}
570
c9c93d50 571/* Handle the second half of deferred shutdown. This is called either
572 * from the deferred-shutdown timer thread, or directly through
573 * ospf_deferred_shutdown_check.
88d6cf37 574 *
575 * Function is to cleanup G-R state, if required then call ospf_finish_final
576 * to complete shutdown of this ospf instance. Possibly exit if the
577 * whole process is being shutdown and this was the last OSPF instance.
578 */
d62a17ae 579static void ospf_deferred_shutdown_finish(struct ospf *ospf)
580{
581 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
cccd44f3 582 THREAD_OFF(ospf->t_deferred_shutdown);
d62a17ae 583
584 ospf_finish_final(ospf);
585
586 /* *ospf is now invalid */
88d6cf37 587
d62a17ae 588 /* ospfd being shut-down? If so, was this the last ospf instance? */
589 if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)
590 && (listcount(om->ospf) == 0)) {
e15a935c 591 frr_fini();
d62a17ae 592 exit(0);
593 }
594
595 return;
88d6cf37 596}
597
598/* Timer thread for G-R */
cc9f21da 599static void ospf_deferred_shutdown_timer(struct thread *t)
88d6cf37 600{
d62a17ae 601 struct ospf *ospf = THREAD_ARG(t);
602
603 ospf_deferred_shutdown_finish(ospf);
88d6cf37 604}
605
c9c93d50 606/* Check whether deferred-shutdown must be scheduled, otherwise call
88d6cf37 607 * down directly into second-half of instance shutdown.
608 */
d62a17ae 609static void ospf_deferred_shutdown_check(struct ospf *ospf)
610{
611 unsigned long timeout;
612 struct listnode *ln;
613 struct ospf_area *area;
614
615 /* deferred shutdown already running? */
616 if (ospf->t_deferred_shutdown)
617 return;
618
619 /* Should we try push out max-metric LSAs? */
620 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) {
621 for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
622 SET_FLAG(area->stub_router_state,
623 OSPF_AREA_ADMIN_STUB_ROUTED);
624
625 if (!CHECK_FLAG(area->stub_router_state,
626 OSPF_AREA_IS_STUB_ROUTED))
627 ospf_router_lsa_update_area(area);
628 }
629 timeout = ospf->stub_router_shutdown_time;
630 } else {
631 /* No timer needed */
632 ospf_deferred_shutdown_finish(ospf);
633 return;
634 }
635
636 OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
637 timeout);
638 return;
88d6cf37 639}
6b0655a2 640
88d6cf37 641/* Shut down the entire process */
d62a17ae 642void ospf_terminate(void)
643{
644 struct ospf *ospf;
645 struct listnode *node, *nnode;
646
647 /* shutdown already in progress */
648 if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
649 return;
650
651 SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN);
652
41b21bfa 653 /* Skip some steps if OSPF not actually running */
d62a17ae 654 if (listcount(om->ospf) == 0)
41b21bfa 655 goto done;
d62a17ae 656
d62a17ae 657 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
658 ospf_finish(ospf);
659
51f8588e
RW
660 /* Cleanup GR */
661 ospf_gr_helper_stop();
662
ded42248 663 /* Cleanup route maps */
ded42248
CS
664 route_map_finish();
665
666 /* reverse prefix_list_init */
667 prefix_list_add_hook(NULL);
668 prefix_list_delete_hook(NULL);
669 prefix_list_reset();
670
671 /* Cleanup vrf info */
672 ospf_vrf_terminate();
673
d62a17ae 674 /* Deliberately go back up, hopefully to thread scheduler, as
675 * One or more ospf_finish()'s may have deferred shutdown to a timer
676 * thread
677 */
678 zclient_stop(zclient);
679 zclient_free(zclient);
8879bd22 680
41b21bfa 681done:
8879bd22 682 frr_fini();
d62a17ae 683}
684
685void ospf_finish(struct ospf *ospf)
686{
687 /* let deferred shutdown decide */
688 ospf_deferred_shutdown_check(ospf);
689
690 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
691 * deferred to expiry of G-S timer thread. Return back up, hopefully
692 * to thread scheduler.
693 */
694 return;
88d6cf37 695}
696
697/* Final cleanup of ospf instance */
d62a17ae 698static void ospf_finish_final(struct ospf *ospf)
718e3744 699{
1113a2fb 700 struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
d62a17ae 701 struct route_node *rn;
702 struct ospf_nbr_nbma *nbr_nbma;
703 struct ospf_lsa *lsa;
d62a17ae 704 struct ospf_interface *oi;
705 struct ospf_area *area;
706 struct ospf_vl_data *vl_data;
707 struct listnode *node, *nnode;
ca187fd3 708 struct ospf_redist *red;
d62a17ae 709 int i;
7c8ff89e 710
d62a17ae 711 QOBJ_UNREG(ospf);
7c8ff89e 712
d62a17ae 713 ospf_opaque_type11_lsa_term(ospf);
953cde65 714
bcf4475e
OD
715 ospf_opaque_finish();
716
10514170
RW
717 if (!ospf->gr_info.prepare_in_progress)
718 ospf_flush_self_originated_lsas_now(ospf);
953cde65 719
d62a17ae 720 /* Unregister redistribution */
721 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
722 struct list *red_list;
718e3744 723
d62a17ae 724 red_list = ospf->redist[i];
725 if (!red_list)
726 continue;
718e3744 727
1d753551 728 for (ALL_LIST_ELEMENTS(red_list, node, nnode, red)) {
d62a17ae 729 ospf_redistribute_unset(ospf, i, red->instance);
1d753551
DS
730 ospf_redist_del(ospf, i, red->instance);
731 }
d62a17ae 732 }
ca187fd3
IR
733 red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
734 if (red) {
735 ospf_routemap_unset(red);
736 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
737 ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE, 0, 0);
738 }
718e3744 739
d62a17ae 740 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
741 ospf_remove_vls_through_area(ospf, area);
718e3744 742
d62a17ae 743 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
744 ospf_vl_delete(ospf, vl_data);
718e3744 745
6a154c88 746 list_delete(&ospf->vlinks);
718e3744 747
132a782e 748 /* shutdown LDP-Sync */
749 if (ospf->vrf_id == VRF_DEFAULT)
750 ospf_ldp_sync_gbl_exit(ospf, true);
751
d62a17ae 752 /* Reset interface. */
753 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
754 ospf_if_free(oi);
6a154c88 755 list_delete(&ospf->oiflist);
c32eba04 756 ospf->oi_running = 0;
718e3744 757
b5a8894d
CS
758 /* De-Register VRF */
759 ospf_zebra_vrf_deregister(ospf);
760
d62a17ae 761 /* Clear static neighbors */
762 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
763 if ((nbr_nbma = rn->info)) {
cccd44f3 764 THREAD_OFF(nbr_nbma->t_poll);
718e3744 765
d62a17ae 766 if (nbr_nbma->nbr) {
767 nbr_nbma->nbr->nbr_nbma = NULL;
768 nbr_nbma->nbr = NULL;
769 }
770
771 if (nbr_nbma->oi) {
772 listnode_delete(nbr_nbma->oi->nbr_nbma,
773 nbr_nbma);
774 nbr_nbma->oi = NULL;
775 }
776
777 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
778 }
779
780 route_table_finish(ospf->nbr_nbma);
781
782 /* Clear networks and Areas. */
783 for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
784 struct ospf_network *network;
785
786 if ((network = rn->info) != NULL) {
787 ospf_network_free(ospf, network);
788 rn->info = NULL;
789 route_unlock_node(rn);
790 }
91e6a0e5 791 }
7f586094 792 route_table_finish(ospf->networks);
718e3744 793
d62a17ae 794 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
795 listnode_delete(ospf->areas, area);
796 ospf_area_free(area);
797 }
718e3744 798
d62a17ae 799 /* Cancel all timers. */
cccd44f3
DS
800 THREAD_OFF(ospf->t_read);
801 THREAD_OFF(ospf->t_write);
802 THREAD_OFF(ospf->t_spf_calc);
803 THREAD_OFF(ospf->t_ase_calc);
804 THREAD_OFF(ospf->t_maxage);
805 THREAD_OFF(ospf->t_maxage_walker);
806 THREAD_OFF(ospf->t_abr_task);
6f7bbc0c 807 THREAD_OFF(ospf->t_abr_fr);
cccd44f3
DS
808 THREAD_OFF(ospf->t_asbr_check);
809 THREAD_OFF(ospf->t_asbr_nssa_redist_update);
810 THREAD_OFF(ospf->t_distribute_update);
811 THREAD_OFF(ospf->t_lsa_refresher);
812 THREAD_OFF(ospf->t_opaque_lsa_self);
813 THREAD_OFF(ospf->t_sr_update);
814 THREAD_OFF(ospf->t_default_routemap_timer);
815 THREAD_OFF(ospf->t_external_aggr);
816 THREAD_OFF(ospf->gr_info.t_grace_period);
d62a17ae 817
996c9314 818 LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
044506e7 819 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
996c9314 820 LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
044506e7 821 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
d62a17ae 822
823 ospf_lsdb_delete_all(ospf->lsdb);
824 ospf_lsdb_free(ospf->lsdb);
825
826 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
d62a17ae 827 if ((lsa = rn->info) != NULL) {
828 ospf_lsa_unlock(&lsa);
829 rn->info = NULL;
69843e81 830 route_unlock_node(rn);
d62a17ae 831 }
d62a17ae 832 }
833 route_table_finish(ospf->maxage_lsa);
834
835 if (ospf->old_table)
836 ospf_route_table_free(ospf->old_table);
837 if (ospf->new_table) {
10514170
RW
838 if (!ospf->gr_info.prepare_in_progress)
839 ospf_route_delete(ospf, ospf->new_table);
d62a17ae 840 ospf_route_table_free(ospf->new_table);
841 }
9bf19426
RZ
842 if (ospf->oall_rtrs)
843 ospf_rtrs_free(ospf->oall_rtrs);
844 if (ospf->all_rtrs)
845 ospf_rtrs_free(ospf->all_rtrs);
d62a17ae 846 if (ospf->old_rtrs)
847 ospf_rtrs_free(ospf->old_rtrs);
848 if (ospf->new_rtrs)
849 ospf_rtrs_free(ospf->new_rtrs);
850 if (ospf->new_external_route) {
10514170
RW
851 if (!ospf->gr_info.prepare_in_progress)
852 ospf_route_delete(ospf, ospf->new_external_route);
d62a17ae 853 ospf_route_table_free(ospf->new_external_route);
854 }
855 if (ospf->old_external_route) {
10514170
RW
856 if (!ospf->gr_info.prepare_in_progress)
857 ospf_route_delete(ospf, ospf->old_external_route);
d62a17ae 858 ospf_route_table_free(ospf->old_external_route);
859 }
860 if (ospf->external_lsas) {
861 ospf_ase_external_lsas_finish(ospf->external_lsas);
862 }
718e3744 863
d62a17ae 864 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
865 struct list *ext_list;
d62a17ae 866 struct ospf_external *ext;
867
de1ac5fd 868 ext_list = ospf->external[i];
d62a17ae 869 if (!ext_list)
870 continue;
871
76fdc7f4 872 for (ALL_LIST_ELEMENTS(ext_list, node, nnode, ext)) {
d62a17ae 873 if (ext->external_info)
874 for (rn = route_top(ext->external_info); rn;
875 rn = route_next(rn)) {
876 if (rn->info == NULL)
877 continue;
878
879 XFREE(MTYPE_OSPF_EXTERNAL_INFO,
880 rn->info);
881 rn->info = NULL;
882 route_unlock_node(rn);
883 }
1d753551
DS
884
885 ospf_external_del(ospf, i, ext->instance);
d62a17ae 886 }
887 }
718e3744 888
d62a17ae 889 ospf_distance_reset(ospf);
890 route_table_finish(ospf->distance_table);
7c8ff89e 891
ad7222b7 892 /* Release extrenal Aggregator table */
893 for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
894 struct ospf_external_aggr_rt *aggr;
895
896 aggr = rn->info;
897
898 if (aggr) {
899 ospf_external_aggregator_free(aggr);
900 rn->info = NULL;
901 route_unlock_node(rn);
902 }
903 }
904
905 route_table_finish(ospf->rt_aggr_tbl);
906
907
594f80c8 908 ospf_free_refresh_queue(ospf);
909
c32eba04
CS
910 list_delete(&ospf->areas);
911 list_delete(&ospf->oi_write_q);
912
06bc3110 913 /* Reset GR helper data structers */
51f8588e 914 ospf_gr_helper_instance_stop(ospf);
06bc3110 915
c32eba04
CS
916 close(ospf->fd);
917 stream_free(ospf->ibuf);
918 ospf->fd = -1;
3d5b9855 919 ospf->max_multipath = MULTIPATH_NUM;
d62a17ae 920 ospf_delete(ospf);
7c8ff89e 921
1113a2fb 922 if (vrf)
923 ospf_vrf_unlink(ospf, vrf);
b5a8894d 924
ac2cb9bf 925 XFREE(MTYPE_OSPF_TOP, ospf->name);
d62a17ae 926 XFREE(MTYPE_OSPF_TOP, ospf);
718e3744 927}
928
6b0655a2 929
718e3744 930/* allocate new OSPF Area object */
7fd0729f 931struct ospf_area *ospf_area_new(struct ospf *ospf, struct in_addr area_id)
718e3744 932{
d62a17ae 933 struct ospf_area *new;
718e3744 934
d62a17ae 935 /* Allocate new config_network. */
936 new = XCALLOC(MTYPE_OSPF_AREA, sizeof(struct ospf_area));
718e3744 937
d62a17ae 938 new->ospf = ospf;
718e3744 939
d62a17ae 940 new->area_id = area_id;
941 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
718e3744 942
d62a17ae 943 new->external_routing = OSPF_AREA_DEFAULT;
944 new->default_cost = 1;
945 new->auth_type = OSPF_AUTH_NULL;
718e3744 946
d62a17ae 947 /* New LSDB init. */
948 new->lsdb = ospf_lsdb_new();
718e3744 949
d62a17ae 950 /* Self-originated LSAs initialize. */
951 new->router_lsa_self = NULL;
718e3744 952
6f7bbc0c
MN
953 /* Initialize FR field */
954 new->fr_info.enabled = false;
955 new->fr_info.configured = false;
956 new->fr_info.state_changed = false;
957 new->fr_info.router_lsas_recv_dc_bit = 0;
958 new->fr_info.indication_lsa_self = NULL;
959 new->fr_info.area_ind_lsa_recvd = false;
960 new->fr_info.area_dc_clear = false;
961
d62a17ae 962 ospf_opaque_type10_lsa_init(new);
718e3744 963
d62a17ae 964 new->oiflist = list_new();
965 new->ranges = route_table_init();
718e3744 966
d62a17ae 967 if (area_id.s_addr == OSPF_AREA_BACKBONE)
968 ospf->backbone = new;
969
970 return new;
718e3744 971}
972
f91ce319 973void ospf_area_lsdb_discard_delete(struct ospf_area *area)
718e3744 974{
d62a17ae 975 struct route_node *rn;
976 struct ospf_lsa *lsa;
977
996c9314 978 LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
044506e7 979 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 980 LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
044506e7 981 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 982 LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
044506e7 983 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 984 LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
044506e7 985 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
68980084 986
996c9314 987 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
044506e7 988 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 989 LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
044506e7 990 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 991 LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
044506e7 992 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
718e3744 993
d62a17ae 994 ospf_lsdb_delete_all(area->lsdb);
f91ce319
MR
995}
996
997static void ospf_area_free(struct ospf_area *area)
998{
999 ospf_opaque_type10_lsa_term(area);
1000
1001 /* Free LSDBs. */
1002 ospf_area_lsdb_discard_delete(area);
1003
d62a17ae 1004 ospf_lsdb_free(area->lsdb);
718e3744 1005
d62a17ae 1006 ospf_lsa_unlock(&area->router_lsa_self);
718e3744 1007
d62a17ae 1008 route_table_finish(area->ranges);
6a154c88 1009 list_delete(&area->oiflist);
718e3744 1010
d62a17ae 1011 if (EXPORT_NAME(area))
1012 free(EXPORT_NAME(area));
718e3744 1013
d62a17ae 1014 if (IMPORT_NAME(area))
1015 free(IMPORT_NAME(area));
718e3744 1016
d62a17ae 1017 /* Cancel timer. */
cccd44f3
DS
1018 THREAD_OFF(area->t_stub_router);
1019 THREAD_OFF(area->t_opaque_lsa_self);
718e3744 1020
d62a17ae 1021 if (OSPF_IS_AREA_BACKBONE(area))
1022 area->ospf->backbone = NULL;
1023
1024 XFREE(MTYPE_OSPF_AREA, area);
718e3744 1025}
1026
d62a17ae 1027void ospf_area_check_free(struct ospf *ospf, struct in_addr area_id)
718e3744 1028{
d62a17ae 1029 struct ospf_area *area;
718e3744 1030
d62a17ae 1031 area = ospf_area_lookup_by_area_id(ospf, area_id);
1032 if (area && listcount(area->oiflist) == 0 && area->ranges->top == NULL
19ce7d5e 1033 && !ospf_vl_count(ospf, area)
d62a17ae 1034 && area->shortcut_configured == OSPF_SHORTCUT_DEFAULT
1035 && area->external_routing == OSPF_AREA_DEFAULT
1036 && area->no_summary == 0 && area->default_cost == 1
1037 && EXPORT_NAME(area) == NULL && IMPORT_NAME(area) == NULL
1038 && area->auth_type == OSPF_AUTH_NULL) {
1039 listnode_delete(ospf->areas, area);
1040 ospf_area_free(area);
1041 }
718e3744 1042}
1043
d62a17ae 1044struct ospf_area *ospf_area_get(struct ospf *ospf, struct in_addr area_id)
718e3744 1045{
d62a17ae 1046 struct ospf_area *area;
1047
1048 area = ospf_area_lookup_by_area_id(ospf, area_id);
1049 if (!area) {
1050 area = ospf_area_new(ospf, area_id);
1051 listnode_add_sort(ospf->areas, area);
1052 ospf_check_abr_status(ospf);
1053 if (ospf->stub_router_admin_set
1054 == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) {
1055 SET_FLAG(area->stub_router_state,
1056 OSPF_AREA_ADMIN_STUB_ROUTED);
1057 }
1058 }
718e3744 1059
d62a17ae 1060 return area;
718e3744 1061}
1062
d62a17ae 1063struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *ospf,
1064 struct in_addr area_id)
718e3744 1065{
d62a17ae 1066 struct ospf_area *area;
1067 struct listnode *node;
718e3744 1068
d62a17ae 1069 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
1070 if (IPV4_ADDR_SAME(&area->area_id, &area_id))
1071 return area;
718e3744 1072
d62a17ae 1073 return NULL;
718e3744 1074}
1075
d62a17ae 1076void ospf_area_add_if(struct ospf_area *area, struct ospf_interface *oi)
718e3744 1077{
d62a17ae 1078 listnode_add(area->oiflist, oi);
718e3744 1079}
1080
d62a17ae 1081void ospf_area_del_if(struct ospf_area *area, struct ospf_interface *oi)
718e3744 1082{
d62a17ae 1083 listnode_delete(area->oiflist, oi);
718e3744 1084}
1085
52c62ab8 1086
7fd0729f
G
1087struct ospf_interface *add_ospf_interface(struct connected *co,
1088 struct ospf_area *area)
953cde65 1089{
d62a17ae 1090 struct ospf_interface *oi;
953cde65 1091
d62a17ae 1092 oi = ospf_if_new(area->ospf, co->ifp, co->address);
1093 oi->connected = co;
953cde65 1094
d62a17ae 1095 oi->area = area;
953cde65 1096
d62a17ae 1097 oi->params = ospf_lookup_if_params(co->ifp, oi->address->u.prefix4);
1098 oi->output_cost = ospf_if_get_output_cost(oi);
953cde65 1099
d62a17ae 1100 /* Relate ospf interface to ospf instance. */
1101 oi->ospf = area->ospf;
953cde65 1102
d62a17ae 1103 /* update network type as interface flag */
1104 /* If network type is specified previously,
1105 skip network type setting. */
1106 oi->type = IF_DEF_PARAMS(co->ifp)->type;
bc97889b 1107 oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn;
953cde65 1108
d62a17ae 1109 /* Add pseudo neighbor. */
1110 ospf_nbr_self_reset(oi, oi->ospf->router_id);
953cde65 1111
d62a17ae 1112 ospf_area_add_if(oi->area, oi);
52c62ab8 1113
132a782e 1114 /* if LDP-IGP Sync is configured globally inherit config */
1115 ospf_ldp_sync_if_init(oi);
1116
d62a17ae 1117 /*
1461559c 1118 * if router_id is not configured, don't bring up
d62a17ae 1119 * interfaces.
1120 * ospf_router_id_update() will call ospf_if_update
1121 * whenever r-id is configured instead.
1122 */
975a328e
DA
1123 if ((area->ospf->router_id.s_addr != INADDR_ANY)
1124 && if_is_operative(co->ifp))
d62a17ae 1125 ospf_if_up(oi);
7fd0729f
G
1126
1127 return oi;
953cde65
JT
1128}
1129
1130static void update_redistributed(struct ospf *ospf, int add_to_ospf)
1131{
d62a17ae 1132 struct route_node *rn;
1133 struct external_info *ei;
1134 struct ospf_external *ext;
1135
de1ac5fd
CS
1136 if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) {
1137 ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0);
1138 if ((ext) && EXTERNAL_INFO(ext)) {
d62a17ae 1139 for (rn = route_top(EXTERNAL_INFO(ext)); rn;
1140 rn = route_next(rn)) {
de1ac5fd
CS
1141 ei = rn->info;
1142 if (ei == NULL)
1143 continue;
1144
1145 if (add_to_ospf) {
996c9314
LB
1146 if (ospf_external_info_find_lsa(ospf,
1147 &ei->p))
e474c143
MR
1148 if (!ospf_redistribute_check(
1149 ospf, ei, NULL))
de1ac5fd 1150 ospf_external_lsa_flush(
996c9314 1151 ospf, ei->type,
de1ac5fd
CS
1152 &ei->p,
1153 ei->ifindex /*, ei->nexthop */);
1154 } else {
1155 if (!ospf_external_info_find_lsa(
1156 ospf, &ei->p))
e474c143
MR
1157 if (ospf_redistribute_check(
1158 ospf, ei, NULL))
de1ac5fd 1159 ospf_external_lsa_originate(
996c9314 1160 ospf, ei);
d62a17ae 1161 }
1162 }
1163 }
de1ac5fd 1164 }
953cde65
JT
1165}
1166
718e3744 1167/* Config network statement related functions. */
d62a17ae 1168static struct ospf_network *ospf_network_new(struct in_addr area_id)
718e3744 1169{
d62a17ae 1170 struct ospf_network *new;
1171 new = XCALLOC(MTYPE_OSPF_NETWORK, sizeof(struct ospf_network));
718e3744 1172
d62a17ae 1173 new->area_id = area_id;
1174 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
1175
1176 return new;
718e3744 1177}
1178
d62a17ae 1179static void ospf_network_free(struct ospf *ospf, struct ospf_network *network)
718e3744 1180{
d62a17ae 1181 ospf_area_check_free(ospf, network->area_id);
1182 ospf_schedule_abr_task(ospf);
1183 XFREE(MTYPE_OSPF_NETWORK, network);
718e3744 1184}
1185
d62a17ae 1186int ospf_network_set(struct ospf *ospf, struct prefix_ipv4 *p,
1187 struct in_addr area_id, int df)
718e3744 1188{
d62a17ae 1189 struct ospf_network *network;
1190 struct ospf_area *area;
1191 struct route_node *rn;
718e3744 1192
d62a17ae 1193 rn = route_node_get(ospf->networks, (struct prefix *)p);
1194 if (rn->info) {
2b0a905a 1195 network = rn->info;
d62a17ae 1196 route_unlock_node(rn);
2b0a905a
DW
1197
1198 if (IPV4_ADDR_SAME(&area_id, &network->area_id)) {
1199 return 1;
1200 } else {
1201 /* There is already same network statement. */
1202 return 0;
1203 }
d62a17ae 1204 }
718e3744 1205
d62a17ae 1206 rn->info = network = ospf_network_new(area_id);
1207 network->area_id_fmt = df;
1208 area = ospf_area_get(ospf, area_id);
1209 ospf_area_display_format_set(ospf, area, df);
718e3744 1210
d62a17ae 1211 /* Run network config now. */
1212 ospf_network_run((struct prefix *)p, area);
718e3744 1213
d62a17ae 1214 /* Update connected redistribute. */
1215 update_redistributed(ospf, 1); /* interfaces possibly added */
718e3744 1216
d62a17ae 1217 ospf_area_check_free(ospf, area_id);
718e3744 1218
d62a17ae 1219 return 1;
718e3744 1220}
1221
d62a17ae 1222int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
1223 struct in_addr area_id)
718e3744 1224{
d62a17ae 1225 struct route_node *rn;
1226 struct ospf_network *network;
1227 struct listnode *node, *nnode;
1228 struct ospf_interface *oi;
718e3744 1229
d62a17ae 1230 rn = route_node_lookup(ospf->networks, (struct prefix *)p);
1231 if (rn == NULL)
1232 return 0;
718e3744 1233
d62a17ae 1234 network = rn->info;
1235 route_unlock_node(rn);
1236 if (!IPV4_ADDR_SAME(&area_id, &network->area_id))
1237 return 0;
718e3744 1238
d62a17ae 1239 ospf_network_free(ospf, rn->info);
1240 rn->info = NULL;
1241 route_unlock_node(rn); /* initial reference */
718e3744 1242
30c0daa4 1243 /* Find interfaces that are not configured already. */
d62a17ae 1244 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
30c0daa4 1245
996c9314
LB
1246 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
1247 continue;
30c0daa4 1248
996c9314 1249 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
d62a17ae 1250 }
953cde65 1251
d62a17ae 1252 /* Update connected redistribute. */
1253 update_redistributed(ospf, 0); /* interfaces possibly removed */
1254 ospf_area_check_free(ospf, area_id);
1255
1256 return 1;
953cde65
JT
1257}
1258
52c62ab8
JAG
1259/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means
1260 * there might not be any 'router ospf' config.
1261 *
1262 * Otherwise, doesn't do anything different to ospf_if_update for now
1263 */
b5a8894d 1264void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
953cde65 1265{
b5a8894d
CS
1266 if (!ospf)
1267 return;
d62a17ae 1268
1269 ospf_if_update(ospf, ifp);
1270 /* if_update does a update_redistributed */
1271
1272 return;
953cde65
JT
1273}
1274
b5a8894d 1275void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
953cde65 1276{
d62a17ae 1277 struct route_node *rn_oi;
953cde65 1278
d62a17ae 1279 if (!ospf)
1280 return; /* Ospf not ready yet */
953cde65 1281
d62a17ae 1282 /* Find interfaces that may need to be removed. */
1283 for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
1284 rn_oi = route_next(rn_oi)) {
b5a8894d 1285 struct ospf_interface *oi = NULL;
d62a17ae 1286
1287 if ((oi = rn_oi->info) == NULL)
1288 continue;
1289
1290 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
1291 continue;
1292
1293 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
1294 }
953cde65 1295
d62a17ae 1296 /* Update connected redistribute. */
1297 update_redistributed(ospf, 0); /* interfaces possibly removed */
718e3744 1298}
1299
570f7598 1300/* Check whether interface matches given network
1301 * returns: 1, true. 0, false
1302 */
d62a17ae 1303static int ospf_network_match_iface(const struct connected *co,
1304 const struct prefix *net)
570f7598 1305{
d62a17ae 1306 /* new approach: more elegant and conceptually clean */
1307 return prefix_match_network_statement(net, CONNECTED_PREFIX(co));
570f7598 1308}
1309
d62a17ae 1310static void ospf_update_interface_area(struct connected *co,
1311 struct ospf_area *area)
52c62ab8 1312{
d62a17ae 1313 struct ospf_interface *oi = ospf_if_table_lookup(co->ifp, co->address);
1314
1315 /* nothing to be done case */
1316 if (oi && oi->area == area) {
1317 return;
1318 }
1319
1320 if (oi)
1321 ospf_if_free(oi);
1322
1323 add_ospf_interface(co, area);
52c62ab8
JAG
1324}
1325
1326/* Run OSPF for the given subnet, taking into account the following
1327 * possible sources of area configuration, in the given order of preference:
1328 *
1329 * - Whether there is interface+address specific area configuration
1330 * - Whether there is a default area for the interface
1331 * - Whether there is an area given as a parameter.
1332 * - If no specific network prefix/area is supplied, whether there's
1333 * a matching network configured.
1334 */
d62a17ae 1335static void ospf_network_run_subnet(struct ospf *ospf, struct connected *co,
1336 struct prefix *p,
1337 struct ospf_area *given_area)
1338{
1339 struct ospf_interface *oi;
1340 struct ospf_if_params *params;
1341 struct ospf_area *area = NULL;
1342 struct route_node *rn;
1343 int configed = 0;
1344
1345 if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
1346 return;
1347
1348 if (co->address->family != AF_INET)
1349 return;
1350
1351 /* Try determine the appropriate area for this interface + address
1352 * Start by checking interface config
1353 */
1354 params = ospf_lookup_if_params(co->ifp, co->address->u.prefix4);
1355 if (params && OSPF_IF_PARAM_CONFIGURED(params, if_area))
1356 area = ospf_area_get(ospf, params->if_area);
1357 else {
1358 params = IF_DEF_PARAMS(co->ifp);
1359 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
1360 area = ospf_area_get(ospf, params->if_area);
1361 }
52c62ab8 1362
d62a17ae 1363 /* If we've found an interface and/or addr specific area, then we're
1364 * done
1365 */
1366 if (area) {
1367 ospf_update_interface_area(co, area);
1368 return;
1369 }
718e3744 1370
d62a17ae 1371 /* Otherwise, only remaining possibility is a matching network statement
1372 */
1373 if (p) {
1374 assert(given_area != NULL);
1375
1376 /* Which either was supplied as a parameter.. (e.g. cause a new
1377 * network/area was just added)..
1378 */
1379 if (p->family == co->address->family
1380 && ospf_network_match_iface(co, p))
1381 ospf_update_interface_area(co, given_area);
1382
1383 return;
1384 }
1385
1386 /* Else we have to search the existing network/area config to see
1387 * if any match..
1388 */
1389 for (rn = route_top(ospf->networks); rn; rn = route_next(rn))
1390 if (rn->info != NULL && ospf_network_match_iface(co, &rn->p)) {
1391 struct ospf_network *network =
1392 (struct ospf_network *)rn->info;
1393 area = ospf_area_get(ospf, network->area_id);
1394 ospf_update_interface_area(co, area);
1395 configed = 1;
1396 }
1397
1398 /* If the subnet isn't in any area, deconfigure */
1399 if (!configed && (oi = ospf_if_table_lookup(co->ifp, co->address)))
1400 ospf_if_free(oi);
718e3744 1401}
1402
d62a17ae 1403static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp,
1404 struct prefix *p,
1405 struct ospf_area *given_area)
718e3744 1406{
d62a17ae 1407 struct listnode *cnode;
1408 struct connected *co;
1409
1410 if (memcmp(ifp->name, "VLINK", 5) == 0)
1411 return;
718e3744 1412
d62a17ae 1413 /* Network prefix without area is nonsensical */
1414 if (p)
1415 assert(given_area != NULL);
1416
1417 /* if interface prefix is match specified prefix,
1418 then create socket and join multicast group. */
1419 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co))
1420 ospf_network_run_subnet(ospf, co, p, given_area);
718e3744 1421}
1422
d62a17ae 1423static void ospf_network_run(struct prefix *p, struct ospf_area *area)
718e3744 1424{
f4e14fdb 1425 struct vrf *vrf = vrf_lookup_by_id(area->ospf->vrf_id);
d62a17ae 1426 struct interface *ifp;
d62a17ae 1427
1428 /* Schedule Router ID Update. */
975a328e 1429 if (area->ospf->router_id.s_addr == INADDR_ANY)
d62a17ae 1430 ospf_router_id_update(area->ospf);
718e3744 1431
d62a17ae 1432 /* Get target interface. */
451fda4f 1433 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1434 ospf_network_run_interface(area->ospf, ifp, p, area);
718e3744 1435}
1436
d62a17ae 1437void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
1438{
1439 struct route_node *rn;
1440 struct listnode *node, *nnode;
1441 struct list *lst;
1442 struct ospf_lsa *lsa;
1443
1444 /* empty ls update queue */
1445 for (rn = route_top(oi->ls_upd_queue); rn; rn = route_next(rn))
1446 if ((lst = (struct list *)rn->info)) {
1447 for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa))
1448 ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */
6a154c88 1449 list_delete(&lst);
d62a17ae 1450 rn->info = NULL;
1451 }
1452
1453 /* remove update event */
bc1f09de 1454 THREAD_OFF(oi->t_ls_upd_event);
d62a17ae 1455}
6b0655a2 1456
d62a17ae 1457void ospf_if_update(struct ospf *ospf, struct interface *ifp)
718e3744 1458{
43b8d1d8 1459
d62a17ae 1460 if (!ospf)
43b8d1d8 1461 return;
b5a8894d
CS
1462
1463 if (IS_DEBUG_OSPF_EVENT)
996c9314 1464 zlog_debug(
096f7609
IR
1465 "%s: interface %s vrf %s(%u) ospf vrf %s vrf_id %u router_id %pI4",
1466 __func__, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
996c9314 1467 ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
96b663a3 1468 &ospf->router_id);
d62a17ae 1469
1470 /* OSPF must be ready. */
1471 if (!ospf_is_ready(ospf))
1472 return;
1473
1474 ospf_network_run_interface(ospf, ifp, NULL, NULL);
1475
1476 /* Update connected redistribute. */
1477 update_redistributed(ospf, 1);
ef7bd2a3 1478
d62a17ae 1479}
718e3744 1480
d62a17ae 1481void ospf_remove_vls_through_area(struct ospf *ospf, struct ospf_area *area)
718e3744 1482{
d62a17ae 1483 struct listnode *node, *nnode;
1484 struct ospf_vl_data *vl_data;
718e3744 1485
d62a17ae 1486 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
1487 if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1488 ospf_vl_delete(ospf, vl_data);
1489}
718e3744 1490
718e3744 1491
d62a17ae 1492static const struct message ospf_area_type_msg[] = {
1493 {OSPF_AREA_DEFAULT, "Default"},
1494 {OSPF_AREA_STUB, "Stub"},
1495 {OSPF_AREA_NSSA, "NSSA"},
1496 {0}};
718e3744 1497
d62a17ae 1498static void ospf_area_type_set(struct ospf_area *area, int type)
1499{
1500 struct listnode *node;
1501 struct ospf_interface *oi;
1502
1503 if (area->external_routing == type) {
1504 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
1505 zlog_debug("Area[%pI4]: Types are the same, ignored.",
1506 &area->area_id);
d62a17ae 1507 return;
1508 }
718e3744 1509
d62a17ae 1510 area->external_routing = type;
1511
1512 if (IS_DEBUG_OSPF_EVENT)
96b663a3
MS
1513 zlog_debug("Area[%pI4]: Configured as %s",
1514 &area->area_id,
d62a17ae 1515 lookup_msg(ospf_area_type_msg, type, NULL));
1516
1517 switch (area->external_routing) {
1518 case OSPF_AREA_DEFAULT:
1519 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1520 if (oi->nbr_self != NULL) {
1521 UNSET_FLAG(oi->nbr_self->options,
1522 OSPF_OPTION_NP);
1523 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
1524 }
1525 break;
1526 case OSPF_AREA_STUB:
1527 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1528 if (oi->nbr_self != NULL) {
1529 if (IS_DEBUG_OSPF_EVENT)
1530 zlog_debug(
1531 "setting options on %s accordingly",
1532 IF_NAME(oi));
1533 UNSET_FLAG(oi->nbr_self->options,
1534 OSPF_OPTION_NP);
1535 UNSET_FLAG(oi->nbr_self->options,
1536 OSPF_OPTION_E);
1537 if (IS_DEBUG_OSPF_EVENT)
1538 zlog_debug("options set on %s: %x",
1539 IF_NAME(oi), OPTIONS(oi));
1540 }
1541 break;
1542 case OSPF_AREA_NSSA:
1543 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1544 if (oi->nbr_self != NULL) {
1545 zlog_debug(
1546 "setting nssa options on %s accordingly",
1547 IF_NAME(oi));
1548 UNSET_FLAG(oi->nbr_self->options,
1549 OSPF_OPTION_E);
1550 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP);
1551 zlog_debug("options set on %s: %x", IF_NAME(oi),
1552 OPTIONS(oi));
1553 }
1554 break;
1555 default:
1556 break;
1557 }
1558
1559 ospf_router_lsa_update_area(area);
1560 ospf_schedule_abr_task(area->ospf);
718e3744 1561}
1562
d62a17ae 1563int ospf_area_shortcut_set(struct ospf *ospf, struct ospf_area *area, int mode)
718e3744 1564{
d62a17ae 1565 if (area->shortcut_configured == mode)
1566 return 0;
718e3744 1567
d62a17ae 1568 area->shortcut_configured = mode;
1569 ospf_router_lsa_update_area(area);
1570 ospf_schedule_abr_task(ospf);
718e3744 1571
d62a17ae 1572 ospf_area_check_free(ospf, area->area_id);
718e3744 1573
d62a17ae 1574 return 1;
718e3744 1575}
1576
d62a17ae 1577int ospf_area_shortcut_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1578{
d62a17ae 1579 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1580 ospf_router_lsa_update_area(area);
1581 ospf_area_check_free(ospf, area->area_id);
1582 ospf_schedule_abr_task(ospf);
718e3744 1583
d62a17ae 1584 return 1;
718e3744 1585}
1586
d62a17ae 1587static int ospf_area_vlink_count(struct ospf *ospf, struct ospf_area *area)
718e3744 1588{
d62a17ae 1589 struct ospf_vl_data *vl;
1590 struct listnode *node;
1591 int count = 0;
718e3744 1592
d62a17ae 1593 for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl))
1594 if (IPV4_ADDR_SAME(&vl->vl_area_id, &area->area_id))
1595 count++;
718e3744 1596
d62a17ae 1597 return count;
718e3744 1598}
1599
d62a17ae 1600int ospf_area_display_format_set(struct ospf *ospf, struct ospf_area *area,
1601 int df)
86573dcb 1602{
d62a17ae 1603 area->area_id_fmt = df;
86573dcb 1604
d62a17ae 1605 return 1;
86573dcb
QY
1606}
1607
d62a17ae 1608int ospf_area_stub_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1609{
d62a17ae 1610 struct ospf_area *area;
718e3744 1611
d62a17ae 1612 area = ospf_area_get(ospf, area_id);
1613 if (ospf_area_vlink_count(ospf, area))
1614 return 0;
718e3744 1615
d62a17ae 1616 if (area->external_routing != OSPF_AREA_STUB)
1617 ospf_area_type_set(area, OSPF_AREA_STUB);
718e3744 1618
d62a17ae 1619 return 1;
718e3744 1620}
1621
d62a17ae 1622int ospf_area_stub_unset(struct ospf *ospf, struct in_addr area_id)
718e3744 1623{
d62a17ae 1624 struct ospf_area *area;
718e3744 1625
d62a17ae 1626 area = ospf_area_lookup_by_area_id(ospf, area_id);
1627 if (area == NULL)
1628 return 1;
718e3744 1629
d62a17ae 1630 if (area->external_routing == OSPF_AREA_STUB)
1631 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
718e3744 1632
d62a17ae 1633 ospf_area_check_free(ospf, area_id);
718e3744 1634
d62a17ae 1635 return 1;
718e3744 1636}
1637
d62a17ae 1638int ospf_area_no_summary_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1639{
d62a17ae 1640 struct ospf_area *area;
718e3744 1641
d62a17ae 1642 area = ospf_area_get(ospf, area_id);
1643 area->no_summary = 1;
718e3744 1644
d62a17ae 1645 return 1;
718e3744 1646}
1647
d62a17ae 1648int ospf_area_no_summary_unset(struct ospf *ospf, struct in_addr area_id)
718e3744 1649{
d62a17ae 1650 struct ospf_area *area;
718e3744 1651
d62a17ae 1652 area = ospf_area_lookup_by_area_id(ospf, area_id);
1653 if (area == NULL)
1654 return 0;
718e3744 1655
d62a17ae 1656 area->no_summary = 0;
1657 ospf_area_check_free(ospf, area_id);
718e3744 1658
d62a17ae 1659 return 1;
718e3744 1660}
1661
7ef56a73 1662int ospf_area_nssa_no_summary_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1663{
d62a17ae 1664 struct ospf_area *area;
718e3744 1665
d62a17ae 1666 area = ospf_area_get(ospf, area_id);
1667 if (ospf_area_vlink_count(ospf, area))
1668 return 0;
718e3744 1669
d62a17ae 1670 if (area->external_routing != OSPF_AREA_NSSA) {
1671 ospf_area_type_set(area, OSPF_AREA_NSSA);
1672 ospf->anyNSSA++;
7ef56a73 1673 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
d62a17ae 1674 }
718e3744 1675
7ef56a73 1676 ospf_area_no_summary_set(ospf, area_id);
084c7844 1677
d62a17ae 1678 return 1;
718e3744 1679}
1680
7ef56a73
CS
1681int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id)
1682{
1683 struct ospf_area *area;
1684
1685 area = ospf_area_get(ospf, area_id);
1686 if (ospf_area_vlink_count(ospf, area))
1687 return 0;
1688
1689 if (area->external_routing != OSPF_AREA_NSSA) {
1690 ospf_area_type_set(area, OSPF_AREA_NSSA);
1691 ospf->anyNSSA++;
1692
1693 /* set NSSA area defaults */
1694 area->no_summary = 0;
c317eddb 1695 area->suppress_fa = 0;
7ef56a73
CS
1696 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1697 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
1698 area->NSSATranslatorStabilityInterval =
1699 OSPF_NSSA_TRANS_STABLE_DEFAULT;
1700 }
1701 return 1;
1702}
1703
1704int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
718e3744 1705{
d62a17ae 1706 struct ospf_area *area;
718e3744 1707
d62a17ae 1708 area = ospf_area_lookup_by_area_id(ospf, area_id);
1709 if (area == NULL)
1710 return 0;
718e3744 1711
7ef56a73
CS
1712 /* argc < 5 -> 'no area x nssa' */
1713 if (argc < 5 && area->external_routing == OSPF_AREA_NSSA) {
d62a17ae 1714 ospf->anyNSSA--;
7ef56a73
CS
1715 /* set NSSA area defaults */
1716 area->no_summary = 0;
c317eddb 1717 area->suppress_fa = 0;
7ef56a73
CS
1718 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1719 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
1720 area->NSSATranslatorStabilityInterval =
1721 OSPF_NSSA_TRANS_STABLE_DEFAULT;
d62a17ae 1722 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
7ef56a73 1723 } else {
a987fe6b 1724 ospf_area_nssa_translator_role_set(ospf, area_id,
1725 OSPF_NSSA_ROLE_CANDIDATE);
d62a17ae 1726 }
718e3744 1727
d62a17ae 1728 ospf_area_check_free(ospf, area_id);
718e3744 1729
d62a17ae 1730 return 1;
718e3744 1731}
1732
c317eddb 1733int ospf_area_nssa_suppress_fa_set(struct ospf *ospf, struct in_addr area_id)
1734{
1735 struct ospf_area *area;
1736
1737 area = ospf_area_lookup_by_area_id(ospf, area_id);
1738 if (area == NULL)
1739 return 0;
1740
1741 area->suppress_fa = 1;
1742
1743 return 1;
1744}
1745
1746int ospf_area_nssa_suppress_fa_unset(struct ospf *ospf, struct in_addr area_id)
1747{
1748 struct ospf_area *area;
1749
1750 area = ospf_area_lookup_by_area_id(ospf, area_id);
1751 if (area == NULL)
1752 return 0;
1753
1754 area->suppress_fa = 0;
1755
1756 return 1;
1757}
1758
d62a17ae 1759int ospf_area_nssa_translator_role_set(struct ospf *ospf,
1760 struct in_addr area_id, int role)
718e3744 1761{
d62a17ae 1762 struct ospf_area *area;
718e3744 1763
d62a17ae 1764 area = ospf_area_lookup_by_area_id(ospf, area_id);
1765 if (area == NULL)
1766 return 0;
718e3744 1767
a987fe6b 1768 if (role != area->NSSATranslatorRole) {
1769 if ((area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)
1770 || (role == OSPF_NSSA_ROLE_ALWAYS)) {
1771 /* RFC 3101 3.1
1772 * if new role is OSPF_NSSA_ROLE_ALWAYS we need to set
1773 * Nt bit, if the role was OSPF_NSSA_ROLE_ALWAYS we need
1774 * to clear Nt bit
1775 */
1776 area->NSSATranslatorRole = role;
1777 ospf_router_lsa_update_area(area);
1778 } else
1779 area->NSSATranslatorRole = role;
1780 }
718e3744 1781
d62a17ae 1782 return 1;
718e3744 1783}
1784
d62a17ae 1785int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area,
1786 const char *list_name)
718e3744 1787{
d62a17ae 1788 struct access_list *list;
1789 list = access_list_lookup(AFI_IP, list_name);
718e3744 1790
d62a17ae 1791 EXPORT_LIST(area) = list;
718e3744 1792
d62a17ae 1793 if (EXPORT_NAME(area))
1794 free(EXPORT_NAME(area));
718e3744 1795
d62a17ae 1796 EXPORT_NAME(area) = strdup(list_name);
1797 ospf_schedule_abr_task(ospf);
718e3744 1798
d62a17ae 1799 return 1;
718e3744 1800}
1801
d62a17ae 1802int ospf_area_export_list_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1803{
1804
d62a17ae 1805 EXPORT_LIST(area) = 0;
718e3744 1806
d62a17ae 1807 if (EXPORT_NAME(area))
1808 free(EXPORT_NAME(area));
718e3744 1809
d62a17ae 1810 EXPORT_NAME(area) = NULL;
718e3744 1811
d62a17ae 1812 ospf_area_check_free(ospf, area->area_id);
718e3744 1813
d62a17ae 1814 ospf_schedule_abr_task(ospf);
1815
1816 return 1;
718e3744 1817}
1818
d62a17ae 1819int ospf_area_import_list_set(struct ospf *ospf, struct ospf_area *area,
1820 const char *name)
718e3744 1821{
d62a17ae 1822 struct access_list *list;
1823 list = access_list_lookup(AFI_IP, name);
718e3744 1824
d62a17ae 1825 IMPORT_LIST(area) = list;
718e3744 1826
d62a17ae 1827 if (IMPORT_NAME(area))
1828 free(IMPORT_NAME(area));
718e3744 1829
d62a17ae 1830 IMPORT_NAME(area) = strdup(name);
1831 ospf_schedule_abr_task(ospf);
718e3744 1832
d62a17ae 1833 return 1;
718e3744 1834}
1835
d62a17ae 1836int ospf_area_import_list_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1837{
d62a17ae 1838 IMPORT_LIST(area) = 0;
718e3744 1839
d62a17ae 1840 if (IMPORT_NAME(area))
1841 free(IMPORT_NAME(area));
718e3744 1842
d62a17ae 1843 IMPORT_NAME(area) = NULL;
1844 ospf_area_check_free(ospf, area->area_id);
718e3744 1845
d62a17ae 1846 ospf_schedule_abr_task(ospf);
718e3744 1847
d62a17ae 1848 return 1;
718e3744 1849}
1850
d62a17ae 1851int ospf_timers_refresh_set(struct ospf *ospf, int interval)
718e3744 1852{
d62a17ae 1853 int time_left;
718e3744 1854
d62a17ae 1855 if (ospf->lsa_refresh_interval == interval)
1856 return 1;
718e3744 1857
d62a17ae 1858 time_left = ospf->lsa_refresh_interval
1859 - (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1860
d62a17ae 1861 if (time_left > interval) {
cccd44f3 1862 THREAD_OFF(ospf->t_lsa_refresher);
d62a17ae 1863 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
1864 interval, &ospf->t_lsa_refresher);
1865 }
1866 ospf->lsa_refresh_interval = interval;
1867
1868 return 1;
718e3744 1869}
1870
d62a17ae 1871int ospf_timers_refresh_unset(struct ospf *ospf)
718e3744 1872{
d62a17ae 1873 int time_left;
718e3744 1874
d62a17ae 1875 time_left = ospf->lsa_refresh_interval
1876 - (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1877
d62a17ae 1878 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) {
cccd44f3 1879 THREAD_OFF(ospf->t_lsa_refresher);
d62a17ae 1880 ospf->t_lsa_refresher = NULL;
1881 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
1882 OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
1883 &ospf->t_lsa_refresher);
1884 }
718e3744 1885
d62a17ae 1886 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
718e3744 1887
d62a17ae 1888 return 1;
718e3744 1889}
1890
6b0655a2 1891
d62a17ae 1892static struct ospf_nbr_nbma *ospf_nbr_nbma_new(void)
718e3744 1893{
d62a17ae 1894 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1895
d62a17ae 1896 nbr_nbma = XCALLOC(MTYPE_OSPF_NEIGHBOR_STATIC,
1897 sizeof(struct ospf_nbr_nbma));
718e3744 1898
d62a17ae 1899 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1900 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
718e3744 1901
d62a17ae 1902 return nbr_nbma;
718e3744 1903}
1904
d62a17ae 1905static void ospf_nbr_nbma_free(struct ospf_nbr_nbma *nbr_nbma)
718e3744 1906{
d62a17ae 1907 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
718e3744 1908}
1909
d62a17ae 1910static void ospf_nbr_nbma_delete(struct ospf *ospf,
1911 struct ospf_nbr_nbma *nbr_nbma)
718e3744 1912{
d62a17ae 1913 struct route_node *rn;
1914 struct prefix_ipv4 p;
718e3744 1915
d62a17ae 1916 p.family = AF_INET;
1917 p.prefix = nbr_nbma->addr;
1918 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1919
d62a17ae 1920 rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
1921 if (rn) {
1922 ospf_nbr_nbma_free(rn->info);
1923 rn->info = NULL;
1924 route_unlock_node(rn);
1925 route_unlock_node(rn);
1926 }
718e3744 1927}
1928
d62a17ae 1929static void ospf_nbr_nbma_down(struct ospf_nbr_nbma *nbr_nbma)
718e3744 1930{
cccd44f3 1931 THREAD_OFF(nbr_nbma->t_poll);
718e3744 1932
d62a17ae 1933 if (nbr_nbma->nbr) {
1934 nbr_nbma->nbr->nbr_nbma = NULL;
1935 OSPF_NSM_EVENT_EXECUTE(nbr_nbma->nbr, NSM_KillNbr);
1936 }
718e3744 1937
d62a17ae 1938 if (nbr_nbma->oi)
1939 listnode_delete(nbr_nbma->oi->nbr_nbma, nbr_nbma);
718e3744 1940}
1941
d62a17ae 1942static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma,
1943 struct ospf_interface *oi)
718e3744 1944{
d62a17ae 1945 struct ospf_neighbor *nbr;
1946 struct route_node *rn;
1947 struct prefix p;
718e3744 1948
d62a17ae 1949 if (oi->type != OSPF_IFTYPE_NBMA)
1950 return;
718e3744 1951
d62a17ae 1952 if (nbr_nbma->nbr != NULL)
1953 return;
718e3744 1954
d62a17ae 1955 if (IPV4_ADDR_SAME(&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1956 return;
718e3744 1957
d62a17ae 1958 nbr_nbma->oi = oi;
1959 listnode_add(oi->nbr_nbma, nbr_nbma);
718e3744 1960
d62a17ae 1961 /* Get neighbor information from table. */
1962 p.family = AF_INET;
1963 p.prefixlen = IPV4_MAX_BITLEN;
1964 p.u.prefix4 = nbr_nbma->addr;
718e3744 1965
c4efd0f4 1966 rn = route_node_get(oi->nbrs, &p);
d62a17ae 1967 if (rn->info) {
1968 nbr = rn->info;
1969 nbr->nbr_nbma = nbr_nbma;
1970 nbr_nbma->nbr = nbr;
718e3744 1971
d62a17ae 1972 route_unlock_node(rn);
1973 } else {
1974 nbr = rn->info = ospf_nbr_new(oi);
1975 nbr->state = NSM_Down;
1976 nbr->src = nbr_nbma->addr;
1977 nbr->nbr_nbma = nbr_nbma;
1978 nbr->priority = nbr_nbma->priority;
1979 nbr->address = p;
718e3744 1980
d62a17ae 1981 nbr_nbma->nbr = nbr;
1982
659f4e40
RZ
1983 /* Configure BFD if interface has it. */
1984 ospf_neighbor_bfd_apply(nbr);
1985
d62a17ae 1986 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start);
1987 }
718e3744 1988}
1989
d62a17ae 1990void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi)
718e3744 1991{
d62a17ae 1992 struct ospf_nbr_nbma *nbr_nbma;
1993 struct route_node *rn;
1994 struct prefix_ipv4 p;
718e3744 1995
d62a17ae 1996 if (oi->type != OSPF_IFTYPE_NBMA)
1997 return;
718e3744 1998
d62a17ae 1999 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
2000 if ((nbr_nbma = rn->info))
2001 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL) {
2002 p.family = AF_INET;
2003 p.prefix = nbr_nbma->addr;
2004 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 2005
d62a17ae 2006 if (prefix_match(oi->address,
2007 (struct prefix *)&p))
2008 ospf_nbr_nbma_add(nbr_nbma, oi);
2009 }
718e3744 2010}
2011
d62a17ae 2012struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *ospf,
2013 struct in_addr nbr_addr)
718e3744 2014{
d62a17ae 2015 struct route_node *rn;
2016 struct prefix_ipv4 p;
718e3744 2017
d62a17ae 2018 p.family = AF_INET;
2019 p.prefix = nbr_addr;
2020 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 2021
d62a17ae 2022 rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
2023 if (rn) {
2024 route_unlock_node(rn);
2025 return rn->info;
2026 }
2027 return NULL;
718e3744 2028}
2029
d62a17ae 2030int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 2031{
d62a17ae 2032 struct ospf_nbr_nbma *nbr_nbma;
2033 struct ospf_interface *oi;
2034 struct prefix_ipv4 p;
2035 struct route_node *rn;
2036 struct listnode *node;
718e3744 2037
d62a17ae 2038 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2039 if (nbr_nbma)
2040 return 0;
718e3744 2041
d62a17ae 2042 nbr_nbma = ospf_nbr_nbma_new();
2043 nbr_nbma->addr = nbr_addr;
718e3744 2044
d62a17ae 2045 p.family = AF_INET;
2046 p.prefix = nbr_addr;
2047 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 2048
d62a17ae 2049 rn = route_node_get(ospf->nbr_nbma, (struct prefix *)&p);
2050 if (rn->info)
2051 route_unlock_node(rn);
2052 rn->info = nbr_nbma;
718e3744 2053
d62a17ae 2054 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
2055 if (oi->type == OSPF_IFTYPE_NBMA)
2056 if (prefix_match(oi->address, (struct prefix *)&p)) {
2057 ospf_nbr_nbma_add(nbr_nbma, oi);
2058 break;
2059 }
2060 }
718e3744 2061
d62a17ae 2062 return 1;
718e3744 2063}
2064
d62a17ae 2065int ospf_nbr_nbma_unset(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 2066{
d62a17ae 2067 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2068
d62a17ae 2069 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2070 if (nbr_nbma == NULL)
2071 return 0;
718e3744 2072
d62a17ae 2073 ospf_nbr_nbma_down(nbr_nbma);
2074 ospf_nbr_nbma_delete(ospf, nbr_nbma);
718e3744 2075
d62a17ae 2076 return 1;
718e3744 2077}
2078
d62a17ae 2079int ospf_nbr_nbma_priority_set(struct ospf *ospf, struct in_addr nbr_addr,
d7c0a89a 2080 uint8_t priority)
718e3744 2081{
d62a17ae 2082 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2083
d62a17ae 2084 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2085 if (nbr_nbma == NULL)
2086 return 0;
718e3744 2087
d62a17ae 2088 if (nbr_nbma->priority != priority)
2089 nbr_nbma->priority = priority;
718e3744 2090
d62a17ae 2091 return 1;
718e3744 2092}
2093
d62a17ae 2094int ospf_nbr_nbma_priority_unset(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 2095{
d62a17ae 2096 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2097
d62a17ae 2098 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2099 if (nbr_nbma == NULL)
2100 return 0;
718e3744 2101
d62a17ae 2102 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
2103 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
718e3744 2104
d62a17ae 2105 return 1;
718e3744 2106}
2107
d62a17ae 2108int ospf_nbr_nbma_poll_interval_set(struct ospf *ospf, struct in_addr nbr_addr,
2109 unsigned int interval)
718e3744 2110{
d62a17ae 2111 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2112
d62a17ae 2113 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
2114 if (nbr_nbma == NULL)
2115 return 0;
718e3744 2116
d62a17ae 2117 if (nbr_nbma->v_poll != interval) {
2118 nbr_nbma->v_poll = interval;
2119 if (nbr_nbma->oi && ospf_if_is_up(nbr_nbma->oi)) {
cccd44f3 2120 THREAD_OFF(nbr_nbma->t_poll);
d62a17ae 2121 OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer,
2122 nbr_nbma->v_poll);
2123 }
718e3744 2124 }
718e3744 2125
d62a17ae 2126 return 1;
718e3744 2127}
2128
d62a17ae 2129int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
718e3744 2130{
d62a17ae 2131 struct ospf_nbr_nbma *nbr_nbma;
718e3744 2132
d62a17ae 2133 nbr_nbma = ospf_nbr_nbma_lookup(ospf, addr);
2134 if (nbr_nbma == NULL)
2135 return 0;
718e3744 2136
d62a17ae 2137 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
2138 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
718e3744 2139
d62a17ae 2140 return 1;
718e3744 2141}
2142
d62a17ae 2143void ospf_master_init(struct thread_master *master)
718e3744 2144{
6006b807 2145 memset(&ospf_master, 0, sizeof(ospf_master));
020709f9 2146
d62a17ae 2147 om = &ospf_master;
2148 om->ospf = list_new();
2149 om->master = master;
020709f9 2150}
b5a8894d
CS
2151
2152/* Link OSPF instance to VRF. */
2153void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
2154{
2155 ospf->vrf_id = vrf->vrf_id;
2156 if (vrf->info != (void *)ospf)
2157 vrf->info = (void *)ospf;
2158}
2159
2160/* Unlink OSPF instance from VRF. */
2161void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
2162{
2163 if (vrf->info == (void *)ospf)
2164 vrf->info = NULL;
2165 ospf->vrf_id = VRF_UNKNOWN;
2166}
2167
2168/* This is hook function for vrf create called as part of vrf_init */
2169static int ospf_vrf_new(struct vrf *vrf)
2170{
2171 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2172 zlog_debug("%s: VRF Created: %s(%u)", __func__, vrf->name,
2173 vrf->vrf_id);
b5a8894d
CS
2174
2175 return 0;
2176}
2177
2178/* This is hook function for vrf delete call as part of vrf_init */
2179static int ospf_vrf_delete(struct vrf *vrf)
2180{
2181 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2182 zlog_debug("%s: VRF Deletion: %s(%u)", __func__, vrf->name,
2183 vrf->vrf_id);
b5a8894d
CS
2184
2185 return 0;
2186}
2187
de11c1bc 2188static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf, bool set)
3d9f7302
PZ
2189{
2190 int type;
2191 struct list *red_list;
2192
2193 for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
2194 red_list = ospf->redist[type];
2195 if (!red_list)
2196 continue;
2197 if (IS_DEBUG_OSPF_EVENT)
2198 zlog_debug(
2199 "%s: setting redist vrf %d bitmap for type %d",
2200 __func__, ospf->vrf_id, type);
de11c1bc
IR
2201 if (set)
2202 vrf_bitmap_set(zclient->redist[AFI_IP][type],
2203 ospf->vrf_id);
2204 else
2205 vrf_bitmap_unset(zclient->redist[AFI_IP][type],
2206 ospf->vrf_id);
3d9f7302 2207 }
b46538c4
IR
2208
2209 red_list = ospf->redist[DEFAULT_ROUTE];
2210 if (red_list) {
2211 if (set)
2212 vrf_bitmap_set(zclient->default_information[AFI_IP],
2213 ospf->vrf_id);
2214 else
2215 vrf_bitmap_unset(zclient->default_information[AFI_IP],
2216 ospf->vrf_id);
2217 }
3d9f7302
PZ
2218}
2219
b5a8894d
CS
2220/* Enable OSPF VRF instance */
2221static int ospf_vrf_enable(struct vrf *vrf)
2222{
2223 struct ospf *ospf = NULL;
7d206035 2224 vrf_id_t old_vrf_id;
3c0eb8fa 2225 int ret = 0;
b5a8894d
CS
2226
2227 if (IS_DEBUG_OSPF_EVENT)
5e81f5dd
DS
2228 zlog_debug("%s: VRF %s id %u enabled", __func__, vrf->name,
2229 vrf->vrf_id);
b5a8894d
CS
2230
2231 ospf = ospf_lookup_by_name(vrf->name);
2232 if (ospf) {
2233 old_vrf_id = ospf->vrf_id;
2234 /* We have instance configured, link to VRF and make it "up". */
2235 ospf_vrf_link(ospf, vrf);
2236 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
2237 zlog_debug(
2238 "%s: ospf linked to vrf %s vrf_id %u (old id %u)",
5e81f5dd 2239 __func__, vrf->name, ospf->vrf_id, old_vrf_id);
b5a8894d
CS
2240
2241 if (old_vrf_id != ospf->vrf_id) {
de11c1bc 2242 ospf_set_redist_vrf_bitmaps(ospf, true);
3d9f7302 2243
de11c1bc
IR
2244 /* start zebra redist to us for new vrf */
2245 ospf_zebra_vrf_register(ospf);
313d7993 2246
de11c1bc 2247 ret = ospf_sock_init(ospf);
3c0eb8fa
PG
2248 if (ret < 0 || ospf->fd <= 0)
2249 return 0;
996c9314
LB
2250 thread_add_read(master, ospf_read, ospf, ospf->fd,
2251 &ospf->t_read);
b5a8894d
CS
2252 ospf->oi_running = 1;
2253 ospf_router_id_update(ospf);
2254 }
2255 }
2256
2257 return 0;
2258}
2259
2260/* Disable OSPF VRF instance */
2261static int ospf_vrf_disable(struct vrf *vrf)
2262{
2263 struct ospf *ospf = NULL;
2264 vrf_id_t old_vrf_id = VRF_UNKNOWN;
2265
2266 if (vrf->vrf_id == VRF_DEFAULT)
2267 return 0;
2268
2269 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2270 zlog_debug("%s: VRF %s id %d disabled.", __func__, vrf->name,
2271 vrf->vrf_id);
b5a8894d
CS
2272
2273 ospf = ospf_lookup_by_name(vrf->name);
2274 if (ospf) {
2275 old_vrf_id = ospf->vrf_id;
2276
de11c1bc
IR
2277 ospf_zebra_vrf_deregister(ospf);
2278
2279 ospf_set_redist_vrf_bitmaps(ospf, false);
2280
b5a8894d
CS
2281 /* We have instance configured, unlink
2282 * from VRF and make it "down".
2283 */
2284 ospf_vrf_unlink(ospf, vrf);
2285 ospf->oi_running = 0;
2286 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2287 zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__,
2288 old_vrf_id);
bc1f09de 2289 THREAD_OFF(ospf->t_read);
3c0eb8fa
PG
2290 close(ospf->fd);
2291 ospf->fd = -1;
b5a8894d
CS
2292 }
2293
2294 /* Note: This is a callback, the VRF will be deleted by the caller. */
2295 return 0;
2296}
2297
2298void ospf_vrf_init(void)
2299{
996c9314 2300 vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
ac2cb9bf 2301 ospf_vrf_delete);
b5a8894d
CS
2302}
2303
2304void ospf_vrf_terminate(void)
2305{
2306 vrf_terminate();
2307}
2308
2309const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
2310{
2311 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
2312
2313 return vrf ? vrf->name : "NIL";
2314}
88b6b28e
DS
2315
2316const char *ospf_get_name(const struct ospf *ospf)
2317{
2318 if (ospf->name)
2319 return ospf->name;
2320 else
2321 return VRF_DEFAULT_NAME;
2322}