blob: e8405136765303f7159a5ea58c49de5c21cb1bbc [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
Denis Ovsienkof102e752007-09-18 09:01:13 +000036#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_network.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_lsdb.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_packet.h"
49#include "ospfd/ospf_dump.h"
50#include "ospfd/ospf_zebra.h"
51#include "ospfd/ospf_abr.h"
52#include "ospfd/ospf_flood.h"
53#include "ospfd/ospf_route.h"
54#include "ospfd/ospf_ase.h"
55
paul020709f2003-04-04 02:44:16 +000056
pauledd7c242003-06-04 13:59:38 +000057
paul020709f2003-04-04 02:44:16 +000058/* OSPF process wide configuration. */
59static struct ospf_master ospf_master;
60
61/* OSPF process wide configuration pointer to export. */
62struct ospf_master *om;
paul718e3742002-12-13 20:15:29 +000063
64extern struct zclient *zclient;
hasso18a6dce2004-10-03 18:18:34 +000065extern struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000066
67
paul88d6cf32005-10-29 12:50:09 +000068static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
69static void ospf_network_free (struct ospf *, struct ospf_network *);
70static void ospf_area_free (struct ospf_area *);
Joakim Tjernlunda49eb302008-09-02 19:06:31 +010071static void ospf_network_run (struct prefix *, struct ospf_area *);
72static void ospf_network_run_interface (struct prefix *, struct ospf_area *,
73 struct interface *);
Stephen Hemminger917e2992009-12-03 19:07:00 +030074static int ospf_network_match_iface (const struct connected *,
75 const struct prefix *);
paul88d6cf32005-10-29 12:50:09 +000076static void ospf_finish_final (struct ospf *);
paul718e3742002-12-13 20:15:29 +000077
paul718e3742002-12-13 20:15:29 +000078#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
paul88d6cf32005-10-29 12:50:09 +000079
paul718e3742002-12-13 20:15:29 +000080void
paul68980082003-03-25 05:07:42 +000081ospf_router_id_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +000082{
paul718e3742002-12-13 20:15:29 +000083 struct in_addr router_id, router_id_old;
paul1eb8ef22005-04-07 07:30:20 +000084 struct ospf_interface *oi;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +010085 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +000086 struct listnode *node;
paul718e3742002-12-13 20:15:29 +000087
88 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +000089 zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +000090
paul68980082003-03-25 05:07:42 +000091 router_id_old = ospf->router_id;
paul718e3742002-12-13 20:15:29 +000092
Andrew J. Schorr16700082006-07-27 22:29:06 +000093 /* Select the router ID based on these priorities:
94 1. Statically assigned router ID is always the first choice.
95 2. If there is no statically assigned router ID, then try to stick
96 with the most recent value, since changing router ID's is very
97 disruptive.
98 3. Last choice: just go with whatever the zebra daemon recommends.
99 */
paul68980082003-03-25 05:07:42 +0000100 if (ospf->router_id_static.s_addr != 0)
101 router_id = ospf->router_id_static;
Andrew J. Schorr16700082006-07-27 22:29:06 +0000102 else if (ospf->router_id.s_addr != 0)
103 router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000104 else
hasso18a6dce2004-10-03 18:18:34 +0000105 router_id = router_id_zebra;
paul718e3742002-12-13 20:15:29 +0000106
paul68980082003-03-25 05:07:42 +0000107 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000108
109 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000110 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000111
112 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
113 {
paul1eb8ef22005-04-07 07:30:20 +0000114 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
115 /* Update self-neighbor's router_id. */
116 oi->nbr_self->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000117
118 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000119 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000120 {
121 int type;
122 /* Originate each redistributed external route. */
123 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000124 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000125 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000126 ospf, type);
paul718e3742002-12-13 20:15:29 +0000127 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000128 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
Paul Jakma4021b602006-05-12 22:55:41 +0000129 thread_add_event (master, ospf_default_originate_timer, ospf, 0);
paul718e3742002-12-13 20:15:29 +0000130
paul68980082003-03-25 05:07:42 +0000131 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000132 }
133
Paul Jakmac363d382010-01-24 22:42:13 +0000134 /* update router-lsa's for each area */
135 ospf_router_lsa_update (ospf);
paulb29800a2005-11-20 14:50:45 +0000136
137 /* update ospf_interface's */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100138 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
139 ospf_if_update (ospf, ifp);
paul718e3742002-12-13 20:15:29 +0000140 }
141}
paul718e3742002-12-13 20:15:29 +0000142
143/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000144static int
paul718e3742002-12-13 20:15:29 +0000145ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
146{
147 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
148 return 1;
149 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
150 return -1;
151 return 0;
152}
153
154/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000155static struct ospf *
156ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000157{
158 int i;
159
160 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
161
162 new->router_id.s_addr = htonl (0);
163 new->router_id_static.s_addr = htonl (0);
164
pauld57834f2005-07-12 20:04:22 +0000165 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000166 new->oiflist = list_new ();
167 new->vlinks = list_new ();
168 new->areas = list_new ();
169 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
170 new->networks = route_table_init ();
171 new->nbr_nbma = route_table_init ();
172
173 new->lsdb = ospf_lsdb_new ();
174
175 new->default_originate = DEFAULT_ORIGINATE_NONE;
176
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000177 new->passive_interface_default = OSPF_IF_ACTIVE;
178
paul718e3742002-12-13 20:15:29 +0000179 new->new_external_route = route_table_init ();
180 new->old_external_route = route_table_init ();
181 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000182
183 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000184 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul88d6cf32005-10-29 12:50:09 +0000185
paul718e3742002-12-13 20:15:29 +0000186 /* Distribute parameter init. */
187 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
188 {
189 new->dmetric[i].type = -1;
190 new->dmetric[i].value = -1;
191 }
192 new->default_metric = -1;
193 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
194
195 /* SPF timer value init. */
196 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
197 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000198 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
199 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000200
201 /* MaxAge init. */
Paul Jakma02d942c2010-01-24 23:36:20 +0000202 new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000203 new->maxage_lsa = list_new ();
204 new->t_maxage_walker =
205 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000206 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000207
208 /* Distance table init. */
209 new->distance_table = route_table_init ();
210
211 new->lsa_refresh_queue.index = 0;
212 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
213 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
214 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000215 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000216
ajs5c333492005-02-23 15:43:01 +0000217 if ((new->fd = ospf_sock_init()) < 0)
218 {
219 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
220 "a socket");
221 exit(1);
222 }
Denis Ovsienkof102e752007-09-18 09:01:13 +0000223 new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
224 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
225 zlog_debug ("%s: starting with OSPF send buffer size %d",
226 __func__, new->maxsndbuflen);
ajs5c333492005-02-23 15:43:01 +0000227 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
228 {
229 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
230 OSPF_MAX_PACKET_SIZE+1);
231 exit(1);
232 }
233 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000234 new->oi_write_q = list_new ();
235
236 return new;
237}
238
239struct ospf *
paul020709f2003-04-04 02:44:16 +0000240ospf_lookup ()
241{
242 if (listcount (om->ospf) == 0)
243 return NULL;
244
paul1eb8ef22005-04-07 07:30:20 +0000245 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000246}
247
paul4dadc292005-05-06 21:37:42 +0000248static void
paul020709f2003-04-04 02:44:16 +0000249ospf_add (struct ospf *ospf)
250{
251 listnode_add (om->ospf, ospf);
252}
253
paul4dadc292005-05-06 21:37:42 +0000254static void
paul020709f2003-04-04 02:44:16 +0000255ospf_delete (struct ospf *ospf)
256{
257 listnode_delete (om->ospf, ospf);
258}
259
260struct ospf *
paul718e3742002-12-13 20:15:29 +0000261ospf_get ()
262{
paul020709f2003-04-04 02:44:16 +0000263 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000264
paul020709f2003-04-04 02:44:16 +0000265 ospf = ospf_lookup ();
266 if (ospf == NULL)
267 {
268 ospf = ospf_new ();
269 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000270
paul020709f2003-04-04 02:44:16 +0000271 if (ospf->router_id_static.s_addr == 0)
272 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000273
274#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000275 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000276#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000277 }
paul68980082003-03-25 05:07:42 +0000278
279 return ospf;
paul718e3742002-12-13 20:15:29 +0000280}
paul88d6cf32005-10-29 12:50:09 +0000281
paulc9c93d52005-11-26 13:31:11 +0000282/* Handle the second half of deferred shutdown. This is called either
283 * from the deferred-shutdown timer thread, or directly through
284 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000285 *
286 * Function is to cleanup G-R state, if required then call ospf_finish_final
287 * to complete shutdown of this ospf instance. Possibly exit if the
288 * whole process is being shutdown and this was the last OSPF instance.
289 */
290static void
paulc9c93d52005-11-26 13:31:11 +0000291ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000292{
293 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000294 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000295
296 ospf_finish_final (ospf);
297
298 /* *ospf is now invalid */
299
300 /* ospfd being shut-down? If so, was this the last ospf instance? */
301 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
302 && (listcount (om->ospf) == 0))
303 exit (0);
304
305 return;
306}
307
308/* Timer thread for G-R */
309static int
paulc9c93d52005-11-26 13:31:11 +0000310ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000311{
312 struct ospf *ospf = THREAD_ARG(t);
313
paulc9c93d52005-11-26 13:31:11 +0000314 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000315
316 return 0;
317}
318
paulc9c93d52005-11-26 13:31:11 +0000319/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000320 * down directly into second-half of instance shutdown.
321 */
322static void
paulc9c93d52005-11-26 13:31:11 +0000323ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000324{
325 unsigned long timeout;
326 struct listnode *ln;
327 struct ospf_area *area;
328
paulc9c93d52005-11-26 13:31:11 +0000329 /* deferred shutdown already running? */
330 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000331 return;
332
333 /* Should we try push out max-metric LSAs? */
334 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
335 {
336 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
337 {
338 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
339
340 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
Paul Jakmac363d382010-01-24 22:42:13 +0000341 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000342 }
343 timeout = ospf->stub_router_shutdown_time;
344 }
345 else
paulc9c93d52005-11-26 13:31:11 +0000346 {
347 /* No timer needed */
348 ospf_deferred_shutdown_finish (ospf);
349 return;
350 }
paul88d6cf32005-10-29 12:50:09 +0000351
paulc9c93d52005-11-26 13:31:11 +0000352 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000353 timeout);
354 return;
355}
356
357/* Shut down the entire process */
358void
359ospf_terminate (void)
360{
361 struct ospf *ospf;
362 struct listnode *node, *nnode;
363
364 /* shutdown already in progress */
365 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
366 return;
367
368 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
369
Andrew J. Schorr4056a542007-02-27 13:55:46 +0000370 /* exit immediately if OSPF not actually running */
371 if (listcount(om->ospf) == 0)
372 exit(0);
373
paul88d6cf32005-10-29 12:50:09 +0000374 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
375 ospf_finish (ospf);
376
377 /* Deliberately go back up, hopefully to thread scheduler, as
378 * One or more ospf_finish()'s may have deferred shutdown to a timer
379 * thread
380 */
381}
paul718e3742002-12-13 20:15:29 +0000382
383void
384ospf_finish (struct ospf *ospf)
385{
paulc9c93d52005-11-26 13:31:11 +0000386 /* let deferred shutdown decide */
387 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000388
paulc9c93d52005-11-26 13:31:11 +0000389 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000390 * deferred to expiry of G-S timer thread. Return back up, hopefully
391 * to thread scheduler.
392 */
paulc9c93d52005-11-26 13:31:11 +0000393 return;
paul88d6cf32005-10-29 12:50:09 +0000394}
395
396/* Final cleanup of ospf instance */
397static void
398ospf_finish_final (struct ospf *ospf)
399{
paul718e3742002-12-13 20:15:29 +0000400 struct route_node *rn;
401 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000402 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000403 struct ospf_interface *oi;
404 struct ospf_area *area;
405 struct ospf_vl_data *vl_data;
406 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000407 int i;
408
409#ifdef HAVE_OPAQUE_LSA
410 ospf_opaque_type11_lsa_term (ospf);
411#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000412
413 /* be nice if this worked, but it doesn't */
414 /*ospf_flush_self_originated_lsas_now (ospf);*/
415
416 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000417 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000418 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000419 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000420
paul1eb8ef22005-04-07 07:30:20 +0000421 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
422 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000423
paul1eb8ef22005-04-07 07:30:20 +0000424 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
425 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000426
427 list_delete (ospf->vlinks);
428
429 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000430 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
431 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000432
433 /* Clear static neighbors */
434 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
435 if ((nbr_nbma = rn->info))
436 {
437 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
438
439 if (nbr_nbma->nbr)
440 {
441 nbr_nbma->nbr->nbr_nbma = NULL;
442 nbr_nbma->nbr = NULL;
443 }
444
445 if (nbr_nbma->oi)
446 {
447 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
448 nbr_nbma->oi = NULL;
449 }
450
451 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
452 }
453
454 route_table_finish (ospf->nbr_nbma);
455
456 /* Clear networks and Areas. */
457 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
458 {
459 struct ospf_network *network;
460
461 if ((network = rn->info) != NULL)
462 {
paul68980082003-03-25 05:07:42 +0000463 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000464 rn->info = NULL;
465 route_unlock_node (rn);
466 }
467 }
468
paul1eb8ef22005-04-07 07:30:20 +0000469 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000470 {
paul718e3742002-12-13 20:15:29 +0000471 listnode_delete (ospf->areas, area);
472 ospf_area_free (area);
473 }
474
475 /* Cancel all timers. */
476 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000477 OSPF_TIMER_OFF (ospf->t_spf_calc);
478 OSPF_TIMER_OFF (ospf->t_ase_calc);
479 OSPF_TIMER_OFF (ospf->t_maxage);
480 OSPF_TIMER_OFF (ospf->t_maxage_walker);
481 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000482 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000483 OSPF_TIMER_OFF (ospf->t_distribute_update);
484 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
485 OSPF_TIMER_OFF (ospf->t_read);
486 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000487#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000488 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000489#endif
paul718e3742002-12-13 20:15:29 +0000490
491 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000492 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000493
494#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000495 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
496 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000497#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000498 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
499 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
500
paul718e3742002-12-13 20:15:29 +0000501 ospf_lsdb_delete_all (ospf->lsdb);
502 ospf_lsdb_free (ospf->lsdb);
503
paul1eb8ef22005-04-07 07:30:20 +0000504 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000505 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +0000506
507 list_delete (ospf->maxage_lsa);
508
509 if (ospf->old_table)
510 ospf_route_table_free (ospf->old_table);
511 if (ospf->new_table)
512 {
513 ospf_route_delete (ospf->new_table);
514 ospf_route_table_free (ospf->new_table);
515 }
516 if (ospf->old_rtrs)
517 ospf_rtrs_free (ospf->old_rtrs);
518 if (ospf->new_rtrs)
519 ospf_rtrs_free (ospf->new_rtrs);
520 if (ospf->new_external_route)
521 {
522 ospf_route_delete (ospf->new_external_route);
523 ospf_route_table_free (ospf->new_external_route);
524 }
525 if (ospf->old_external_route)
526 {
527 ospf_route_delete (ospf->old_external_route);
528 ospf_route_table_free (ospf->old_external_route);
529 }
530 if (ospf->external_lsas)
531 {
532 ospf_ase_external_lsas_finish (ospf->external_lsas);
533 }
534
535 list_delete (ospf->areas);
536
537 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
538 if (EXTERNAL_INFO (i) != NULL)
539 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
540 {
541 if (rn->info == NULL)
542 continue;
543
544 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
545 rn->info = NULL;
546 route_unlock_node (rn);
547 }
548
paul68980082003-03-25 05:07:42 +0000549 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000550 route_table_finish (ospf->distance_table);
551
paul020709f2003-04-04 02:44:16 +0000552 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000553
paul020709f2003-04-04 02:44:16 +0000554 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000555}
556
557
558/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000559static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000560ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000561{
562 struct ospf_area *new;
563
564 /* Allocate new config_network. */
565 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
566
paul68980082003-03-25 05:07:42 +0000567 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000568
569 new->area_id = area_id;
570
571 new->external_routing = OSPF_AREA_DEFAULT;
572 new->default_cost = 1;
573 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000574
paul718e3742002-12-13 20:15:29 +0000575 /* New LSDB init. */
576 new->lsdb = ospf_lsdb_new ();
577
578 /* Self-originated LSAs initialize. */
579 new->router_lsa_self = NULL;
580
581#ifdef HAVE_OPAQUE_LSA
582 ospf_opaque_type10_lsa_init (new);
583#endif /* HAVE_OPAQUE_LSA */
584
585 new->oiflist = list_new ();
586 new->ranges = route_table_init ();
587
588 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000589 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000590
591 return new;
592}
593
Stephen Hemminger917e2992009-12-03 19:07:00 +0300594static void
paul718e3742002-12-13 20:15:29 +0000595ospf_area_free (struct ospf_area *area)
596{
paul68980082003-03-25 05:07:42 +0000597 struct route_node *rn;
598 struct ospf_lsa *lsa;
599
paul718e3742002-12-13 20:15:29 +0000600 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000601 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
602 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
603 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
604 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
605 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
606 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
607 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
608 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000609
paul68980082003-03-25 05:07:42 +0000610 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
611 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000612#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000613 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
614 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
615 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
616 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000617#endif /* HAVE_OPAQUE_LSA */
618
619 ospf_lsdb_delete_all (area->lsdb);
620 ospf_lsdb_free (area->lsdb);
621
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000622 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000623
624 route_table_finish (area->ranges);
625 list_delete (area->oiflist);
626
627 if (EXPORT_NAME (area))
628 free (EXPORT_NAME (area));
629
630 if (IMPORT_NAME (area))
631 free (IMPORT_NAME (area));
632
633 /* Cancel timer. */
paul88d6cf32005-10-29 12:50:09 +0000634 OSPF_TIMER_OFF (area->t_stub_router);
635#ifdef HAVE_OPAQUE_LSA
636 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
637#endif /* HAVE_OPAQUE_LSA */
638
paul718e3742002-12-13 20:15:29 +0000639 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000640 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000641
642 XFREE (MTYPE_OSPF_AREA, area);
643}
644
645void
paul68980082003-03-25 05:07:42 +0000646ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000647{
648 struct ospf_area *area;
649
paul68980082003-03-25 05:07:42 +0000650 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000651 if (area &&
652 listcount (area->oiflist) == 0 &&
653 area->ranges->top == NULL &&
654 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
655 area->external_routing == OSPF_AREA_DEFAULT &&
656 area->no_summary == 0 &&
657 area->default_cost == 1 &&
658 EXPORT_NAME (area) == NULL &&
659 IMPORT_NAME (area) == NULL &&
660 area->auth_type == OSPF_AUTH_NULL)
661 {
paul68980082003-03-25 05:07:42 +0000662 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000663 ospf_area_free (area);
664 }
665}
666
667struct ospf_area *
paul68980082003-03-25 05:07:42 +0000668ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000669{
670 struct ospf_area *area;
671
paul68980082003-03-25 05:07:42 +0000672 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000673 if (!area)
674 {
paul68980082003-03-25 05:07:42 +0000675 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000676 area->format = format;
paul68980082003-03-25 05:07:42 +0000677 listnode_add_sort (ospf->areas, area);
678 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000679 }
680
681 return area;
682}
683
684struct ospf_area *
paul68980082003-03-25 05:07:42 +0000685ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000686{
687 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000688 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000689
paul1eb8ef22005-04-07 07:30:20 +0000690 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
691 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
692 return area;
paul718e3742002-12-13 20:15:29 +0000693
694 return NULL;
695}
696
697void
698ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
699{
700 listnode_add (area->oiflist, oi);
701}
702
703void
704ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
705{
706 listnode_delete (area->oiflist, oi);
707}
708
709
710/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000711static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000712ospf_network_new (struct in_addr area_id, int format)
713{
714 struct ospf_network *new;
715 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
716
717 new->area_id = area_id;
718 new->format = format;
719
720 return new;
721}
722
Stephen Hemminger917e2992009-12-03 19:07:00 +0300723static void
paul68980082003-03-25 05:07:42 +0000724ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000725{
paul68980082003-03-25 05:07:42 +0000726 ospf_area_check_free (ospf, network->area_id);
727 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000728 XFREE (MTYPE_OSPF_NETWORK, network);
729}
730
731int
732ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
733 struct in_addr area_id)
734{
735 struct ospf_network *network;
736 struct ospf_area *area;
737 struct route_node *rn;
738 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000739 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000740
741 rn = route_node_get (ospf->networks, (struct prefix *)p);
742 if (rn->info)
743 {
744 /* There is already same network statement. */
745 route_unlock_node (rn);
746 return 0;
747 }
748
749 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000750 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000751
752 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100753 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000754
755 /* Update connected redistribute. */
756 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
757 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
758 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
759 rn; rn = route_next (rn))
760 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000761 if (ospf_external_info_find_lsa (ospf, &ei->p))
762 if (!ospf_distribute_check_connected (ospf, ei))
763 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000764 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000765
paul68980082003-03-25 05:07:42 +0000766 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000767
768 return 1;
769}
770
771int
772ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
773 struct in_addr area_id)
774{
775 struct route_node *rn;
776 struct ospf_network *network;
777 struct external_info *ei;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100778 struct listnode *node, *nnode;
779 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000780
781 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
782 if (rn == NULL)
783 return 0;
784
785 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700786 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000787 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
788 return 0;
789
paul68980082003-03-25 05:07:42 +0000790 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000791 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700792 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000793
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100794 /* Find interfaces that not configured already. */
795 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
796 {
797 int found = 0;
798 struct connected *co = oi->connected;
799
800 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
801 continue;
802
803 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
804 {
805 if (rn->info == NULL)
806 continue;
807
808 if (ospf_network_match_iface(co,&rn->p))
809 {
810 found = 1;
811 route_unlock_node (rn);
812 break;
813 }
814 }
815
816 if (found == 0)
817 ospf_if_free (oi);
818 }
paul718e3742002-12-13 20:15:29 +0000819
820 /* Update connected redistribute. */
821 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
822 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
823 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
824 rn; rn = route_next (rn))
825 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000826 if (!ospf_external_info_find_lsa (ospf, &ei->p))
827 if (ospf_distribute_check_connected (ospf, ei))
828 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000829
830 return 1;
831}
832
paul570f7592003-01-25 06:47:41 +0000833/* Check whether interface matches given network
834 * returns: 1, true. 0, false
835 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300836static int
837ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000838{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000839 /* new approach: more elegant and conceptually clean */
840 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000841}
842
Stephen Hemminger917e2992009-12-03 19:07:00 +0300843static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100844ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
845 struct interface *ifp)
846{
847 struct listnode *cnode;
848 struct connected *co;
849
850 if (memcmp (ifp->name, "VLINK", 5) == 0)
851 return;
852
853 /* if interface prefix is match specified prefix,
854 then create socket and join multicast group. */
855 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
856 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200857
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100858 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
859 continue;
860
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100861 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200862 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100863 && ospf_network_match_iface(co,p))
864 {
865 struct ospf_interface *oi;
866
867 oi = ospf_if_new (area->ospf, ifp, co->address);
868 oi->connected = co;
869
870 oi->area = area;
871
872 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
873 oi->output_cost = ospf_if_get_output_cost (oi);
874
875 /* Add pseudo neighbor. */
876 ospf_nbr_add_self (oi);
877
878 /* Relate ospf interface to ospf instance. */
879 oi->ospf = area->ospf;
880
881 /* update network type as interface flag */
882 /* If network type is specified previously,
883 skip network type setting. */
884 oi->type = IF_DEF_PARAMS (ifp)->type;
885
886 ospf_area_add_if (oi->area, oi);
887
888 /* if router_id is not configured, dont bring up
889 * interfaces.
890 * ospf_router_id_update() will call ospf_if_update
891 * whenever r-id is configured instead.
892 */
893 if ((area->ospf->router_id.s_addr != 0)
894 && if_is_operative (ifp))
895 ospf_if_up (oi);
896 }
897 }
898}
899
Stephen Hemminger917e2992009-12-03 19:07:00 +0300900static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100901ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000902{
903 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000904 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000905
906 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100907 if (area->ospf->router_id.s_addr == 0)
908 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000909
paul718e3742002-12-13 20:15:29 +0000910 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000911 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100912 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000913}
914
915void
916ospf_ls_upd_queue_empty (struct ospf_interface *oi)
917{
918 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000919 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000920 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000921 struct ospf_lsa *lsa;
922
923 /* empty ls update queue */
924 for (rn = route_top (oi->ls_upd_queue); rn;
925 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000926 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000927 {
paul1eb8ef22005-04-07 07:30:20 +0000928 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000929 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000930 list_free (lst);
931 rn->info = NULL;
932 }
933
934 /* remove update event */
935 if (oi->t_ls_upd_event)
936 {
937 thread_cancel (oi->t_ls_upd_event);
938 oi->t_ls_upd_event = NULL;
939 }
940}
941
942void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100943ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000944{
945 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000946 struct ospf_network *network;
947 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100948
949 if (!ospf)
950 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000951
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100952 /* OSPF must be on and Router-ID must be configured. */
953 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100954 return;
955
956 /* Run each netowrk for this interface. */
957 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
958 if (rn->info != NULL)
959 {
960 network = (struct ospf_network *) rn->info;
961 area = ospf_area_get (ospf, network->area_id, network->format);
962 ospf_network_run_interface (&rn->p, area, ifp);
963 }
paul718e3742002-12-13 20:15:29 +0000964}
965
966void
paul68980082003-03-25 05:07:42 +0000967ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000968{
paul1eb8ef22005-04-07 07:30:20 +0000969 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000970 struct ospf_vl_data *vl_data;
971
paul1eb8ef22005-04-07 07:30:20 +0000972 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
973 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
974 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000975}
976
977
Stephen Hemminger7ba82f72009-05-15 10:47:45 -0700978static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +0000979{
980 { OSPF_AREA_DEFAULT, "Default" },
981 { OSPF_AREA_STUB, "Stub" },
982 { OSPF_AREA_NSSA, "NSSA" },
983};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -0700984static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +0000985
paul4dadc292005-05-06 21:37:42 +0000986static void
paul718e3742002-12-13 20:15:29 +0000987ospf_area_type_set (struct ospf_area *area, int type)
988{
hasso52dc7ee2004-09-23 19:18:23 +0000989 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000990 struct ospf_interface *oi;
991
992 if (area->external_routing == type)
993 {
994 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000995 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +0000996 inet_ntoa (area->area_id));
997 return;
998 }
999
1000 area->external_routing = type;
1001
1002 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001003 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001004 LOOKUP (ospf_area_type_msg, type));
1005
1006 switch (area->external_routing)
1007 {
1008 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001009 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1010 if (oi->nbr_self != NULL)
1011 {
1012 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1013 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1014 }
paul718e3742002-12-13 20:15:29 +00001015 break;
1016 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001017 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1018 if (oi->nbr_self != NULL)
1019 {
1020 if (IS_DEBUG_OSPF_EVENT)
1021 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1022 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1023 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1024 if (IS_DEBUG_OSPF_EVENT)
1025 zlog_debug ("options set on %s: %x",
1026 IF_NAME (oi), OPTIONS (oi));
1027 }
paul718e3742002-12-13 20:15:29 +00001028 break;
1029 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001030 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1031 if (oi->nbr_self != NULL)
1032 {
1033 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1034 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1035 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1036 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1037 }
paul718e3742002-12-13 20:15:29 +00001038 break;
1039 default:
1040 break;
1041 }
1042
Paul Jakmac363d382010-01-24 22:42:13 +00001043 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001044 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001045}
1046
1047int
paul68980082003-03-25 05:07:42 +00001048ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001049{
1050 if (area->shortcut_configured == mode)
1051 return 0;
1052
1053 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001054 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001055 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001056
paul68980082003-03-25 05:07:42 +00001057 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001058
1059 return 1;
1060}
1061
1062int
paul68980082003-03-25 05:07:42 +00001063ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001064{
1065 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001066 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001067 ospf_area_check_free (ospf, area->area_id);
1068 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001069
1070 return 1;
1071}
1072
paul4dadc292005-05-06 21:37:42 +00001073static int
paul718e3742002-12-13 20:15:29 +00001074ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1075{
1076 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001077 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001078 int count = 0;
1079
paul1eb8ef22005-04-07 07:30:20 +00001080 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1081 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1082 count++;
paul718e3742002-12-13 20:15:29 +00001083
1084 return count;
1085}
1086
1087int
1088ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1089{
1090 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001091 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001092
paul68980082003-03-25 05:07:42 +00001093 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001094 if (ospf_area_vlink_count (ospf, area))
1095 return 0;
1096
1097 if (area->external_routing != OSPF_AREA_STUB)
1098 ospf_area_type_set (area, OSPF_AREA_STUB);
1099
1100 return 1;
1101}
1102
1103int
1104ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1105{
1106 struct ospf_area *area;
1107
paul68980082003-03-25 05:07:42 +00001108 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001109 if (area == NULL)
1110 return 1;
1111
1112 if (area->external_routing == OSPF_AREA_STUB)
1113 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1114
paul68980082003-03-25 05:07:42 +00001115 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001116
1117 return 1;
1118}
1119
1120int
1121ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1122{
1123 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001124 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001125
paul68980082003-03-25 05:07:42 +00001126 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001127 area->no_summary = 1;
1128
1129 return 1;
1130}
1131
1132int
1133ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1134{
1135 struct ospf_area *area;
1136
paul68980082003-03-25 05:07:42 +00001137 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001138 if (area == NULL)
1139 return 0;
1140
1141 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001142 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001143
1144 return 1;
1145}
1146
1147int
1148ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1149{
1150 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001151 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001152
paul68980082003-03-25 05:07:42 +00001153 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001154 if (ospf_area_vlink_count (ospf, area))
1155 return 0;
1156
1157 if (area->external_routing != OSPF_AREA_NSSA)
1158 {
1159 ospf_area_type_set (area, OSPF_AREA_NSSA);
1160 ospf->anyNSSA++;
1161 }
1162
paul084c7842003-06-22 08:35:18 +00001163 /* set NSSA area defaults */
1164 area->no_summary = 0;
1165 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001166 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001167 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1168
paul718e3742002-12-13 20:15:29 +00001169 return 1;
1170}
1171
1172int
1173ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1174{
1175 struct ospf_area *area;
1176
paul68980082003-03-25 05:07:42 +00001177 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001178 if (area == NULL)
1179 return 0;
1180
1181 if (area->external_routing == OSPF_AREA_NSSA)
1182 {
1183 ospf->anyNSSA--;
1184 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1185 }
1186
paul68980082003-03-25 05:07:42 +00001187 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001188
1189 return 1;
1190}
1191
1192int
1193ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1194 int role)
1195{
1196 struct ospf_area *area;
1197
paul68980082003-03-25 05:07:42 +00001198 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001199 if (area == NULL)
1200 return 0;
1201
paul084c7842003-06-22 08:35:18 +00001202 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001203
1204 return 1;
1205}
1206
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001207#if 0
paul4dadc292005-05-06 21:37:42 +00001208/* XXX: unused? Leave for symmetry? */
1209static int
paul718e3742002-12-13 20:15:29 +00001210ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1211 struct in_addr area_id)
1212{
1213 struct ospf_area *area;
1214
paul68980082003-03-25 05:07:42 +00001215 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001216 if (area == NULL)
1217 return 0;
1218
paul084c7842003-06-22 08:35:18 +00001219 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001220
paul68980082003-03-25 05:07:42 +00001221 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001222
1223 return 1;
1224}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001225#endif
paul718e3742002-12-13 20:15:29 +00001226
1227int
paul68980082003-03-25 05:07:42 +00001228ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001229 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001230{
1231 struct access_list *list;
1232 list = access_list_lookup (AFI_IP, list_name);
1233
1234 EXPORT_LIST (area) = list;
1235
1236 if (EXPORT_NAME (area))
1237 free (EXPORT_NAME (area));
1238
1239 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001240 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001241
1242 return 1;
1243}
1244
1245int
paul68980082003-03-25 05:07:42 +00001246ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001247{
1248
1249 EXPORT_LIST (area) = 0;
1250
1251 if (EXPORT_NAME (area))
1252 free (EXPORT_NAME (area));
1253
1254 EXPORT_NAME (area) = NULL;
1255
paul68980082003-03-25 05:07:42 +00001256 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001257
paul68980082003-03-25 05:07:42 +00001258 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001259
1260 return 1;
1261}
1262
1263int
paul6c835672004-10-11 11:00:30 +00001264ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1265 const char *name)
paul718e3742002-12-13 20:15:29 +00001266{
1267 struct access_list *list;
1268 list = access_list_lookup (AFI_IP, name);
1269
1270 IMPORT_LIST (area) = list;
1271
1272 if (IMPORT_NAME (area))
1273 free (IMPORT_NAME (area));
1274
1275 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001276 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001277
1278 return 1;
1279}
1280
1281int
paul68980082003-03-25 05:07:42 +00001282ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001283{
1284 IMPORT_LIST (area) = 0;
1285
1286 if (IMPORT_NAME (area))
1287 free (IMPORT_NAME (area));
1288
1289 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001290 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001291
paul68980082003-03-25 05:07:42 +00001292 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001293
1294 return 1;
1295}
1296
1297int
paul718e3742002-12-13 20:15:29 +00001298ospf_timers_refresh_set (struct ospf *ospf, int interval)
1299{
1300 int time_left;
1301
1302 if (ospf->lsa_refresh_interval == interval)
1303 return 1;
1304
1305 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001306 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001307
1308 if (time_left > interval)
1309 {
1310 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1311 ospf->t_lsa_refresher =
1312 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1313 }
1314 ospf->lsa_refresh_interval = interval;
1315
1316 return 1;
1317}
1318
1319int
1320ospf_timers_refresh_unset (struct ospf *ospf)
1321{
1322 int time_left;
1323
1324 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001325 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001326
1327 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1328 {
1329 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1330 ospf->t_lsa_refresher =
1331 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1332 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1333 }
1334
1335 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1336
1337 return 1;
1338}
1339
1340
paul4dadc292005-05-06 21:37:42 +00001341static struct ospf_nbr_nbma *
1342ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001343{
1344 struct ospf_nbr_nbma *nbr_nbma;
1345
Stephen Hemminger393deb92008-08-18 14:13:29 -07001346 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001347 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001348
1349 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1350 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1351
1352 return nbr_nbma;
1353}
1354
paul4dadc292005-05-06 21:37:42 +00001355static void
paul718e3742002-12-13 20:15:29 +00001356ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1357{
1358 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1359}
1360
paul4dadc292005-05-06 21:37:42 +00001361static void
paul718e3742002-12-13 20:15:29 +00001362ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1363{
1364 struct route_node *rn;
1365 struct prefix_ipv4 p;
1366
1367 p.family = AF_INET;
1368 p.prefix = nbr_nbma->addr;
1369 p.prefixlen = IPV4_MAX_BITLEN;
1370
1371 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1372 if (rn)
1373 {
1374 ospf_nbr_nbma_free (rn->info);
1375 rn->info = NULL;
1376 route_unlock_node (rn);
1377 route_unlock_node (rn);
1378 }
1379}
1380
paul4dadc292005-05-06 21:37:42 +00001381static void
paul718e3742002-12-13 20:15:29 +00001382ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1383{
1384 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1385
1386 if (nbr_nbma->nbr)
1387 {
1388 nbr_nbma->nbr->nbr_nbma = NULL;
1389 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1390 }
1391
1392 if (nbr_nbma->oi)
1393 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1394}
1395
paul4dadc292005-05-06 21:37:42 +00001396static void
paul718e3742002-12-13 20:15:29 +00001397ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1398 struct ospf_interface *oi)
1399{
1400 struct ospf_neighbor *nbr;
1401 struct route_node *rn;
1402 struct prefix p;
1403
1404 if (oi->type != OSPF_IFTYPE_NBMA)
1405 return;
1406
1407 if (nbr_nbma->nbr != NULL)
1408 return;
1409
1410 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1411 return;
1412
1413 nbr_nbma->oi = oi;
1414 listnode_add (oi->nbr_nbma, nbr_nbma);
1415
1416 /* Get neighbor information from table. */
1417 p.family = AF_INET;
1418 p.prefixlen = IPV4_MAX_BITLEN;
1419 p.u.prefix4 = nbr_nbma->addr;
1420
1421 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1422 if (rn->info)
1423 {
1424 nbr = rn->info;
1425 nbr->nbr_nbma = nbr_nbma;
1426 nbr_nbma->nbr = nbr;
1427
1428 route_unlock_node (rn);
1429 }
1430 else
1431 {
1432 nbr = rn->info = ospf_nbr_new (oi);
1433 nbr->state = NSM_Down;
1434 nbr->src = nbr_nbma->addr;
1435 nbr->nbr_nbma = nbr_nbma;
1436 nbr->priority = nbr_nbma->priority;
1437 nbr->address = p;
1438
1439 nbr_nbma->nbr = nbr;
1440
1441 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1442 }
1443}
1444
1445void
paul68980082003-03-25 05:07:42 +00001446ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001447{
1448 struct ospf_nbr_nbma *nbr_nbma;
1449 struct route_node *rn;
1450 struct prefix_ipv4 p;
1451
1452 if (oi->type != OSPF_IFTYPE_NBMA)
1453 return;
1454
paul68980082003-03-25 05:07:42 +00001455 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001456 if ((nbr_nbma = rn->info))
1457 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1458 {
1459 p.family = AF_INET;
1460 p.prefix = nbr_nbma->addr;
1461 p.prefixlen = IPV4_MAX_BITLEN;
1462
1463 if (prefix_match (oi->address, (struct prefix *)&p))
1464 ospf_nbr_nbma_add (nbr_nbma, oi);
1465 }
1466}
1467
1468struct ospf_nbr_nbma *
1469ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1470{
1471 struct route_node *rn;
1472 struct prefix_ipv4 p;
1473
1474 p.family = AF_INET;
1475 p.prefix = nbr_addr;
1476 p.prefixlen = IPV4_MAX_BITLEN;
1477
1478 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1479 if (rn)
1480 {
1481 route_unlock_node (rn);
1482 return rn->info;
1483 }
1484 return NULL;
1485}
1486
1487struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001488ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001489{
1490#if 0
1491 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001492 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001493#endif
1494
paul68980082003-03-25 05:07:42 +00001495 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001496 return NULL;
1497
1498#if 0
paul1eb8ef22005-04-07 07:30:20 +00001499 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001500 {
paul718e3742002-12-13 20:15:29 +00001501 if (first)
1502 {
1503 *addr = nbr_nbma->addr;
1504 return nbr_nbma;
1505 }
1506 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1507 {
1508 *addr = nbr_nbma->addr;
1509 return nbr_nbma;
1510 }
1511 }
1512#endif
1513 return NULL;
1514}
1515
1516int
1517ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1518{
1519 struct ospf_nbr_nbma *nbr_nbma;
1520 struct ospf_interface *oi;
1521 struct prefix_ipv4 p;
1522 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001523 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001524
1525 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1526 if (nbr_nbma)
1527 return 0;
1528
1529 nbr_nbma = ospf_nbr_nbma_new ();
1530 nbr_nbma->addr = nbr_addr;
1531
1532 p.family = AF_INET;
1533 p.prefix = nbr_addr;
1534 p.prefixlen = IPV4_MAX_BITLEN;
1535
1536 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1537 rn->info = nbr_nbma;
1538
paul1eb8ef22005-04-07 07:30:20 +00001539 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001540 {
paul718e3742002-12-13 20:15:29 +00001541 if (oi->type == OSPF_IFTYPE_NBMA)
1542 if (prefix_match (oi->address, (struct prefix *)&p))
1543 {
1544 ospf_nbr_nbma_add (nbr_nbma, oi);
1545 break;
1546 }
1547 }
1548
1549 return 1;
1550}
1551
1552int
1553ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1554{
1555 struct ospf_nbr_nbma *nbr_nbma;
1556
1557 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1558 if (nbr_nbma == NULL)
1559 return 0;
1560
1561 ospf_nbr_nbma_down (nbr_nbma);
1562 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1563
1564 return 1;
1565}
1566
1567int
1568ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1569 u_char priority)
1570{
1571 struct ospf_nbr_nbma *nbr_nbma;
1572
1573 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1574 if (nbr_nbma == NULL)
1575 return 0;
1576
1577 if (nbr_nbma->priority != priority)
1578 nbr_nbma->priority = priority;
1579
1580 return 1;
1581}
1582
1583int
1584ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1585{
1586 struct ospf_nbr_nbma *nbr_nbma;
1587
1588 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1589 if (nbr_nbma == NULL)
1590 return 0;
1591
1592 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1593 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1594
1595 return 1;
1596}
1597
1598int
1599ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001600 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001601{
1602 struct ospf_nbr_nbma *nbr_nbma;
1603
1604 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1605 if (nbr_nbma == NULL)
1606 return 0;
1607
1608 if (nbr_nbma->v_poll != interval)
1609 {
1610 nbr_nbma->v_poll = interval;
1611 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1612 {
1613 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1614 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1615 nbr_nbma->v_poll);
1616 }
1617 }
1618
1619 return 1;
1620}
1621
1622int
1623ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1624{
1625 struct ospf_nbr_nbma *nbr_nbma;
1626
1627 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1628 if (nbr_nbma == NULL)
1629 return 0;
1630
1631 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1632 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1633
1634 return 1;
1635}
1636
paul718e3742002-12-13 20:15:29 +00001637void
paul020709f2003-04-04 02:44:16 +00001638ospf_master_init ()
1639{
1640 memset (&ospf_master, 0, sizeof (struct ospf_master));
1641
1642 om = &ospf_master;
1643 om->ospf = list_new ();
1644 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001645 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001646}