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