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