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