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