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