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