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