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