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