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