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