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