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