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