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