]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospfd.c
Merge pull request #9503 from opensourcerouting/ospf6d-redistribute-metrics
[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"
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
5bd78355
IR
294static void ospf_add(struct ospf *ospf)
295{
296 listnode_add(om->ospf, ospf);
297}
298
299static void ospf_delete(struct ospf *ospf)
300{
301 listnode_delete(om->ospf, ospf);
302}
303
7fd0729f 304struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
718e3744 305{
d62a17ae 306 int i;
b5a8894d 307 struct vrf *vrf = NULL;
718e3744 308
d62a17ae 309 struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
718e3744 310
d62a17ae 311 new->instance = instance;
312 new->router_id.s_addr = htonl(0);
313 new->router_id_static.s_addr = htonl(0);
14406e8e
DS
314 if (name) {
315 vrf = vrf_lookup_by_name(name);
316 if (vrf)
317 new->vrf_id = vrf->vrf_id;
318 else
319 new->vrf_id = VRF_UNKNOWN;
b5a8894d
CS
320 /* Freed in ospf_finish_final */
321 new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
b5a8894d 322 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
323 zlog_debug(
324 "%s: Create new ospf instance with vrf_name %s vrf_id %u",
15569c58 325 __func__, name, new->vrf_id);
b5a8894d
CS
326 } else {
327 new->vrf_id = VRF_DEFAULT;
328 vrf = vrf_lookup_by_id(VRF_DEFAULT);
b5a8894d 329 }
a2d7fdfe 330
331 if (vrf)
332 ospf_vrf_link(new, vrf);
333
b5a8894d
CS
334 ospf_zebra_vrf_register(new);
335
d62a17ae 336 new->abr_type = OSPF_ABR_DEFAULT;
337 new->oiflist = list_new();
338 new->vlinks = list_new();
339 new->areas = list_new();
340 new->areas->cmp = (int (*)(void *, void *))ospf_area_id_cmp;
341 new->networks = route_table_init();
342 new->nbr_nbma = route_table_init();
718e3744 343
d62a17ae 344 new->lsdb = ospf_lsdb_new();
718e3744 345
d62a17ae 346 new->default_originate = DEFAULT_ORIGINATE_NONE;
718e3744 347
d62a17ae 348 new->passive_interface_default = OSPF_IF_ACTIVE;
4ba4fc85 349
d62a17ae 350 new->new_external_route = route_table_init();
351 new->old_external_route = route_table_init();
352 new->external_lsas = route_table_init();
353
354 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
355 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
356 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
357
358 /* Distribute parameter init. */
359 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
360 new->dtag[i] = 0;
361 }
362 new->default_metric = -1;
363 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
364
365 /* LSA timers */
366 new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
367 new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
368
369 /* SPF timer value init. */
370 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
371 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
372 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
373 new->spf_hold_multiplier = 1;
374
375 /* MaxAge init. */
376 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
377 new->maxage_lsa = route_table_init();
378 new->t_maxage_walker = NULL;
5bd78355
IR
379 thread_add_timer(master, ospf_lsa_maxage_walker, new,
380 OSPF_LSA_MAXAGE_CHECK_INTERVAL, &new->t_maxage_walker);
d62a17ae 381
3d5b9855 382 /* Max paths initialization */
383 new->max_multipath = MULTIPATH_NUM;
384
d62a17ae 385 /* Distance table init. */
386 new->distance_table = route_table_init();
387
388 new->lsa_refresh_queue.index = 0;
389 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
390 new->t_lsa_refresher = NULL;
5bd78355
IR
391 thread_add_timer(master, ospf_lsa_refresh_walker, new,
392 new->lsa_refresh_interval, &new->t_lsa_refresher);
d62a17ae 393 new->lsa_refresher_started = monotime(NULL);
394
266469eb
DS
395 new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1);
396
d62a17ae 397 new->t_read = NULL;
d62a17ae 398 new->oi_write_q = list_new();
399 new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
400
a92706bb
JU
401 new->proactive_arp = OSPF_PROACTIVE_ARP_DEFAULT;
402
51f8588e 403 ospf_gr_helper_instance_init(new);
06bc3110 404
ad7222b7 405 ospf_asbr_external_aggregator_init(new);
406
5bd78355
IR
407 ospf_opaque_type11_lsa_init(new);
408
d62a17ae 409 QOBJ_REG(new, ospf);
ae19c240 410
3c0eb8fa 411 new->fd = -1;
7fd0729f
G
412
413 return new;
414}
415
416/* Allocate new ospf structure. */
417static struct ospf *ospf_new(unsigned short instance, const char *name)
418{
419 struct ospf *new;
420
421 new = ospf_new_alloc(instance, name);
5bd78355
IR
422 ospf_add(new);
423
424 if (new->vrf_id == VRF_UNKNOWN)
425 return new;
7fd0729f 426
3c0eb8fa 427 if ((ospf_sock_init(new)) < 0) {
5bd78355
IR
428 flog_err(EC_LIB_SOCKET,
429 "%s: ospf_sock_init is unable to open a socket",
430 __func__);
3c0eb8fa
PG
431 return new;
432 }
7fd0729f 433
3c0eb8fa
PG
434 thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
435
5bd78355
IR
436 new->oi_running = 1;
437 ospf_router_id_update(new);
438
10514170
RW
439 /*
440 * Read from non-volatile memory whether this instance is performing a
441 * graceful restart or not.
442 */
443 ospf_gr_nvm_read(new);
444
d62a17ae 445 return new;
718e3744 446}
447
d7c0a89a 448struct ospf *ospf_lookup_instance(unsigned short instance)
7c8ff89e 449{
d62a17ae 450 struct ospf *ospf;
451 struct listnode *node, *nnode;
7c8ff89e 452
d62a17ae 453 if (listcount(om->ospf) == 0)
454 return NULL;
7c8ff89e 455
d62a17ae 456 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
457 if ((ospf->instance == 0 && instance == 0)
458 || (ospf->instance && instance
459 && ospf->instance == instance))
460 return ospf;
7c8ff89e 461
d62a17ae 462 return NULL;
7c8ff89e
DS
463}
464
d62a17ae 465static int ospf_is_ready(struct ospf *ospf)
52c62ab8 466{
d62a17ae 467 /* OSPF must be on and Router-ID must be configured. */
975a328e 468 if (!ospf || ospf->router_id.s_addr == INADDR_ANY)
d62a17ae 469 return 0;
470
471 return 1;
52c62ab8
JAG
472}
473
d7c0a89a 474struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
b5a8894d
CS
475{
476 struct ospf *ospf = NULL;
477 struct listnode *node, *nnode;
478
6895b354
PG
479 if (name == NULL || strmatch(name, VRF_DEFAULT_NAME))
480 return ospf_lookup_by_vrf_id(VRF_DEFAULT);
481
b5a8894d 482 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
996c9314
LB
483 if ((ospf->instance == instance)
484 && ((ospf->name == NULL && name == NULL)
485 || (ospf->name && name
486 && strcmp(ospf->name, name) == 0)))
b5a8894d
CS
487 return ospf;
488 }
489 return NULL;
490}
491
409f98ab 492struct ospf *ospf_lookup(unsigned short instance, const char *name)
c3391da1
IR
493{
494 struct ospf *ospf;
495
409f98ab
IR
496 if (ospf_instance) {
497 ospf = ospf_lookup_instance(instance);
498 } else {
b5a8894d 499 ospf = ospf_lookup_by_inst_name(instance, name);
d62a17ae 500 }
7c8ff89e 501
d62a17ae 502 return ospf;
7c8ff89e
DS
503}
504
409f98ab 505struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
7c8ff89e 506{
d62a17ae 507 struct ospf *ospf;
7c8ff89e 508
409f98ab
IR
509 ospf = ospf_lookup(instance, name);
510
c572fbfe 511 *created = (ospf == NULL);
5bd78355 512 if (ospf == NULL)
409f98ab 513 ospf = ospf_new(instance, name);
68980084 514
d62a17ae 515 return ospf;
718e3744 516}
6b0655a2 517
b5a8894d
CS
518struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
519{
520 struct vrf *vrf = NULL;
521
522 vrf = vrf_lookup_by_id(vrf_id);
523 if (!vrf)
524 return NULL;
525 return (vrf->info) ? (struct ospf *)vrf->info : NULL;
b5a8894d
CS
526}
527
cbf32f74
IR
528uint32_t ospf_count_area_params(struct ospf *ospf)
529{
530 struct vrf *vrf;
531 struct interface *ifp;
532 uint32_t count = 0;
533
534 if (ospf->vrf_id != VRF_UNKNOWN) {
535 vrf = vrf_lookup_by_id(ospf->vrf_id);
536
537 FOR_ALL_INTERFACES (vrf, ifp) {
538 count += ospf_if_count_area_params(ifp);
539 }
540 }
541
542 return count;
543}
544
43b8d1d8
CS
545/* It should only be used when processing incoming info update from zebra.
546 * Other situations, it is not sufficient to lookup the ospf instance by
547 * vrf_name only without using the instance number.
548 */
549static struct ospf *ospf_lookup_by_name(const char *vrf_name)
b5a8894d
CS
550{
551 struct ospf *ospf = NULL;
552 struct listnode *node, *nnode;
553
554 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
43b8d1d8 555 if ((ospf->name == NULL && vrf_name == NULL)
996c9314
LB
556 || (ospf->name && vrf_name
557 && strcmp(ospf->name, vrf_name) == 0))
b5a8894d
CS
558 return ospf;
559 return NULL;
560}
561
c9c93d50 562/* Handle the second half of deferred shutdown. This is called either
563 * from the deferred-shutdown timer thread, or directly through
564 * ospf_deferred_shutdown_check.
88d6cf37 565 *
566 * Function is to cleanup G-R state, if required then call ospf_finish_final
567 * to complete shutdown of this ospf instance. Possibly exit if the
568 * whole process is being shutdown and this was the last OSPF instance.
569 */
d62a17ae 570static void ospf_deferred_shutdown_finish(struct ospf *ospf)
571{
572 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
573 OSPF_TIMER_OFF(ospf->t_deferred_shutdown);
574
575 ospf_finish_final(ospf);
576
577 /* *ospf is now invalid */
88d6cf37 578
d62a17ae 579 /* ospfd being shut-down? If so, was this the last ospf instance? */
580 if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)
581 && (listcount(om->ospf) == 0)) {
582 exit(0);
583 }
584
585 return;
88d6cf37 586}
587
588/* Timer thread for G-R */
d62a17ae 589static int ospf_deferred_shutdown_timer(struct thread *t)
88d6cf37 590{
d62a17ae 591 struct ospf *ospf = THREAD_ARG(t);
592
593 ospf_deferred_shutdown_finish(ospf);
594
595 return 0;
88d6cf37 596}
597
c9c93d50 598/* Check whether deferred-shutdown must be scheduled, otherwise call
88d6cf37 599 * down directly into second-half of instance shutdown.
600 */
d62a17ae 601static void ospf_deferred_shutdown_check(struct ospf *ospf)
602{
603 unsigned long timeout;
604 struct listnode *ln;
605 struct ospf_area *area;
606
607 /* deferred shutdown already running? */
608 if (ospf->t_deferred_shutdown)
609 return;
610
611 /* Should we try push out max-metric LSAs? */
612 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) {
613 for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
614 SET_FLAG(area->stub_router_state,
615 OSPF_AREA_ADMIN_STUB_ROUTED);
616
617 if (!CHECK_FLAG(area->stub_router_state,
618 OSPF_AREA_IS_STUB_ROUTED))
619 ospf_router_lsa_update_area(area);
620 }
621 timeout = ospf->stub_router_shutdown_time;
622 } else {
623 /* No timer needed */
624 ospf_deferred_shutdown_finish(ospf);
625 return;
626 }
627
628 OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
629 timeout);
630 return;
88d6cf37 631}
6b0655a2 632
88d6cf37 633/* Shut down the entire process */
d62a17ae 634void ospf_terminate(void)
635{
636 struct ospf *ospf;
637 struct listnode *node, *nnode;
638
639 /* shutdown already in progress */
640 if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
641 return;
642
643 SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN);
644
41b21bfa 645 /* Skip some steps if OSPF not actually running */
d62a17ae 646 if (listcount(om->ospf) == 0)
41b21bfa 647 goto done;
d62a17ae 648
d62a17ae 649 for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
650 ospf_finish(ospf);
651
51f8588e
RW
652 /* Cleanup GR */
653 ospf_gr_helper_stop();
654
ded42248 655 /* Cleanup route maps */
ded42248
CS
656 route_map_finish();
657
658 /* reverse prefix_list_init */
659 prefix_list_add_hook(NULL);
660 prefix_list_delete_hook(NULL);
661 prefix_list_reset();
662
663 /* Cleanup vrf info */
664 ospf_vrf_terminate();
665
d62a17ae 666 /* Deliberately go back up, hopefully to thread scheduler, as
667 * One or more ospf_finish()'s may have deferred shutdown to a timer
668 * thread
669 */
670 zclient_stop(zclient);
671 zclient_free(zclient);
8879bd22 672
41b21bfa 673done:
8879bd22 674 frr_fini();
d62a17ae 675}
676
677void ospf_finish(struct ospf *ospf)
678{
679 /* let deferred shutdown decide */
680 ospf_deferred_shutdown_check(ospf);
681
682 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
683 * deferred to expiry of G-S timer thread. Return back up, hopefully
684 * to thread scheduler.
685 */
686 return;
88d6cf37 687}
688
689/* Final cleanup of ospf instance */
d62a17ae 690static void ospf_finish_final(struct ospf *ospf)
718e3744 691{
1113a2fb 692 struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
d62a17ae 693 struct route_node *rn;
694 struct ospf_nbr_nbma *nbr_nbma;
695 struct ospf_lsa *lsa;
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
10514170
RW
709 if (!ospf->gr_info.prepare_in_progress)
710 ospf_flush_self_originated_lsas_now(ospf);
953cde65 711
d62a17ae 712 /* Unregister redistribution */
713 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
714 struct list *red_list;
718e3744 715
d62a17ae 716 red_list = ospf->redist[i];
717 if (!red_list)
718 continue;
718e3744 719
1d753551 720 for (ALL_LIST_ELEMENTS(red_list, node, nnode, red)) {
d62a17ae 721 ospf_redistribute_unset(ospf, i, red->instance);
1d753551
DS
722 ospf_redist_del(ospf, i, red->instance);
723 }
d62a17ae 724 }
ca187fd3
IR
725 red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
726 if (red) {
727 ospf_routemap_unset(red);
728 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
729 ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE, 0, 0);
730 }
718e3744 731
d62a17ae 732 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
733 ospf_remove_vls_through_area(ospf, area);
718e3744 734
d62a17ae 735 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
736 ospf_vl_delete(ospf, vl_data);
718e3744 737
6a154c88 738 list_delete(&ospf->vlinks);
718e3744 739
132a782e 740 /* shutdown LDP-Sync */
741 if (ospf->vrf_id == VRF_DEFAULT)
742 ospf_ldp_sync_gbl_exit(ospf, true);
743
d62a17ae 744 /* Reset interface. */
745 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
746 ospf_if_free(oi);
6a154c88 747 list_delete(&ospf->oiflist);
c32eba04 748 ospf->oi_running = 0;
718e3744 749
b5a8894d
CS
750 /* De-Register VRF */
751 ospf_zebra_vrf_deregister(ospf);
752
d62a17ae 753 /* Clear static neighbors */
754 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
755 if ((nbr_nbma = rn->info)) {
756 OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll);
718e3744 757
d62a17ae 758 if (nbr_nbma->nbr) {
759 nbr_nbma->nbr->nbr_nbma = NULL;
760 nbr_nbma->nbr = NULL;
761 }
762
763 if (nbr_nbma->oi) {
764 listnode_delete(nbr_nbma->oi->nbr_nbma,
765 nbr_nbma);
766 nbr_nbma->oi = NULL;
767 }
768
769 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
770 }
771
772 route_table_finish(ospf->nbr_nbma);
773
774 /* Clear networks and Areas. */
775 for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
776 struct ospf_network *network;
777
778 if ((network = rn->info) != NULL) {
779 ospf_network_free(ospf, network);
780 rn->info = NULL;
781 route_unlock_node(rn);
782 }
91e6a0e5 783 }
7f586094 784 route_table_finish(ospf->networks);
718e3744 785
d62a17ae 786 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
787 listnode_delete(ospf->areas, area);
788 ospf_area_free(area);
789 }
718e3744 790
d62a17ae 791 /* Cancel all timers. */
c32eba04
CS
792 OSPF_TIMER_OFF(ospf->t_read);
793 OSPF_TIMER_OFF(ospf->t_write);
d62a17ae 794 OSPF_TIMER_OFF(ospf->t_spf_calc);
795 OSPF_TIMER_OFF(ospf->t_ase_calc);
796 OSPF_TIMER_OFF(ospf->t_maxage);
797 OSPF_TIMER_OFF(ospf->t_maxage_walker);
798 OSPF_TIMER_OFF(ospf->t_abr_task);
799 OSPF_TIMER_OFF(ospf->t_asbr_check);
1c1c342d 800 OSPF_TIMER_OFF(ospf->t_asbr_nssa_redist_update);
d62a17ae 801 OSPF_TIMER_OFF(ospf->t_distribute_update);
802 OSPF_TIMER_OFF(ospf->t_lsa_refresher);
d62a17ae 803 OSPF_TIMER_OFF(ospf->t_opaque_lsa_self);
45a43856 804 OSPF_TIMER_OFF(ospf->t_sr_update);
1febb13d 805 OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
ad7222b7 806 OSPF_TIMER_OFF(ospf->t_external_aggr);
10514170 807 OSPF_TIMER_OFF(ospf->gr_info.t_grace_period);
d62a17ae 808
996c9314 809 LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
044506e7 810 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
996c9314 811 LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
044506e7 812 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
d62a17ae 813
814 ospf_lsdb_delete_all(ospf->lsdb);
815 ospf_lsdb_free(ospf->lsdb);
816
817 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
d62a17ae 818 if ((lsa = rn->info) != NULL) {
819 ospf_lsa_unlock(&lsa);
820 rn->info = NULL;
69843e81 821 route_unlock_node(rn);
d62a17ae 822 }
d62a17ae 823 }
824 route_table_finish(ospf->maxage_lsa);
825
826 if (ospf->old_table)
827 ospf_route_table_free(ospf->old_table);
828 if (ospf->new_table) {
10514170
RW
829 if (!ospf->gr_info.prepare_in_progress)
830 ospf_route_delete(ospf, ospf->new_table);
d62a17ae 831 ospf_route_table_free(ospf->new_table);
832 }
833 if (ospf->old_rtrs)
834 ospf_rtrs_free(ospf->old_rtrs);
835 if (ospf->new_rtrs)
836 ospf_rtrs_free(ospf->new_rtrs);
837 if (ospf->new_external_route) {
10514170
RW
838 if (!ospf->gr_info.prepare_in_progress)
839 ospf_route_delete(ospf, ospf->new_external_route);
d62a17ae 840 ospf_route_table_free(ospf->new_external_route);
841 }
842 if (ospf->old_external_route) {
10514170
RW
843 if (!ospf->gr_info.prepare_in_progress)
844 ospf_route_delete(ospf, ospf->old_external_route);
d62a17ae 845 ospf_route_table_free(ospf->old_external_route);
846 }
847 if (ospf->external_lsas) {
848 ospf_ase_external_lsas_finish(ospf->external_lsas);
849 }
718e3744 850
d62a17ae 851 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
852 struct list *ext_list;
d62a17ae 853 struct ospf_external *ext;
854
de1ac5fd 855 ext_list = ospf->external[i];
d62a17ae 856 if (!ext_list)
857 continue;
858
76fdc7f4 859 for (ALL_LIST_ELEMENTS(ext_list, node, nnode, ext)) {
d62a17ae 860 if (ext->external_info)
861 for (rn = route_top(ext->external_info); rn;
862 rn = route_next(rn)) {
863 if (rn->info == NULL)
864 continue;
865
866 XFREE(MTYPE_OSPF_EXTERNAL_INFO,
867 rn->info);
868 rn->info = NULL;
869 route_unlock_node(rn);
870 }
1d753551
DS
871
872 ospf_external_del(ospf, i, ext->instance);
d62a17ae 873 }
874 }
718e3744 875
d62a17ae 876 ospf_distance_reset(ospf);
877 route_table_finish(ospf->distance_table);
7c8ff89e 878
ad7222b7 879 /* Release extrenal Aggregator table */
880 for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
881 struct ospf_external_aggr_rt *aggr;
882
883 aggr = rn->info;
884
885 if (aggr) {
886 ospf_external_aggregator_free(aggr);
887 rn->info = NULL;
888 route_unlock_node(rn);
889 }
890 }
891
892 route_table_finish(ospf->rt_aggr_tbl);
893
894
c32eba04
CS
895 list_delete(&ospf->areas);
896 list_delete(&ospf->oi_write_q);
897
06bc3110 898 /* Reset GR helper data structers */
51f8588e 899 ospf_gr_helper_instance_stop(ospf);
06bc3110 900
c32eba04
CS
901 close(ospf->fd);
902 stream_free(ospf->ibuf);
903 ospf->fd = -1;
3d5b9855 904 ospf->max_multipath = MULTIPATH_NUM;
d62a17ae 905 ospf_delete(ospf);
7c8ff89e 906
1113a2fb 907 if (vrf)
908 ospf_vrf_unlink(ospf, vrf);
b5a8894d 909
1113a2fb 910 if (ospf->name)
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 /*
1095 * if router_id is not configured, dont bring up
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(
96b663a3 1442 "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %pI4",
15569c58 1443 __func__, ifp->name, ifp->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{
d62a17ae 2122 memset(&ospf_master, 0, sizeof(struct 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) {
6895b354
PG
2210 if (ospf->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
2211 XFREE(MTYPE_OSPF_TOP, ospf->name);
2212 ospf->name = NULL;
2213 }
b5a8894d
CS
2214 old_vrf_id = ospf->vrf_id;
2215 /* We have instance configured, link to VRF and make it "up". */
2216 ospf_vrf_link(ospf, vrf);
2217 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
2218 zlog_debug(
2219 "%s: ospf linked to vrf %s vrf_id %u (old id %u)",
5e81f5dd 2220 __func__, vrf->name, ospf->vrf_id, old_vrf_id);
b5a8894d
CS
2221
2222 if (old_vrf_id != ospf->vrf_id) {
de11c1bc 2223 ospf_set_redist_vrf_bitmaps(ospf, true);
3d9f7302 2224
de11c1bc
IR
2225 /* start zebra redist to us for new vrf */
2226 ospf_zebra_vrf_register(ospf);
313d7993 2227
de11c1bc 2228 ret = ospf_sock_init(ospf);
3c0eb8fa
PG
2229 if (ret < 0 || ospf->fd <= 0)
2230 return 0;
996c9314
LB
2231 thread_add_read(master, ospf_read, ospf, ospf->fd,
2232 &ospf->t_read);
b5a8894d
CS
2233 ospf->oi_running = 1;
2234 ospf_router_id_update(ospf);
2235 }
2236 }
2237
2238 return 0;
2239}
2240
2241/* Disable OSPF VRF instance */
2242static int ospf_vrf_disable(struct vrf *vrf)
2243{
2244 struct ospf *ospf = NULL;
2245 vrf_id_t old_vrf_id = VRF_UNKNOWN;
2246
2247 if (vrf->vrf_id == VRF_DEFAULT)
2248 return 0;
2249
2250 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2251 zlog_debug("%s: VRF %s id %d disabled.", __func__, vrf->name,
2252 vrf->vrf_id);
b5a8894d
CS
2253
2254 ospf = ospf_lookup_by_name(vrf->name);
2255 if (ospf) {
2256 old_vrf_id = ospf->vrf_id;
2257
de11c1bc
IR
2258 ospf_zebra_vrf_deregister(ospf);
2259
2260 ospf_set_redist_vrf_bitmaps(ospf, false);
2261
b5a8894d
CS
2262 /* We have instance configured, unlink
2263 * from VRF and make it "down".
2264 */
2265 ospf_vrf_unlink(ospf, vrf);
2266 ospf->oi_running = 0;
2267 if (IS_DEBUG_OSPF_EVENT)
15569c58
DA
2268 zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__,
2269 old_vrf_id);
b3d6bc6e 2270 thread_cancel(&ospf->t_read);
3c0eb8fa
PG
2271 close(ospf->fd);
2272 ospf->fd = -1;
b5a8894d
CS
2273 }
2274
2275 /* Note: This is a callback, the VRF will be deleted by the caller. */
2276 return 0;
2277}
2278
2279void ospf_vrf_init(void)
2280{
996c9314 2281 vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
b5c056fa 2282 ospf_vrf_delete, ospf_vrf_enable);
b5a8894d
CS
2283}
2284
2285void ospf_vrf_terminate(void)
2286{
2287 vrf_terminate();
2288}
2289
2290const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
2291{
2292 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
2293
2294 return vrf ? vrf->name : "NIL";
2295}
88b6b28e
DS
2296
2297const char *ospf_get_name(const struct ospf *ospf)
2298{
2299 if (ospf->name)
2300 return ospf->name;
2301 else
2302 return VRF_DEFAULT_NAME;
2303}