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