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