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