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