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