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