]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospfd.c
Merge pull request #2777 from qlyoung/fix-checkpatch-sh-greps
[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 563 /* Cleanup route maps */
ded42248
CS
564 route_map_finish();
565
566 /* reverse prefix_list_init */
567 prefix_list_add_hook(NULL);
568 prefix_list_delete_hook(NULL);
569 prefix_list_reset();
570
571 /* Cleanup vrf info */
572 ospf_vrf_terminate();
573
d62a17ae 574 /* Deliberately go back up, hopefully to thread scheduler, as
575 * One or more ospf_finish()'s may have deferred shutdown to a timer
576 * thread
577 */
578 zclient_stop(zclient);
579 zclient_free(zclient);
8879bd22
RW
580
581 frr_fini();
d62a17ae 582}
583
584void ospf_finish(struct ospf *ospf)
585{
586 /* let deferred shutdown decide */
587 ospf_deferred_shutdown_check(ospf);
588
589 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
590 * deferred to expiry of G-S timer thread. Return back up, hopefully
591 * to thread scheduler.
592 */
593 return;
88d6cf37 594}
595
596/* Final cleanup of ospf instance */
d62a17ae 597static void ospf_finish_final(struct ospf *ospf)
718e3744 598{
f4e14fdb 599 struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
d62a17ae 600 struct route_node *rn;
601 struct ospf_nbr_nbma *nbr_nbma;
602 struct ospf_lsa *lsa;
603 struct interface *ifp;
604 struct ospf_interface *oi;
605 struct ospf_area *area;
606 struct ospf_vl_data *vl_data;
607 struct listnode *node, *nnode;
608 int i;
d7c0a89a 609 unsigned short instance = 0;
7c8ff89e 610
d62a17ae 611 QOBJ_UNREG(ospf);
7c8ff89e 612
d62a17ae 613 ospf_opaque_type11_lsa_term(ospf);
953cde65 614
bcf4475e
OD
615 ospf_opaque_finish();
616
046460a1 617 ospf_flush_self_originated_lsas_now(ospf);
953cde65 618
d62a17ae 619 /* Unregister redistribution */
620 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
621 struct list *red_list;
622 struct ospf_redist *red;
718e3744 623
d62a17ae 624 red_list = ospf->redist[i];
625 if (!red_list)
626 continue;
718e3744 627
d62a17ae 628 for (ALL_LIST_ELEMENTS(red_list, node, nnode, red))
629 ospf_redistribute_unset(ospf, i, red->instance);
630 }
631 ospf_redistribute_default_unset(ospf);
718e3744 632
d62a17ae 633 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
634 ospf_remove_vls_through_area(ospf, area);
718e3744 635
d62a17ae 636 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
637 ospf_vl_delete(ospf, vl_data);
718e3744 638
affe9e99 639 list_delete_and_null(&ospf->vlinks);
718e3744 640
d62a17ae 641 /* Remove any ospf interface config params */
451fda4f 642 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 643 struct ospf_if_params *params;
718e3744 644
d62a17ae 645 params = IF_DEF_PARAMS(ifp);
646 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
647 UNSET_IF_PARAM(params, if_area);
718e3744 648 }
718e3744 649
d62a17ae 650 /* Reset interface. */
651 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
652 ospf_if_free(oi);
84519c81 653 list_delete_and_null(&ospf->oiflist);
718e3744 654
b5a8894d
CS
655 /* De-Register VRF */
656 ospf_zebra_vrf_deregister(ospf);
657
d62a17ae 658 /* Clear static neighbors */
659 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
660 if ((nbr_nbma = rn->info)) {
661 OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll);
718e3744 662
d62a17ae 663 if (nbr_nbma->nbr) {
664 nbr_nbma->nbr->nbr_nbma = NULL;
665 nbr_nbma->nbr = NULL;
666 }
667
668 if (nbr_nbma->oi) {
669 listnode_delete(nbr_nbma->oi->nbr_nbma,
670 nbr_nbma);
671 nbr_nbma->oi = NULL;
672 }
673
674 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
675 }
676
677 route_table_finish(ospf->nbr_nbma);
678
679 /* Clear networks and Areas. */
680 for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
681 struct ospf_network *network;
682
683 if ((network = rn->info) != NULL) {
684 ospf_network_free(ospf, network);
685 rn->info = NULL;
686 route_unlock_node(rn);
687 }
91e6a0e5 688 }
7f586094 689 route_table_finish(ospf->networks);
718e3744 690
d62a17ae 691 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
692 listnode_delete(ospf->areas, area);
693 ospf_area_free(area);
694 }
718e3744 695
d62a17ae 696 /* Cancel all timers. */
697 OSPF_TIMER_OFF(ospf->t_external_lsa);
698 OSPF_TIMER_OFF(ospf->t_spf_calc);
699 OSPF_TIMER_OFF(ospf->t_ase_calc);
700 OSPF_TIMER_OFF(ospf->t_maxage);
701 OSPF_TIMER_OFF(ospf->t_maxage_walker);
702 OSPF_TIMER_OFF(ospf->t_abr_task);
703 OSPF_TIMER_OFF(ospf->t_asbr_check);
704 OSPF_TIMER_OFF(ospf->t_distribute_update);
705 OSPF_TIMER_OFF(ospf->t_lsa_refresher);
706 OSPF_TIMER_OFF(ospf->t_read);
707 OSPF_TIMER_OFF(ospf->t_write);
708 OSPF_TIMER_OFF(ospf->t_opaque_lsa_self);
45a43856 709 OSPF_TIMER_OFF(ospf->t_sr_update);
d62a17ae 710
711 close(ospf->fd);
712 stream_free(ospf->ibuf);
713
996c9314 714 LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
044506e7 715 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
996c9314 716 LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
044506e7 717 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
d62a17ae 718
719 ospf_lsdb_delete_all(ospf->lsdb);
720 ospf_lsdb_free(ospf->lsdb);
721
722 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
723 struct ospf_lsa *lsa;
724
725 if ((lsa = rn->info) != NULL) {
726 ospf_lsa_unlock(&lsa);
727 rn->info = NULL;
728 }
729 route_unlock_node(rn);
730 }
731 route_table_finish(ospf->maxage_lsa);
732
733 if (ospf->old_table)
734 ospf_route_table_free(ospf->old_table);
735 if (ospf->new_table) {
b5a8894d 736 ospf_route_delete(ospf, ospf->new_table);
d62a17ae 737 ospf_route_table_free(ospf->new_table);
738 }
739 if (ospf->old_rtrs)
740 ospf_rtrs_free(ospf->old_rtrs);
741 if (ospf->new_rtrs)
742 ospf_rtrs_free(ospf->new_rtrs);
743 if (ospf->new_external_route) {
b5a8894d 744 ospf_route_delete(ospf, ospf->new_external_route);
d62a17ae 745 ospf_route_table_free(ospf->new_external_route);
746 }
747 if (ospf->old_external_route) {
b5a8894d 748 ospf_route_delete(ospf, ospf->old_external_route);
d62a17ae 749 ospf_route_table_free(ospf->old_external_route);
750 }
751 if (ospf->external_lsas) {
752 ospf_ase_external_lsas_finish(ospf->external_lsas);
753 }
718e3744 754
affe9e99
DS
755 list_delete_and_null(&ospf->areas);
756 list_delete_and_null(&ospf->oi_write_q);
d62a17ae 757
758 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
759 struct list *ext_list;
760 struct listnode *node;
761 struct ospf_external *ext;
762
de1ac5fd 763 ext_list = ospf->external[i];
d62a17ae 764 if (!ext_list)
765 continue;
766
767 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
768 if (ext->external_info)
769 for (rn = route_top(ext->external_info); rn;
770 rn = route_next(rn)) {
771 if (rn->info == NULL)
772 continue;
773
774 XFREE(MTYPE_OSPF_EXTERNAL_INFO,
775 rn->info);
776 rn->info = NULL;
777 route_unlock_node(rn);
778 }
779 }
780 }
718e3744 781
d62a17ae 782 ospf_distance_reset(ospf);
783 route_table_finish(ospf->distance_table);
7c8ff89e 784
d62a17ae 785 if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
786 instance = ospf->instance;
718e3744 787
d62a17ae 788 ospf_delete(ospf);
7c8ff89e 789
b5a8894d
CS
790 if (ospf->name) {
791 vrf = vrf_lookup_by_name(ospf->name);
792 if (vrf)
793 ospf_vrf_unlink(ospf, vrf);
794 XFREE(MTYPE_OSPF_TOP, ospf->name);
795 } else {
796 vrf = vrf_lookup_by_id(VRF_DEFAULT);
797 if (vrf)
798 ospf_vrf_unlink(ospf, vrf);
799 }
800
d62a17ae 801 XFREE(MTYPE_OSPF_TOP, ospf);
7c8ff89e 802
d62a17ae 803 if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
804 ospf_get_instance(instance);
718e3744 805}
806
6b0655a2 807
718e3744 808/* allocate new OSPF Area object */
d62a17ae 809static struct ospf_area *ospf_area_new(struct ospf *ospf,
810 struct in_addr area_id)
718e3744 811{
d62a17ae 812 struct ospf_area *new;
718e3744 813
d62a17ae 814 /* Allocate new config_network. */
815 new = XCALLOC(MTYPE_OSPF_AREA, sizeof(struct ospf_area));
718e3744 816
d62a17ae 817 new->ospf = ospf;
718e3744 818
d62a17ae 819 new->area_id = area_id;
820 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
718e3744 821
d62a17ae 822 new->external_routing = OSPF_AREA_DEFAULT;
823 new->default_cost = 1;
824 new->auth_type = OSPF_AUTH_NULL;
718e3744 825
d62a17ae 826 /* New LSDB init. */
827 new->lsdb = ospf_lsdb_new();
718e3744 828
d62a17ae 829 /* Self-originated LSAs initialize. */
830 new->router_lsa_self = NULL;
718e3744 831
d62a17ae 832 ospf_opaque_type10_lsa_init(new);
718e3744 833
d62a17ae 834 new->oiflist = list_new();
835 new->ranges = route_table_init();
718e3744 836
d62a17ae 837 if (area_id.s_addr == OSPF_AREA_BACKBONE)
838 ospf->backbone = new;
839
840 return new;
718e3744 841}
842
d62a17ae 843static void ospf_area_free(struct ospf_area *area)
718e3744 844{
d62a17ae 845 struct route_node *rn;
846 struct ospf_lsa *lsa;
847
7f7f77a0
DS
848 ospf_opaque_type10_lsa_term(area);
849
d62a17ae 850 /* Free LSDBs. */
996c9314 851 LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
044506e7 852 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 853 LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
044506e7 854 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 855 LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
044506e7 856 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 857 LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
044506e7 858 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
68980084 859
996c9314 860 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
044506e7 861 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 862 LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
044506e7 863 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
996c9314 864 LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
044506e7 865 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
718e3744 866
d62a17ae 867 ospf_lsdb_delete_all(area->lsdb);
868 ospf_lsdb_free(area->lsdb);
718e3744 869
d62a17ae 870 ospf_lsa_unlock(&area->router_lsa_self);
718e3744 871
d62a17ae 872 route_table_finish(area->ranges);
affe9e99 873 list_delete_and_null(&area->oiflist);
718e3744 874
d62a17ae 875 if (EXPORT_NAME(area))
876 free(EXPORT_NAME(area));
718e3744 877
d62a17ae 878 if (IMPORT_NAME(area))
879 free(IMPORT_NAME(area));
718e3744 880
d62a17ae 881 /* Cancel timer. */
882 OSPF_TIMER_OFF(area->t_stub_router);
883 OSPF_TIMER_OFF(area->t_opaque_lsa_self);
718e3744 884
d62a17ae 885 if (OSPF_IS_AREA_BACKBONE(area))
886 area->ospf->backbone = NULL;
887
888 XFREE(MTYPE_OSPF_AREA, area);
718e3744 889}
890
d62a17ae 891void ospf_area_check_free(struct ospf *ospf, struct in_addr area_id)
718e3744 892{
d62a17ae 893 struct ospf_area *area;
718e3744 894
d62a17ae 895 area = ospf_area_lookup_by_area_id(ospf, area_id);
896 if (area && listcount(area->oiflist) == 0 && area->ranges->top == NULL
897 && area->shortcut_configured == OSPF_SHORTCUT_DEFAULT
898 && area->external_routing == OSPF_AREA_DEFAULT
899 && area->no_summary == 0 && area->default_cost == 1
900 && EXPORT_NAME(area) == NULL && IMPORT_NAME(area) == NULL
901 && area->auth_type == OSPF_AUTH_NULL) {
902 listnode_delete(ospf->areas, area);
903 ospf_area_free(area);
904 }
718e3744 905}
906
d62a17ae 907struct ospf_area *ospf_area_get(struct ospf *ospf, struct in_addr area_id)
718e3744 908{
d62a17ae 909 struct ospf_area *area;
910
911 area = ospf_area_lookup_by_area_id(ospf, area_id);
912 if (!area) {
913 area = ospf_area_new(ospf, area_id);
914 listnode_add_sort(ospf->areas, area);
915 ospf_check_abr_status(ospf);
916 if (ospf->stub_router_admin_set
917 == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) {
918 SET_FLAG(area->stub_router_state,
919 OSPF_AREA_ADMIN_STUB_ROUTED);
920 }
921 }
718e3744 922
d62a17ae 923 return area;
718e3744 924}
925
d62a17ae 926struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *ospf,
927 struct in_addr area_id)
718e3744 928{
d62a17ae 929 struct ospf_area *area;
930 struct listnode *node;
718e3744 931
d62a17ae 932 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
933 if (IPV4_ADDR_SAME(&area->area_id, &area_id))
934 return area;
718e3744 935
d62a17ae 936 return NULL;
718e3744 937}
938
d62a17ae 939void ospf_area_add_if(struct ospf_area *area, struct ospf_interface *oi)
718e3744 940{
d62a17ae 941 listnode_add(area->oiflist, oi);
718e3744 942}
943
d62a17ae 944void ospf_area_del_if(struct ospf_area *area, struct ospf_interface *oi)
718e3744 945{
d62a17ae 946 listnode_delete(area->oiflist, oi);
718e3744 947}
948
52c62ab8 949
d62a17ae 950static void add_ospf_interface(struct connected *co, struct ospf_area *area)
953cde65 951{
d62a17ae 952 struct ospf_interface *oi;
953cde65 953
d62a17ae 954 oi = ospf_if_new(area->ospf, co->ifp, co->address);
955 oi->connected = co;
953cde65 956
d62a17ae 957 oi->area = area;
953cde65 958
d62a17ae 959 oi->params = ospf_lookup_if_params(co->ifp, oi->address->u.prefix4);
960 oi->output_cost = ospf_if_get_output_cost(oi);
953cde65 961
d62a17ae 962 /* Relate ospf interface to ospf instance. */
963 oi->ospf = area->ospf;
953cde65 964
d62a17ae 965 /* update network type as interface flag */
966 /* If network type is specified previously,
967 skip network type setting. */
968 oi->type = IF_DEF_PARAMS(co->ifp)->type;
953cde65 969
d62a17ae 970 /* Add pseudo neighbor. */
971 ospf_nbr_self_reset(oi, oi->ospf->router_id);
953cde65 972
d62a17ae 973 ospf_area_add_if(oi->area, oi);
52c62ab8 974
d62a17ae 975 /*
976 * if router_id is not configured, dont bring up
977 * interfaces.
978 * ospf_router_id_update() will call ospf_if_update
979 * whenever r-id is configured instead.
980 */
981 if ((area->ospf->router_id.s_addr != 0) && if_is_operative(co->ifp))
982 ospf_if_up(oi);
953cde65
JT
983}
984
985static void update_redistributed(struct ospf *ospf, int add_to_ospf)
986{
d62a17ae 987 struct route_node *rn;
988 struct external_info *ei;
989 struct ospf_external *ext;
990
de1ac5fd
CS
991 if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) {
992 ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0);
993 if ((ext) && EXTERNAL_INFO(ext)) {
d62a17ae 994 for (rn = route_top(EXTERNAL_INFO(ext)); rn;
995 rn = route_next(rn)) {
de1ac5fd
CS
996 ei = rn->info;
997 if (ei == NULL)
998 continue;
999
1000 if (add_to_ospf) {
996c9314
LB
1001 if (ospf_external_info_find_lsa(ospf,
1002 &ei->p))
de1ac5fd
CS
1003 if (!ospf_distribute_check_connected(
1004 ospf, ei))
1005 ospf_external_lsa_flush(
996c9314 1006 ospf, ei->type,
de1ac5fd
CS
1007 &ei->p,
1008 ei->ifindex /*, ei->nexthop */);
1009 } else {
1010 if (!ospf_external_info_find_lsa(
1011 ospf, &ei->p))
1012 if (ospf_distribute_check_connected(
1013 ospf, ei))
1014 ospf_external_lsa_originate(
996c9314 1015 ospf, ei);
d62a17ae 1016 }
1017 }
1018 }
de1ac5fd 1019 }
953cde65
JT
1020}
1021
718e3744 1022/* Config network statement related functions. */
d62a17ae 1023static struct ospf_network *ospf_network_new(struct in_addr area_id)
718e3744 1024{
d62a17ae 1025 struct ospf_network *new;
1026 new = XCALLOC(MTYPE_OSPF_NETWORK, sizeof(struct ospf_network));
718e3744 1027
d62a17ae 1028 new->area_id = area_id;
1029 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
1030
1031 return new;
718e3744 1032}
1033
d62a17ae 1034static void ospf_network_free(struct ospf *ospf, struct ospf_network *network)
718e3744 1035{
d62a17ae 1036 ospf_area_check_free(ospf, network->area_id);
1037 ospf_schedule_abr_task(ospf);
1038 XFREE(MTYPE_OSPF_NETWORK, network);
718e3744 1039}
1040
d62a17ae 1041int ospf_network_set(struct ospf *ospf, struct prefix_ipv4 *p,
1042 struct in_addr area_id, int df)
718e3744 1043{
d62a17ae 1044 struct ospf_network *network;
1045 struct ospf_area *area;
1046 struct route_node *rn;
718e3744 1047
d62a17ae 1048 rn = route_node_get(ospf->networks, (struct prefix *)p);
1049 if (rn->info) {
2b0a905a 1050 network = rn->info;
d62a17ae 1051 route_unlock_node(rn);
2b0a905a
DW
1052
1053 if (IPV4_ADDR_SAME(&area_id, &network->area_id)) {
1054 return 1;
1055 } else {
1056 /* There is already same network statement. */
1057 return 0;
1058 }
d62a17ae 1059 }
718e3744 1060
d62a17ae 1061 rn->info = network = ospf_network_new(area_id);
1062 network->area_id_fmt = df;
1063 area = ospf_area_get(ospf, area_id);
1064 ospf_area_display_format_set(ospf, area, df);
718e3744 1065
d62a17ae 1066 /* Run network config now. */
1067 ospf_network_run((struct prefix *)p, area);
718e3744 1068
d62a17ae 1069 /* Update connected redistribute. */
1070 update_redistributed(ospf, 1); /* interfaces possibly added */
718e3744 1071
d62a17ae 1072 ospf_area_check_free(ospf, area_id);
718e3744 1073
d62a17ae 1074 return 1;
718e3744 1075}
1076
d62a17ae 1077int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
1078 struct in_addr area_id)
718e3744 1079{
d62a17ae 1080 struct route_node *rn;
1081 struct ospf_network *network;
1082 struct listnode *node, *nnode;
1083 struct ospf_interface *oi;
718e3744 1084
d62a17ae 1085 rn = route_node_lookup(ospf->networks, (struct prefix *)p);
1086 if (rn == NULL)
1087 return 0;
718e3744 1088
d62a17ae 1089 network = rn->info;
1090 route_unlock_node(rn);
1091 if (!IPV4_ADDR_SAME(&area_id, &network->area_id))
1092 return 0;
718e3744 1093
d62a17ae 1094 ospf_network_free(ospf, rn->info);
1095 rn->info = NULL;
1096 route_unlock_node(rn); /* initial reference */
718e3744 1097
30c0daa4 1098 /* Find interfaces that are not configured already. */
d62a17ae 1099 for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
30c0daa4 1100
996c9314
LB
1101 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
1102 continue;
30c0daa4 1103
996c9314 1104 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
d62a17ae 1105 }
953cde65 1106
d62a17ae 1107 /* Update connected redistribute. */
1108 update_redistributed(ospf, 0); /* interfaces possibly removed */
1109 ospf_area_check_free(ospf, area_id);
1110
1111 return 1;
953cde65
JT
1112}
1113
52c62ab8
JAG
1114/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means
1115 * there might not be any 'router ospf' config.
1116 *
1117 * Otherwise, doesn't do anything different to ospf_if_update for now
1118 */
b5a8894d 1119void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
953cde65 1120{
b5a8894d
CS
1121 if (!ospf)
1122 return;
d62a17ae 1123
1124 ospf_if_update(ospf, ifp);
1125 /* if_update does a update_redistributed */
1126
1127 return;
953cde65
JT
1128}
1129
b5a8894d 1130void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
953cde65 1131{
d62a17ae 1132 struct route_node *rn_oi;
953cde65 1133
d62a17ae 1134 if (!ospf)
1135 return; /* Ospf not ready yet */
953cde65 1136
d62a17ae 1137 /* Find interfaces that may need to be removed. */
1138 for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
1139 rn_oi = route_next(rn_oi)) {
b5a8894d 1140 struct ospf_interface *oi = NULL;
d62a17ae 1141
1142 if ((oi = rn_oi->info) == NULL)
1143 continue;
1144
1145 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
1146 continue;
1147
1148 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
1149 }
953cde65 1150
d62a17ae 1151 /* Update connected redistribute. */
1152 update_redistributed(ospf, 0); /* interfaces possibly removed */
718e3744 1153}
1154
570f7598 1155/* Check whether interface matches given network
1156 * returns: 1, true. 0, false
1157 */
d62a17ae 1158static int ospf_network_match_iface(const struct connected *co,
1159 const struct prefix *net)
570f7598 1160{
d62a17ae 1161 /* new approach: more elegant and conceptually clean */
1162 return prefix_match_network_statement(net, CONNECTED_PREFIX(co));
570f7598 1163}
1164
d62a17ae 1165static void ospf_update_interface_area(struct connected *co,
1166 struct ospf_area *area)
52c62ab8 1167{
d62a17ae 1168 struct ospf_interface *oi = ospf_if_table_lookup(co->ifp, co->address);
1169
1170 /* nothing to be done case */
1171 if (oi && oi->area == area) {
1172 return;
1173 }
1174
1175 if (oi)
1176 ospf_if_free(oi);
1177
1178 add_ospf_interface(co, area);
52c62ab8
JAG
1179}
1180
1181/* Run OSPF for the given subnet, taking into account the following
1182 * possible sources of area configuration, in the given order of preference:
1183 *
1184 * - Whether there is interface+address specific area configuration
1185 * - Whether there is a default area for the interface
1186 * - Whether there is an area given as a parameter.
1187 * - If no specific network prefix/area is supplied, whether there's
1188 * a matching network configured.
1189 */
d62a17ae 1190static void ospf_network_run_subnet(struct ospf *ospf, struct connected *co,
1191 struct prefix *p,
1192 struct ospf_area *given_area)
1193{
1194 struct ospf_interface *oi;
1195 struct ospf_if_params *params;
1196 struct ospf_area *area = NULL;
1197 struct route_node *rn;
1198 int configed = 0;
1199
1200 if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
1201 return;
1202
1203 if (co->address->family != AF_INET)
1204 return;
1205
1206 /* Try determine the appropriate area for this interface + address
1207 * Start by checking interface config
1208 */
1209 params = ospf_lookup_if_params(co->ifp, co->address->u.prefix4);
1210 if (params && OSPF_IF_PARAM_CONFIGURED(params, if_area))
1211 area = ospf_area_get(ospf, params->if_area);
1212 else {
1213 params = IF_DEF_PARAMS(co->ifp);
1214 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
1215 area = ospf_area_get(ospf, params->if_area);
1216 }
52c62ab8 1217
d62a17ae 1218 /* If we've found an interface and/or addr specific area, then we're
1219 * done
1220 */
1221 if (area) {
1222 ospf_update_interface_area(co, area);
1223 return;
1224 }
718e3744 1225
d62a17ae 1226 /* Otherwise, only remaining possibility is a matching network statement
1227 */
1228 if (p) {
1229 assert(given_area != NULL);
1230
1231 /* Which either was supplied as a parameter.. (e.g. cause a new
1232 * network/area was just added)..
1233 */
1234 if (p->family == co->address->family
1235 && ospf_network_match_iface(co, p))
1236 ospf_update_interface_area(co, given_area);
1237
1238 return;
1239 }
1240
1241 /* Else we have to search the existing network/area config to see
1242 * if any match..
1243 */
1244 for (rn = route_top(ospf->networks); rn; rn = route_next(rn))
1245 if (rn->info != NULL && ospf_network_match_iface(co, &rn->p)) {
1246 struct ospf_network *network =
1247 (struct ospf_network *)rn->info;
1248 area = ospf_area_get(ospf, network->area_id);
1249 ospf_update_interface_area(co, area);
1250 configed = 1;
1251 }
1252
1253 /* If the subnet isn't in any area, deconfigure */
1254 if (!configed && (oi = ospf_if_table_lookup(co->ifp, co->address)))
1255 ospf_if_free(oi);
718e3744 1256}
1257
d62a17ae 1258static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp,
1259 struct prefix *p,
1260 struct ospf_area *given_area)
718e3744 1261{
d62a17ae 1262 struct listnode *cnode;
1263 struct connected *co;
1264
1265 if (memcmp(ifp->name, "VLINK", 5) == 0)
1266 return;
718e3744 1267
d62a17ae 1268 /* Network prefix without area is nonsensical */
1269 if (p)
1270 assert(given_area != NULL);
1271
1272 /* if interface prefix is match specified prefix,
1273 then create socket and join multicast group. */
1274 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co))
1275 ospf_network_run_subnet(ospf, co, p, given_area);
718e3744 1276}
1277
d62a17ae 1278static void ospf_network_run(struct prefix *p, struct ospf_area *area)
718e3744 1279{
f4e14fdb 1280 struct vrf *vrf = vrf_lookup_by_id(area->ospf->vrf_id);
d62a17ae 1281 struct interface *ifp;
d62a17ae 1282
1283 /* Schedule Router ID Update. */
1284 if (area->ospf->router_id.s_addr == 0)
1285 ospf_router_id_update(area->ospf);
718e3744 1286
d62a17ae 1287 /* Get target interface. */
451fda4f 1288 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1289 ospf_network_run_interface(area->ospf, ifp, p, area);
718e3744 1290}
1291
d62a17ae 1292void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
1293{
1294 struct route_node *rn;
1295 struct listnode *node, *nnode;
1296 struct list *lst;
1297 struct ospf_lsa *lsa;
1298
1299 /* empty ls update queue */
1300 for (rn = route_top(oi->ls_upd_queue); rn; rn = route_next(rn))
1301 if ((lst = (struct list *)rn->info)) {
1302 for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa))
1303 ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */
affe9e99 1304 list_delete_and_null(&lst);
d62a17ae 1305 rn->info = NULL;
1306 }
1307
1308 /* remove update event */
1309 if (oi->t_ls_upd_event) {
1310 thread_cancel(oi->t_ls_upd_event);
1311 oi->t_ls_upd_event = NULL;
1312 }
1313}
6b0655a2 1314
d62a17ae 1315void ospf_if_update(struct ospf *ospf, struct interface *ifp)
718e3744 1316{
43b8d1d8 1317
d62a17ae 1318 if (!ospf)
43b8d1d8 1319 return;
b5a8894d
CS
1320
1321 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
1322 zlog_debug(
1323 "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
1324 __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
1325 ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
1326 inet_ntoa(ospf->router_id));
d62a17ae 1327
1328 /* OSPF must be ready. */
1329 if (!ospf_is_ready(ospf))
1330 return;
1331
1332 ospf_network_run_interface(ospf, ifp, NULL, NULL);
1333
1334 /* Update connected redistribute. */
1335 update_redistributed(ospf, 1);
1336}
718e3744 1337
d62a17ae 1338void ospf_remove_vls_through_area(struct ospf *ospf, struct ospf_area *area)
718e3744 1339{
d62a17ae 1340 struct listnode *node, *nnode;
1341 struct ospf_vl_data *vl_data;
718e3744 1342
d62a17ae 1343 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
1344 if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1345 ospf_vl_delete(ospf, vl_data);
1346}
718e3744 1347
718e3744 1348
d62a17ae 1349static const struct message ospf_area_type_msg[] = {
1350 {OSPF_AREA_DEFAULT, "Default"},
1351 {OSPF_AREA_STUB, "Stub"},
1352 {OSPF_AREA_NSSA, "NSSA"},
1353 {0}};
718e3744 1354
d62a17ae 1355static void ospf_area_type_set(struct ospf_area *area, int type)
1356{
1357 struct listnode *node;
1358 struct ospf_interface *oi;
1359
1360 if (area->external_routing == type) {
1361 if (IS_DEBUG_OSPF_EVENT)
1362 zlog_debug("Area[%s]: Types are the same, ignored.",
1363 inet_ntoa(area->area_id));
1364 return;
1365 }
718e3744 1366
d62a17ae 1367 area->external_routing = type;
1368
1369 if (IS_DEBUG_OSPF_EVENT)
1370 zlog_debug("Area[%s]: Configured as %s",
1371 inet_ntoa(area->area_id),
1372 lookup_msg(ospf_area_type_msg, type, NULL));
1373
1374 switch (area->external_routing) {
1375 case OSPF_AREA_DEFAULT:
1376 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1377 if (oi->nbr_self != NULL) {
1378 UNSET_FLAG(oi->nbr_self->options,
1379 OSPF_OPTION_NP);
1380 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
1381 }
1382 break;
1383 case OSPF_AREA_STUB:
1384 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1385 if (oi->nbr_self != NULL) {
1386 if (IS_DEBUG_OSPF_EVENT)
1387 zlog_debug(
1388 "setting options on %s accordingly",
1389 IF_NAME(oi));
1390 UNSET_FLAG(oi->nbr_self->options,
1391 OSPF_OPTION_NP);
1392 UNSET_FLAG(oi->nbr_self->options,
1393 OSPF_OPTION_E);
1394 if (IS_DEBUG_OSPF_EVENT)
1395 zlog_debug("options set on %s: %x",
1396 IF_NAME(oi), OPTIONS(oi));
1397 }
1398 break;
1399 case OSPF_AREA_NSSA:
1400 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
1401 if (oi->nbr_self != NULL) {
1402 zlog_debug(
1403 "setting nssa options on %s accordingly",
1404 IF_NAME(oi));
1405 UNSET_FLAG(oi->nbr_self->options,
1406 OSPF_OPTION_E);
1407 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP);
1408 zlog_debug("options set on %s: %x", IF_NAME(oi),
1409 OPTIONS(oi));
1410 }
1411 break;
1412 default:
1413 break;
1414 }
1415
1416 ospf_router_lsa_update_area(area);
1417 ospf_schedule_abr_task(area->ospf);
718e3744 1418}
1419
d62a17ae 1420int ospf_area_shortcut_set(struct ospf *ospf, struct ospf_area *area, int mode)
718e3744 1421{
d62a17ae 1422 if (area->shortcut_configured == mode)
1423 return 0;
718e3744 1424
d62a17ae 1425 area->shortcut_configured = mode;
1426 ospf_router_lsa_update_area(area);
1427 ospf_schedule_abr_task(ospf);
718e3744 1428
d62a17ae 1429 ospf_area_check_free(ospf, area->area_id);
718e3744 1430
d62a17ae 1431 return 1;
718e3744 1432}
1433
d62a17ae 1434int ospf_area_shortcut_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1435{
d62a17ae 1436 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1437 ospf_router_lsa_update_area(area);
1438 ospf_area_check_free(ospf, area->area_id);
1439 ospf_schedule_abr_task(ospf);
718e3744 1440
d62a17ae 1441 return 1;
718e3744 1442}
1443
d62a17ae 1444static int ospf_area_vlink_count(struct ospf *ospf, struct ospf_area *area)
718e3744 1445{
d62a17ae 1446 struct ospf_vl_data *vl;
1447 struct listnode *node;
1448 int count = 0;
718e3744 1449
d62a17ae 1450 for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl))
1451 if (IPV4_ADDR_SAME(&vl->vl_area_id, &area->area_id))
1452 count++;
718e3744 1453
d62a17ae 1454 return count;
718e3744 1455}
1456
d62a17ae 1457int ospf_area_display_format_set(struct ospf *ospf, struct ospf_area *area,
1458 int df)
86573dcb 1459{
d62a17ae 1460 area->area_id_fmt = df;
86573dcb 1461
d62a17ae 1462 return 1;
86573dcb
QY
1463}
1464
d62a17ae 1465int ospf_area_stub_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1466{
d62a17ae 1467 struct ospf_area *area;
718e3744 1468
d62a17ae 1469 area = ospf_area_get(ospf, area_id);
1470 if (ospf_area_vlink_count(ospf, area))
1471 return 0;
718e3744 1472
d62a17ae 1473 if (area->external_routing != OSPF_AREA_STUB)
1474 ospf_area_type_set(area, OSPF_AREA_STUB);
718e3744 1475
d62a17ae 1476 return 1;
718e3744 1477}
1478
d62a17ae 1479int ospf_area_stub_unset(struct ospf *ospf, struct in_addr area_id)
718e3744 1480{
d62a17ae 1481 struct ospf_area *area;
718e3744 1482
d62a17ae 1483 area = ospf_area_lookup_by_area_id(ospf, area_id);
1484 if (area == NULL)
1485 return 1;
718e3744 1486
d62a17ae 1487 if (area->external_routing == OSPF_AREA_STUB)
1488 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
718e3744 1489
d62a17ae 1490 ospf_area_check_free(ospf, area_id);
718e3744 1491
d62a17ae 1492 return 1;
718e3744 1493}
1494
d62a17ae 1495int ospf_area_no_summary_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1496{
d62a17ae 1497 struct ospf_area *area;
718e3744 1498
d62a17ae 1499 area = ospf_area_get(ospf, area_id);
1500 area->no_summary = 1;
718e3744 1501
d62a17ae 1502 return 1;
718e3744 1503}
1504
d62a17ae 1505int ospf_area_no_summary_unset(struct ospf *ospf, struct in_addr area_id)
718e3744 1506{
d62a17ae 1507 struct ospf_area *area;
718e3744 1508
d62a17ae 1509 area = ospf_area_lookup_by_area_id(ospf, area_id);
1510 if (area == NULL)
1511 return 0;
718e3744 1512
d62a17ae 1513 area->no_summary = 0;
1514 ospf_area_check_free(ospf, area_id);
718e3744 1515
d62a17ae 1516 return 1;
718e3744 1517}
1518
7ef56a73 1519int ospf_area_nssa_no_summary_set(struct ospf *ospf, struct in_addr area_id)
718e3744 1520{
d62a17ae 1521 struct ospf_area *area;
718e3744 1522
d62a17ae 1523 area = ospf_area_get(ospf, area_id);
1524 if (ospf_area_vlink_count(ospf, area))
1525 return 0;
718e3744 1526
d62a17ae 1527 if (area->external_routing != OSPF_AREA_NSSA) {
1528 ospf_area_type_set(area, OSPF_AREA_NSSA);
1529 ospf->anyNSSA++;
7ef56a73 1530 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
d62a17ae 1531 }
718e3744 1532
7ef56a73 1533 ospf_area_no_summary_set(ospf, area_id);
084c7844 1534
d62a17ae 1535 return 1;
718e3744 1536}
1537
7ef56a73
CS
1538int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id)
1539{
1540 struct ospf_area *area;
1541
1542 area = ospf_area_get(ospf, area_id);
1543 if (ospf_area_vlink_count(ospf, area))
1544 return 0;
1545
1546 if (area->external_routing != OSPF_AREA_NSSA) {
1547 ospf_area_type_set(area, OSPF_AREA_NSSA);
1548 ospf->anyNSSA++;
1549
1550 /* set NSSA area defaults */
1551 area->no_summary = 0;
1552 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1553 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
1554 area->NSSATranslatorStabilityInterval =
1555 OSPF_NSSA_TRANS_STABLE_DEFAULT;
1556 }
1557 return 1;
1558}
1559
1560int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
718e3744 1561{
d62a17ae 1562 struct ospf_area *area;
718e3744 1563
d62a17ae 1564 area = ospf_area_lookup_by_area_id(ospf, area_id);
1565 if (area == NULL)
1566 return 0;
718e3744 1567
7ef56a73
CS
1568 /* argc < 5 -> 'no area x nssa' */
1569 if (argc < 5 && area->external_routing == OSPF_AREA_NSSA) {
d62a17ae 1570 ospf->anyNSSA--;
7ef56a73
CS
1571 /* set NSSA area defaults */
1572 area->no_summary = 0;
1573 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1574 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
1575 area->NSSATranslatorStabilityInterval =
1576 OSPF_NSSA_TRANS_STABLE_DEFAULT;
d62a17ae 1577 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
7ef56a73
CS
1578 } else {
1579 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
d62a17ae 1580 }
718e3744 1581
d62a17ae 1582 ospf_area_check_free(ospf, area_id);
718e3744 1583
d62a17ae 1584 return 1;
718e3744 1585}
1586
d62a17ae 1587int ospf_area_nssa_translator_role_set(struct ospf *ospf,
1588 struct in_addr area_id, int role)
718e3744 1589{
d62a17ae 1590 struct ospf_area *area;
718e3744 1591
d62a17ae 1592 area = ospf_area_lookup_by_area_id(ospf, area_id);
1593 if (area == NULL)
1594 return 0;
718e3744 1595
d62a17ae 1596 area->NSSATranslatorRole = role;
718e3744 1597
d62a17ae 1598 return 1;
718e3744 1599}
1600
075e12f5 1601#if 0
4dadc291 1602/* XXX: unused? Leave for symmetry? */
1603static int
718e3744 1604ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1605 struct in_addr area_id)
1606{
1607 struct ospf_area *area;
1608
68980084 1609 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1610 if (area == NULL)
1611 return 0;
1612
084c7844 1613 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
718e3744 1614
68980084 1615 ospf_area_check_free (ospf, area_id);
718e3744 1616
1617 return 1;
1618}
075e12f5 1619#endif
718e3744 1620
d62a17ae 1621int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area,
1622 const char *list_name)
718e3744 1623{
d62a17ae 1624 struct access_list *list;
1625 list = access_list_lookup(AFI_IP, list_name);
718e3744 1626
d62a17ae 1627 EXPORT_LIST(area) = list;
718e3744 1628
d62a17ae 1629 if (EXPORT_NAME(area))
1630 free(EXPORT_NAME(area));
718e3744 1631
d62a17ae 1632 EXPORT_NAME(area) = strdup(list_name);
1633 ospf_schedule_abr_task(ospf);
718e3744 1634
d62a17ae 1635 return 1;
718e3744 1636}
1637
d62a17ae 1638int ospf_area_export_list_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1639{
1640
d62a17ae 1641 EXPORT_LIST(area) = 0;
718e3744 1642
d62a17ae 1643 if (EXPORT_NAME(area))
1644 free(EXPORT_NAME(area));
718e3744 1645
d62a17ae 1646 EXPORT_NAME(area) = NULL;
718e3744 1647
d62a17ae 1648 ospf_area_check_free(ospf, area->area_id);
718e3744 1649
d62a17ae 1650 ospf_schedule_abr_task(ospf);
1651
1652 return 1;
718e3744 1653}
1654
d62a17ae 1655int ospf_area_import_list_set(struct ospf *ospf, struct ospf_area *area,
1656 const char *name)
718e3744 1657{
d62a17ae 1658 struct access_list *list;
1659 list = access_list_lookup(AFI_IP, name);
718e3744 1660
d62a17ae 1661 IMPORT_LIST(area) = list;
718e3744 1662
d62a17ae 1663 if (IMPORT_NAME(area))
1664 free(IMPORT_NAME(area));
718e3744 1665
d62a17ae 1666 IMPORT_NAME(area) = strdup(name);
1667 ospf_schedule_abr_task(ospf);
718e3744 1668
d62a17ae 1669 return 1;
718e3744 1670}
1671
d62a17ae 1672int ospf_area_import_list_unset(struct ospf *ospf, struct ospf_area *area)
718e3744 1673{
d62a17ae 1674 IMPORT_LIST(area) = 0;
718e3744 1675
d62a17ae 1676 if (IMPORT_NAME(area))
1677 free(IMPORT_NAME(area));
718e3744 1678
d62a17ae 1679 IMPORT_NAME(area) = NULL;
1680 ospf_area_check_free(ospf, area->area_id);
718e3744 1681
d62a17ae 1682 ospf_schedule_abr_task(ospf);
718e3744 1683
d62a17ae 1684 return 1;
718e3744 1685}
1686
d62a17ae 1687int ospf_timers_refresh_set(struct ospf *ospf, int interval)
718e3744 1688{
d62a17ae 1689 int time_left;
718e3744 1690
d62a17ae 1691 if (ospf->lsa_refresh_interval == interval)
1692 return 1;
718e3744 1693
d62a17ae 1694 time_left = ospf->lsa_refresh_interval
1695 - (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1696
d62a17ae 1697 if (time_left > interval) {
1698 OSPF_TIMER_OFF(ospf->t_lsa_refresher);
1699 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
1700 interval, &ospf->t_lsa_refresher);
1701 }
1702 ospf->lsa_refresh_interval = interval;
1703
1704 return 1;
718e3744 1705}
1706
d62a17ae 1707int ospf_timers_refresh_unset(struct ospf *ospf)
718e3744 1708{
d62a17ae 1709 int time_left;
718e3744 1710
d62a17ae 1711 time_left = ospf->lsa_refresh_interval
1712 - (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1713
d62a17ae 1714 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) {
1715 OSPF_TIMER_OFF(ospf->t_lsa_refresher);
1716 ospf->t_lsa_refresher = NULL;
1717 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
1718 OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
1719 &ospf->t_lsa_refresher);
1720 }
718e3744 1721
d62a17ae 1722 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
718e3744 1723
d62a17ae 1724 return 1;
718e3744 1725}
1726
6b0655a2 1727
d62a17ae 1728static struct ospf_nbr_nbma *ospf_nbr_nbma_new(void)
718e3744 1729{
d62a17ae 1730 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1731
d62a17ae 1732 nbr_nbma = XCALLOC(MTYPE_OSPF_NEIGHBOR_STATIC,
1733 sizeof(struct ospf_nbr_nbma));
718e3744 1734
d62a17ae 1735 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1736 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
718e3744 1737
d62a17ae 1738 return nbr_nbma;
718e3744 1739}
1740
d62a17ae 1741static void ospf_nbr_nbma_free(struct ospf_nbr_nbma *nbr_nbma)
718e3744 1742{
d62a17ae 1743 XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
718e3744 1744}
1745
d62a17ae 1746static void ospf_nbr_nbma_delete(struct ospf *ospf,
1747 struct ospf_nbr_nbma *nbr_nbma)
718e3744 1748{
d62a17ae 1749 struct route_node *rn;
1750 struct prefix_ipv4 p;
718e3744 1751
d62a17ae 1752 p.family = AF_INET;
1753 p.prefix = nbr_nbma->addr;
1754 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1755
d62a17ae 1756 rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
1757 if (rn) {
1758 ospf_nbr_nbma_free(rn->info);
1759 rn->info = NULL;
1760 route_unlock_node(rn);
1761 route_unlock_node(rn);
1762 }
718e3744 1763}
1764
d62a17ae 1765static void ospf_nbr_nbma_down(struct ospf_nbr_nbma *nbr_nbma)
718e3744 1766{
d62a17ae 1767 OSPF_TIMER_OFF(nbr_nbma->t_poll);
718e3744 1768
d62a17ae 1769 if (nbr_nbma->nbr) {
1770 nbr_nbma->nbr->nbr_nbma = NULL;
1771 OSPF_NSM_EVENT_EXECUTE(nbr_nbma->nbr, NSM_KillNbr);
1772 }
718e3744 1773
d62a17ae 1774 if (nbr_nbma->oi)
1775 listnode_delete(nbr_nbma->oi->nbr_nbma, nbr_nbma);
718e3744 1776}
1777
d62a17ae 1778static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma,
1779 struct ospf_interface *oi)
718e3744 1780{
d62a17ae 1781 struct ospf_neighbor *nbr;
1782 struct route_node *rn;
1783 struct prefix p;
718e3744 1784
d62a17ae 1785 if (oi->type != OSPF_IFTYPE_NBMA)
1786 return;
718e3744 1787
d62a17ae 1788 if (nbr_nbma->nbr != NULL)
1789 return;
718e3744 1790
d62a17ae 1791 if (IPV4_ADDR_SAME(&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1792 return;
718e3744 1793
d62a17ae 1794 nbr_nbma->oi = oi;
1795 listnode_add(oi->nbr_nbma, nbr_nbma);
718e3744 1796
d62a17ae 1797 /* Get neighbor information from table. */
1798 p.family = AF_INET;
1799 p.prefixlen = IPV4_MAX_BITLEN;
1800 p.u.prefix4 = nbr_nbma->addr;
718e3744 1801
d62a17ae 1802 rn = route_node_get(oi->nbrs, (struct prefix *)&p);
1803 if (rn->info) {
1804 nbr = rn->info;
1805 nbr->nbr_nbma = nbr_nbma;
1806 nbr_nbma->nbr = nbr;
718e3744 1807
d62a17ae 1808 route_unlock_node(rn);
1809 } else {
1810 nbr = rn->info = ospf_nbr_new(oi);
1811 nbr->state = NSM_Down;
1812 nbr->src = nbr_nbma->addr;
1813 nbr->nbr_nbma = nbr_nbma;
1814 nbr->priority = nbr_nbma->priority;
1815 nbr->address = p;
718e3744 1816
d62a17ae 1817 nbr_nbma->nbr = nbr;
1818
1819 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start);
1820 }
718e3744 1821}
1822
d62a17ae 1823void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi)
718e3744 1824{
d62a17ae 1825 struct ospf_nbr_nbma *nbr_nbma;
1826 struct route_node *rn;
1827 struct prefix_ipv4 p;
718e3744 1828
d62a17ae 1829 if (oi->type != OSPF_IFTYPE_NBMA)
1830 return;
718e3744 1831
d62a17ae 1832 for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
1833 if ((nbr_nbma = rn->info))
1834 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL) {
1835 p.family = AF_INET;
1836 p.prefix = nbr_nbma->addr;
1837 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1838
d62a17ae 1839 if (prefix_match(oi->address,
1840 (struct prefix *)&p))
1841 ospf_nbr_nbma_add(nbr_nbma, oi);
1842 }
718e3744 1843}
1844
d62a17ae 1845struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *ospf,
1846 struct in_addr nbr_addr)
718e3744 1847{
d62a17ae 1848 struct route_node *rn;
1849 struct prefix_ipv4 p;
718e3744 1850
d62a17ae 1851 p.family = AF_INET;
1852 p.prefix = nbr_addr;
1853 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1854
d62a17ae 1855 rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
1856 if (rn) {
1857 route_unlock_node(rn);
1858 return rn->info;
1859 }
1860 return NULL;
718e3744 1861}
1862
d62a17ae 1863struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next(struct ospf *ospf,
1864 struct in_addr *addr, int first)
718e3744 1865{
1866#if 0
1867 struct ospf_nbr_nbma *nbr_nbma;
52dc7ee6 1868 struct listnode *node;
718e3744 1869#endif
1870
d62a17ae 1871 if (ospf == NULL)
1872 return NULL;
718e3744 1873
1874#if 0
1eb8ef25 1875 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
718e3744 1876 {
718e3744 1877 if (first)
1878 {
1879 *addr = nbr_nbma->addr;
1880 return nbr_nbma;
1881 }
1882 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1883 {
1884 *addr = nbr_nbma->addr;
1885 return nbr_nbma;
1886 }
1887 }
1888#endif
d62a17ae 1889 return NULL;
718e3744 1890}
1891
d62a17ae 1892int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 1893{
d62a17ae 1894 struct ospf_nbr_nbma *nbr_nbma;
1895 struct ospf_interface *oi;
1896 struct prefix_ipv4 p;
1897 struct route_node *rn;
1898 struct listnode *node;
718e3744 1899
d62a17ae 1900 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
1901 if (nbr_nbma)
1902 return 0;
718e3744 1903
d62a17ae 1904 nbr_nbma = ospf_nbr_nbma_new();
1905 nbr_nbma->addr = nbr_addr;
718e3744 1906
d62a17ae 1907 p.family = AF_INET;
1908 p.prefix = nbr_addr;
1909 p.prefixlen = IPV4_MAX_BITLEN;
718e3744 1910
d62a17ae 1911 rn = route_node_get(ospf->nbr_nbma, (struct prefix *)&p);
1912 if (rn->info)
1913 route_unlock_node(rn);
1914 rn->info = nbr_nbma;
718e3744 1915
d62a17ae 1916 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
1917 if (oi->type == OSPF_IFTYPE_NBMA)
1918 if (prefix_match(oi->address, (struct prefix *)&p)) {
1919 ospf_nbr_nbma_add(nbr_nbma, oi);
1920 break;
1921 }
1922 }
718e3744 1923
d62a17ae 1924 return 1;
718e3744 1925}
1926
d62a17ae 1927int ospf_nbr_nbma_unset(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 1928{
d62a17ae 1929 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1930
d62a17ae 1931 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
1932 if (nbr_nbma == NULL)
1933 return 0;
718e3744 1934
d62a17ae 1935 ospf_nbr_nbma_down(nbr_nbma);
1936 ospf_nbr_nbma_delete(ospf, nbr_nbma);
718e3744 1937
d62a17ae 1938 return 1;
718e3744 1939}
1940
d62a17ae 1941int ospf_nbr_nbma_priority_set(struct ospf *ospf, struct in_addr nbr_addr,
d7c0a89a 1942 uint8_t priority)
718e3744 1943{
d62a17ae 1944 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1945
d62a17ae 1946 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
1947 if (nbr_nbma == NULL)
1948 return 0;
718e3744 1949
d62a17ae 1950 if (nbr_nbma->priority != priority)
1951 nbr_nbma->priority = priority;
718e3744 1952
d62a17ae 1953 return 1;
718e3744 1954}
1955
d62a17ae 1956int ospf_nbr_nbma_priority_unset(struct ospf *ospf, struct in_addr nbr_addr)
718e3744 1957{
d62a17ae 1958 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1959
d62a17ae 1960 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
1961 if (nbr_nbma == NULL)
1962 return 0;
718e3744 1963
d62a17ae 1964 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1965 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
718e3744 1966
d62a17ae 1967 return 1;
718e3744 1968}
1969
d62a17ae 1970int ospf_nbr_nbma_poll_interval_set(struct ospf *ospf, struct in_addr nbr_addr,
1971 unsigned int interval)
718e3744 1972{
d62a17ae 1973 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1974
d62a17ae 1975 nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
1976 if (nbr_nbma == NULL)
1977 return 0;
718e3744 1978
d62a17ae 1979 if (nbr_nbma->v_poll != interval) {
1980 nbr_nbma->v_poll = interval;
1981 if (nbr_nbma->oi && ospf_if_is_up(nbr_nbma->oi)) {
1982 OSPF_TIMER_OFF(nbr_nbma->t_poll);
1983 OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer,
1984 nbr_nbma->v_poll);
1985 }
718e3744 1986 }
718e3744 1987
d62a17ae 1988 return 1;
718e3744 1989}
1990
d62a17ae 1991int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
718e3744 1992{
d62a17ae 1993 struct ospf_nbr_nbma *nbr_nbma;
718e3744 1994
d62a17ae 1995 nbr_nbma = ospf_nbr_nbma_lookup(ospf, addr);
1996 if (nbr_nbma == NULL)
1997 return 0;
718e3744 1998
d62a17ae 1999 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
2000 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
718e3744 2001
d62a17ae 2002 return 1;
718e3744 2003}
2004
d62a17ae 2005void ospf_master_init(struct thread_master *master)
718e3744 2006{
d62a17ae 2007 memset(&ospf_master, 0, sizeof(struct ospf_master));
020709f9 2008
d62a17ae 2009 om = &ospf_master;
2010 om->ospf = list_new();
2011 om->master = master;
020709f9 2012}
b5a8894d
CS
2013
2014/* Link OSPF instance to VRF. */
2015void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
2016{
2017 ospf->vrf_id = vrf->vrf_id;
2018 if (vrf->info != (void *)ospf)
2019 vrf->info = (void *)ospf;
2020}
2021
2022/* Unlink OSPF instance from VRF. */
2023void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
2024{
2025 if (vrf->info == (void *)ospf)
2026 vrf->info = NULL;
2027 ospf->vrf_id = VRF_UNKNOWN;
2028}
2029
2030/* This is hook function for vrf create called as part of vrf_init */
2031static int ospf_vrf_new(struct vrf *vrf)
2032{
2033 if (IS_DEBUG_OSPF_EVENT)
fe3da9e7 2034 zlog_debug("%s: VRF Created: %s(%u)", __PRETTY_FUNCTION__,
b5a8894d
CS
2035 vrf->name, vrf->vrf_id);
2036
2037 return 0;
2038}
2039
2040/* This is hook function for vrf delete call as part of vrf_init */
2041static int ospf_vrf_delete(struct vrf *vrf)
2042{
2043 if (IS_DEBUG_OSPF_EVENT)
fe3da9e7 2044 zlog_debug("%s: VRF Deletion: %s(%u)", __PRETTY_FUNCTION__,
b5a8894d
CS
2045 vrf->name, vrf->vrf_id);
2046
2047 return 0;
2048}
2049
3d9f7302
PZ
2050static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf)
2051{
2052 int type;
2053 struct list *red_list;
2054
2055 for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
2056 red_list = ospf->redist[type];
2057 if (!red_list)
2058 continue;
2059 if (IS_DEBUG_OSPF_EVENT)
2060 zlog_debug(
2061 "%s: setting redist vrf %d bitmap for type %d",
2062 __func__, ospf->vrf_id, type);
2063 vrf_bitmap_set(zclient->redist[AFI_IP][type], ospf->vrf_id);
2064 }
2065}
2066
b5a8894d
CS
2067/* Enable OSPF VRF instance */
2068static int ospf_vrf_enable(struct vrf *vrf)
2069{
2070 struct ospf *ospf = NULL;
7d206035 2071 vrf_id_t old_vrf_id;
3c0eb8fa 2072 int ret = 0;
b5a8894d
CS
2073
2074 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
2075 zlog_debug("%s: VRF %s id %u enabled", __PRETTY_FUNCTION__,
2076 vrf->name, vrf->vrf_id);
b5a8894d
CS
2077
2078 ospf = ospf_lookup_by_name(vrf->name);
2079 if (ospf) {
2080 old_vrf_id = ospf->vrf_id;
2081 /* We have instance configured, link to VRF and make it "up". */
2082 ospf_vrf_link(ospf, vrf);
2083 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
2084 zlog_debug(
2085 "%s: ospf linked to vrf %s vrf_id %u (old id %u)",
2086 __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
2087 old_vrf_id);
b5a8894d
CS
2088
2089 if (old_vrf_id != ospf->vrf_id) {
e7503eab 2090 if (ospfd_privs.change(ZPRIVS_RAISE)) {
996c9314
LB
2091 zlog_err(
2092 "ospf_sock_init: could not raise privs, %s",
2093 safe_strerror(errno));
e7503eab 2094 }
3d9f7302
PZ
2095
2096 /* stop zebra redist to us for old vrf */
2097 zclient_send_dereg_requests(zclient, old_vrf_id);
2098
2099 ospf_set_redist_vrf_bitmaps(ospf);
2100
2101 /* start zebra redist to us for new vrf */
2102 ospf_zebra_vrf_register(ospf);
2103
3c0eb8fa 2104 ret = ospf_sock_init(ospf);
e7503eab 2105 if (ospfd_privs.change(ZPRIVS_LOWER)) {
996c9314
LB
2106 zlog_err(
2107 "ospf_sock_init: could not lower privs, %s",
2108 safe_strerror(errno));
e7503eab 2109 }
3c0eb8fa
PG
2110 if (ret < 0 || ospf->fd <= 0)
2111 return 0;
996c9314
LB
2112 thread_add_read(master, ospf_read, ospf, ospf->fd,
2113 &ospf->t_read);
b5a8894d
CS
2114 ospf->oi_running = 1;
2115 ospf_router_id_update(ospf);
2116 }
2117 }
2118
2119 return 0;
2120}
2121
2122/* Disable OSPF VRF instance */
2123static int ospf_vrf_disable(struct vrf *vrf)
2124{
2125 struct ospf *ospf = NULL;
2126 vrf_id_t old_vrf_id = VRF_UNKNOWN;
2127
2128 if (vrf->vrf_id == VRF_DEFAULT)
2129 return 0;
2130
2131 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
2132 zlog_debug("%s: VRF %s id %d disabled.", __PRETTY_FUNCTION__,
2133 vrf->name, vrf->vrf_id);
b5a8894d
CS
2134
2135 ospf = ospf_lookup_by_name(vrf->name);
2136 if (ospf) {
2137 old_vrf_id = ospf->vrf_id;
2138
2139 /* We have instance configured, unlink
2140 * from VRF and make it "down".
2141 */
2142 ospf_vrf_unlink(ospf, vrf);
2143 ospf->oi_running = 0;
2144 if (IS_DEBUG_OSPF_EVENT)
2145 zlog_debug("%s: ospf old_vrf_id %d unlinked",
996c9314 2146 __PRETTY_FUNCTION__, old_vrf_id);
3c0eb8fa
PG
2147 thread_cancel(ospf->t_read);
2148 close(ospf->fd);
2149 ospf->fd = -1;
b5a8894d
CS
2150 }
2151
2152 /* Note: This is a callback, the VRF will be deleted by the caller. */
2153 return 0;
2154}
2155
2156void ospf_vrf_init(void)
2157{
996c9314
LB
2158 vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
2159 ospf_vrf_delete);
b5a8894d
CS
2160}
2161
2162void ospf_vrf_terminate(void)
2163{
2164 vrf_terminate();
2165}
2166
2167const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
2168{
2169 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
2170
2171 return vrf ? vrf->name : "NIL";
2172}