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