blob: dd5af5e9a405fb81103423b420cbaee8296149f4 [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"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_zebra.h"
50#include "ospfd/ospf_abr.h"
51#include "ospfd/ospf_flood.h"
52#include "ospfd/ospf_route.h"
53#include "ospfd/ospf_ase.h"
54
paul020709f2003-04-04 02:44:16 +000055
pauledd7c242003-06-04 13:59:38 +000056
paul020709f2003-04-04 02:44:16 +000057/* OSPF process wide configuration. */
58static struct ospf_master ospf_master;
59
60/* OSPF process wide configuration pointer to export. */
61struct ospf_master *om;
paul718e3742002-12-13 20:15:29 +000062
63extern struct zclient *zclient;
hasso18a6dce2004-10-03 18:18:34 +000064extern struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000065
66
paul88d6cf32005-10-29 12:50:09 +000067static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
68static void ospf_network_free (struct ospf *, struct ospf_network *);
69static void ospf_area_free (struct ospf_area *);
70static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
71static void ospf_finish_final (struct ospf *);
paul718e3742002-12-13 20:15:29 +000072
paul718e3742002-12-13 20:15:29 +000073#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
paul88d6cf32005-10-29 12:50:09 +000074
paul718e3742002-12-13 20:15:29 +000075void
paul68980082003-03-25 05:07:42 +000076ospf_router_id_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +000077{
paul718e3742002-12-13 20:15:29 +000078 struct in_addr router_id, router_id_old;
paul1eb8ef22005-04-07 07:30:20 +000079 struct ospf_interface *oi;
hasso52dc7ee2004-09-23 19:18:23 +000080 struct listnode *node;
paul718e3742002-12-13 20:15:29 +000081
82 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +000083 zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +000084
paul68980082003-03-25 05:07:42 +000085 router_id_old = ospf->router_id;
paul718e3742002-12-13 20:15:29 +000086
Andrew J. Schorr16700082006-07-27 22:29:06 +000087 /* Select the router ID based on these priorities:
88 1. Statically assigned router ID is always the first choice.
89 2. If there is no statically assigned router ID, then try to stick
90 with the most recent value, since changing router ID's is very
91 disruptive.
92 3. Last choice: just go with whatever the zebra daemon recommends.
93 */
paul68980082003-03-25 05:07:42 +000094 if (ospf->router_id_static.s_addr != 0)
95 router_id = ospf->router_id_static;
Andrew J. Schorr16700082006-07-27 22:29:06 +000096 else if (ospf->router_id.s_addr != 0)
97 router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +000098 else
hasso18a6dce2004-10-03 18:18:34 +000099 router_id = router_id_zebra;
paul718e3742002-12-13 20:15:29 +0000100
paul68980082003-03-25 05:07:42 +0000101 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000102
103 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000104 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000105
106 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
107 {
paul1eb8ef22005-04-07 07:30:20 +0000108 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
109 /* Update self-neighbor's router_id. */
110 oi->nbr_self->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000111
112 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000113 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000114 {
115 int type;
116 /* Originate each redistributed external route. */
117 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000118 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000119 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000120 ospf, type);
paul718e3742002-12-13 20:15:29 +0000121 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000122 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
Paul Jakma4021b602006-05-12 22:55:41 +0000123 thread_add_event (master, ospf_default_originate_timer, ospf, 0);
paul718e3742002-12-13 20:15:29 +0000124
paul68980082003-03-25 05:07:42 +0000125 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000126 }
127
paul68980082003-03-25 05:07:42 +0000128 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000129 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
paulb29800a2005-11-20 14:50:45 +0000130
131 /* update ospf_interface's */
132 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000133 }
134}
paul718e3742002-12-13 20:15:29 +0000135
136/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000137static int
paul718e3742002-12-13 20:15:29 +0000138ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
139{
140 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
141 return 1;
142 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
143 return -1;
144 return 0;
145}
146
147/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000148static struct ospf *
149ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000150{
151 int i;
152
153 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
154
155 new->router_id.s_addr = htonl (0);
156 new->router_id_static.s_addr = htonl (0);
157
pauld57834f2005-07-12 20:04:22 +0000158 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000159 new->oiflist = list_new ();
160 new->vlinks = list_new ();
161 new->areas = list_new ();
162 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
163 new->networks = route_table_init ();
164 new->nbr_nbma = route_table_init ();
165
166 new->lsdb = ospf_lsdb_new ();
167
168 new->default_originate = DEFAULT_ORIGINATE_NONE;
169
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000170 new->passive_interface_default = OSPF_IF_ACTIVE;
171
paul718e3742002-12-13 20:15:29 +0000172 new->new_external_route = route_table_init ();
173 new->old_external_route = route_table_init ();
174 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000175
176 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000177 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul88d6cf32005-10-29 12:50:09 +0000178
paul718e3742002-12-13 20:15:29 +0000179 /* Distribute parameter init. */
180 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
181 {
182 new->dmetric[i].type = -1;
183 new->dmetric[i].value = -1;
184 }
185 new->default_metric = -1;
186 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
187
188 /* SPF timer value init. */
189 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
190 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000191 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
192 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000193
194 /* MaxAge init. */
195 new->maxage_lsa = list_new ();
196 new->t_maxage_walker =
197 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000198 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000199
200 /* Distance table init. */
201 new->distance_table = route_table_init ();
202
203 new->lsa_refresh_queue.index = 0;
204 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
205 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
206 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000207 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000208
ajs5c333492005-02-23 15:43:01 +0000209 if ((new->fd = ospf_sock_init()) < 0)
210 {
211 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
212 "a socket");
213 exit(1);
214 }
215 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
216 {
217 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
218 OSPF_MAX_PACKET_SIZE+1);
219 exit(1);
220 }
221 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000222 new->oi_write_q = list_new ();
223
224 return new;
225}
226
227struct ospf *
paul020709f2003-04-04 02:44:16 +0000228ospf_lookup ()
229{
230 if (listcount (om->ospf) == 0)
231 return NULL;
232
paul1eb8ef22005-04-07 07:30:20 +0000233 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000234}
235
paul4dadc292005-05-06 21:37:42 +0000236static void
paul020709f2003-04-04 02:44:16 +0000237ospf_add (struct ospf *ospf)
238{
239 listnode_add (om->ospf, ospf);
240}
241
paul4dadc292005-05-06 21:37:42 +0000242static void
paul020709f2003-04-04 02:44:16 +0000243ospf_delete (struct ospf *ospf)
244{
245 listnode_delete (om->ospf, ospf);
246}
247
248struct ospf *
paul718e3742002-12-13 20:15:29 +0000249ospf_get ()
250{
paul020709f2003-04-04 02:44:16 +0000251 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000252
paul020709f2003-04-04 02:44:16 +0000253 ospf = ospf_lookup ();
254 if (ospf == NULL)
255 {
256 ospf = ospf_new ();
257 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000258
paul020709f2003-04-04 02:44:16 +0000259 if (ospf->router_id_static.s_addr == 0)
260 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000261
262#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000263 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000264#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000265 }
paul68980082003-03-25 05:07:42 +0000266
267 return ospf;
paul718e3742002-12-13 20:15:29 +0000268}
paul88d6cf32005-10-29 12:50:09 +0000269
paulc9c93d52005-11-26 13:31:11 +0000270/* Handle the second half of deferred shutdown. This is called either
271 * from the deferred-shutdown timer thread, or directly through
272 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000273 *
274 * Function is to cleanup G-R state, if required then call ospf_finish_final
275 * to complete shutdown of this ospf instance. Possibly exit if the
276 * whole process is being shutdown and this was the last OSPF instance.
277 */
278static void
paulc9c93d52005-11-26 13:31:11 +0000279ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000280{
281 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000282 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000283
284 ospf_finish_final (ospf);
285
286 /* *ospf is now invalid */
287
288 /* ospfd being shut-down? If so, was this the last ospf instance? */
289 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
290 && (listcount (om->ospf) == 0))
291 exit (0);
292
293 return;
294}
295
296/* Timer thread for G-R */
297static int
paulc9c93d52005-11-26 13:31:11 +0000298ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000299{
300 struct ospf *ospf = THREAD_ARG(t);
301
paulc9c93d52005-11-26 13:31:11 +0000302 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000303
304 return 0;
305}
306
paulc9c93d52005-11-26 13:31:11 +0000307/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000308 * down directly into second-half of instance shutdown.
309 */
310static void
paulc9c93d52005-11-26 13:31:11 +0000311ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000312{
313 unsigned long timeout;
314 struct listnode *ln;
315 struct ospf_area *area;
316
paulc9c93d52005-11-26 13:31:11 +0000317 /* deferred shutdown already running? */
318 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000319 return;
320
321 /* Should we try push out max-metric LSAs? */
322 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
323 {
324 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
325 {
326 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
327
328 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
329 ospf_router_lsa_timer_add (area);
330 }
331 timeout = ospf->stub_router_shutdown_time;
332 }
333 else
paulc9c93d52005-11-26 13:31:11 +0000334 {
335 /* No timer needed */
336 ospf_deferred_shutdown_finish (ospf);
337 return;
338 }
paul88d6cf32005-10-29 12:50:09 +0000339
paulc9c93d52005-11-26 13:31:11 +0000340 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000341 timeout);
342 return;
343}
344
345/* Shut down the entire process */
346void
347ospf_terminate (void)
348{
349 struct ospf *ospf;
350 struct listnode *node, *nnode;
351
352 /* shutdown already in progress */
353 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
354 return;
355
356 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
357
358 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
359 ospf_finish (ospf);
360
361 /* Deliberately go back up, hopefully to thread scheduler, as
362 * One or more ospf_finish()'s may have deferred shutdown to a timer
363 * thread
364 */
365}
paul718e3742002-12-13 20:15:29 +0000366
367void
368ospf_finish (struct ospf *ospf)
369{
paulc9c93d52005-11-26 13:31:11 +0000370 /* let deferred shutdown decide */
371 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000372
paulc9c93d52005-11-26 13:31:11 +0000373 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000374 * deferred to expiry of G-S timer thread. Return back up, hopefully
375 * to thread scheduler.
376 */
paulc9c93d52005-11-26 13:31:11 +0000377 return;
paul88d6cf32005-10-29 12:50:09 +0000378}
379
380/* Final cleanup of ospf instance */
381static void
382ospf_finish_final (struct ospf *ospf)
383{
paul718e3742002-12-13 20:15:29 +0000384 struct route_node *rn;
385 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000386 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000387 struct ospf_interface *oi;
388 struct ospf_area *area;
389 struct ospf_vl_data *vl_data;
390 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000391 int i;
392
393#ifdef HAVE_OPAQUE_LSA
394 ospf_opaque_type11_lsa_term (ospf);
395#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000396
397 /* be nice if this worked, but it doesn't */
398 /*ospf_flush_self_originated_lsas_now (ospf);*/
399
400 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000401 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000402 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000403 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000404
paul1eb8ef22005-04-07 07:30:20 +0000405 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
406 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000407
paul1eb8ef22005-04-07 07:30:20 +0000408 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
409 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000410
411 list_delete (ospf->vlinks);
412
413 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000414 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
415 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000416
417 /* Clear static neighbors */
418 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
419 if ((nbr_nbma = rn->info))
420 {
421 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
422
423 if (nbr_nbma->nbr)
424 {
425 nbr_nbma->nbr->nbr_nbma = NULL;
426 nbr_nbma->nbr = NULL;
427 }
428
429 if (nbr_nbma->oi)
430 {
431 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
432 nbr_nbma->oi = NULL;
433 }
434
435 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
436 }
437
438 route_table_finish (ospf->nbr_nbma);
439
440 /* Clear networks and Areas. */
441 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
442 {
443 struct ospf_network *network;
444
445 if ((network = rn->info) != NULL)
446 {
paul68980082003-03-25 05:07:42 +0000447 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000448 rn->info = NULL;
449 route_unlock_node (rn);
450 }
451 }
452
paul1eb8ef22005-04-07 07:30:20 +0000453 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000454 {
paul718e3742002-12-13 20:15:29 +0000455 listnode_delete (ospf->areas, area);
456 ospf_area_free (area);
457 }
458
459 /* Cancel all timers. */
460 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000461 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
462 OSPF_TIMER_OFF (ospf->t_spf_calc);
463 OSPF_TIMER_OFF (ospf->t_ase_calc);
464 OSPF_TIMER_OFF (ospf->t_maxage);
465 OSPF_TIMER_OFF (ospf->t_maxage_walker);
466 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000467 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000468 OSPF_TIMER_OFF (ospf->t_distribute_update);
469 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
470 OSPF_TIMER_OFF (ospf->t_read);
471 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000472#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000473 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000474#endif
paul718e3742002-12-13 20:15:29 +0000475
476 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000477 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000478
479#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000480 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
481 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000482#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000483 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
484 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
485
paul718e3742002-12-13 20:15:29 +0000486 ospf_lsdb_delete_all (ospf->lsdb);
487 ospf_lsdb_free (ospf->lsdb);
488
paul1eb8ef22005-04-07 07:30:20 +0000489 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000490 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +0000491
492 list_delete (ospf->maxage_lsa);
493
494 if (ospf->old_table)
495 ospf_route_table_free (ospf->old_table);
496 if (ospf->new_table)
497 {
498 ospf_route_delete (ospf->new_table);
499 ospf_route_table_free (ospf->new_table);
500 }
501 if (ospf->old_rtrs)
502 ospf_rtrs_free (ospf->old_rtrs);
503 if (ospf->new_rtrs)
504 ospf_rtrs_free (ospf->new_rtrs);
505 if (ospf->new_external_route)
506 {
507 ospf_route_delete (ospf->new_external_route);
508 ospf_route_table_free (ospf->new_external_route);
509 }
510 if (ospf->old_external_route)
511 {
512 ospf_route_delete (ospf->old_external_route);
513 ospf_route_table_free (ospf->old_external_route);
514 }
515 if (ospf->external_lsas)
516 {
517 ospf_ase_external_lsas_finish (ospf->external_lsas);
518 }
519
520 list_delete (ospf->areas);
521
522 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
523 if (EXTERNAL_INFO (i) != NULL)
524 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
525 {
526 if (rn->info == NULL)
527 continue;
528
529 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
530 rn->info = NULL;
531 route_unlock_node (rn);
532 }
533
paul68980082003-03-25 05:07:42 +0000534 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000535 route_table_finish (ospf->distance_table);
536
paul020709f2003-04-04 02:44:16 +0000537 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000538
paul020709f2003-04-04 02:44:16 +0000539 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000540}
541
542
543/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000544static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000545ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000546{
547 struct ospf_area *new;
548
549 /* Allocate new config_network. */
550 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
551
paul68980082003-03-25 05:07:42 +0000552 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000553
554 new->area_id = area_id;
555
556 new->external_routing = OSPF_AREA_DEFAULT;
557 new->default_cost = 1;
558 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000559
paul718e3742002-12-13 20:15:29 +0000560 /* New LSDB init. */
561 new->lsdb = ospf_lsdb_new ();
562
563 /* Self-originated LSAs initialize. */
564 new->router_lsa_self = NULL;
565
566#ifdef HAVE_OPAQUE_LSA
567 ospf_opaque_type10_lsa_init (new);
568#endif /* HAVE_OPAQUE_LSA */
569
570 new->oiflist = list_new ();
571 new->ranges = route_table_init ();
572
573 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000574 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000575
576 return new;
577}
578
579void
580ospf_area_free (struct ospf_area *area)
581{
paul68980082003-03-25 05:07:42 +0000582 struct route_node *rn;
583 struct ospf_lsa *lsa;
584
paul718e3742002-12-13 20:15:29 +0000585 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000586 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
587 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
588 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
589 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
590 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
591 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
592 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
593 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000594
paul68980082003-03-25 05:07:42 +0000595 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
596 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000597#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000598 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
599 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
600 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
601 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000602#endif /* HAVE_OPAQUE_LSA */
603
604 ospf_lsdb_delete_all (area->lsdb);
605 ospf_lsdb_free (area->lsdb);
606
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000607 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000608
609 route_table_finish (area->ranges);
610 list_delete (area->oiflist);
611
612 if (EXPORT_NAME (area))
613 free (EXPORT_NAME (area));
614
615 if (IMPORT_NAME (area))
616 free (IMPORT_NAME (area));
617
618 /* Cancel timer. */
619 OSPF_TIMER_OFF (area->t_router_lsa_self);
paul88d6cf32005-10-29 12:50:09 +0000620 OSPF_TIMER_OFF (area->t_stub_router);
621#ifdef HAVE_OPAQUE_LSA
622 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
623#endif /* HAVE_OPAQUE_LSA */
624
paul718e3742002-12-13 20:15:29 +0000625 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000626 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000627
628 XFREE (MTYPE_OSPF_AREA, area);
629}
630
631void
paul68980082003-03-25 05:07:42 +0000632ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000633{
634 struct ospf_area *area;
635
paul68980082003-03-25 05:07:42 +0000636 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000637 if (area &&
638 listcount (area->oiflist) == 0 &&
639 area->ranges->top == NULL &&
640 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
641 area->external_routing == OSPF_AREA_DEFAULT &&
642 area->no_summary == 0 &&
643 area->default_cost == 1 &&
644 EXPORT_NAME (area) == NULL &&
645 IMPORT_NAME (area) == NULL &&
646 area->auth_type == OSPF_AUTH_NULL)
647 {
paul68980082003-03-25 05:07:42 +0000648 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000649 ospf_area_free (area);
650 }
651}
652
653struct ospf_area *
paul68980082003-03-25 05:07:42 +0000654ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000655{
656 struct ospf_area *area;
657
paul68980082003-03-25 05:07:42 +0000658 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000659 if (!area)
660 {
paul68980082003-03-25 05:07:42 +0000661 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000662 area->format = format;
paul68980082003-03-25 05:07:42 +0000663 listnode_add_sort (ospf->areas, area);
664 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000665 }
666
667 return area;
668}
669
670struct ospf_area *
paul68980082003-03-25 05:07:42 +0000671ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000672{
673 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000674 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000675
paul1eb8ef22005-04-07 07:30:20 +0000676 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
677 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
678 return area;
paul718e3742002-12-13 20:15:29 +0000679
680 return NULL;
681}
682
683void
684ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
685{
686 listnode_add (area->oiflist, oi);
687}
688
689void
690ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
691{
692 listnode_delete (area->oiflist, oi);
693}
694
695
696/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000697static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000698ospf_network_new (struct in_addr area_id, int format)
699{
700 struct ospf_network *new;
701 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
702
703 new->area_id = area_id;
704 new->format = format;
705
706 return new;
707}
708
709void
paul68980082003-03-25 05:07:42 +0000710ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000711{
paul68980082003-03-25 05:07:42 +0000712 ospf_area_check_free (ospf, network->area_id);
713 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000714 XFREE (MTYPE_OSPF_NETWORK, network);
715}
716
717int
718ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
719 struct in_addr area_id)
720{
721 struct ospf_network *network;
722 struct ospf_area *area;
723 struct route_node *rn;
724 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000725 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000726
727 rn = route_node_get (ospf->networks, (struct prefix *)p);
728 if (rn->info)
729 {
730 /* There is already same network statement. */
731 route_unlock_node (rn);
732 return 0;
733 }
734
735 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000736 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000737
738 /* Run network config now. */
739 ospf_network_run (ospf, (struct prefix *)p, area);
740
741 /* Update connected redistribute. */
742 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
743 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
744 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
745 rn; rn = route_next (rn))
746 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000747 if (ospf_external_info_find_lsa (ospf, &ei->p))
748 if (!ospf_distribute_check_connected (ospf, ei))
749 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000750 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000751
paul68980082003-03-25 05:07:42 +0000752 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000753
754 return 1;
755}
756
757int
758ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
759 struct in_addr area_id)
760{
761 struct route_node *rn;
762 struct ospf_network *network;
763 struct external_info *ei;
764
765 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
766 if (rn == NULL)
767 return 0;
768
769 network = rn->info;
770 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
771 return 0;
772
paul68980082003-03-25 05:07:42 +0000773 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000774 rn->info = NULL;
775 route_unlock_node (rn);
776
paul68980082003-03-25 05:07:42 +0000777 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000778
779 /* Update connected redistribute. */
780 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
781 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
782 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
783 rn; rn = route_next (rn))
784 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000785 if (!ospf_external_info_find_lsa (ospf, &ei->p))
786 if (ospf_distribute_check_connected (ospf, ei))
787 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000788
789 return 1;
790}
791
paul570f7592003-01-25 06:47:41 +0000792/* Check whether interface matches given network
793 * returns: 1, true. 0, false
794 */
795int
796ospf_network_match_iface(struct connected *co, struct prefix *net)
797{
798 /* Behaviour to match both Cisco where:
799 * iface address lies within network specified -> ospf
800 * and zebra 0.9[2ish-3]:
801 * PtP special case: network specified == iface peer addr -> ospf
802 */
gdt8f40e892003-12-05 14:01:43 +0000803
paulf3ae74c2004-11-04 20:35:31 +0000804 /* For PtP, match if peer address matches network address exactly.
805 * This can be addr/32 or addr/p for p < 32, but the addr must match
806 * exactly; this is not a test for falling within the prefix. This
gdt8f40e892003-12-05 14:01:43 +0000807 * test is solely for compatibility with zebra.
gdt8f40e892003-12-05 14:01:43 +0000808 */
paulf3ae74c2004-11-04 20:35:31 +0000809 if (if_is_pointopoint (co->ifp) && co->destination &&
810 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
811 return 1;
812
813#if 0
814 /* Decline to accept PtP if dst address does not match the
815 * prefix. (ifdefed out because this is a workaround, not the
816 * desired behavior.) */
817 if (if_is_pointopoint (co->ifp) &&
818 ! prefix_match (net, co->destination))
819 return 0;
820#endif
821
822 /* If the address is within the prefix, accept. Note that this
823 * applies to PtP as well as other types.
824 */
825 if (prefix_match (net, co->address))
826 return 1;
827
828 return 0; /* no match */
paul570f7592003-01-25 06:47:41 +0000829}
830
paul718e3742002-12-13 20:15:29 +0000831void
832ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
833{
834 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000835 struct connected *co;
hasso52dc7ee2004-09-23 19:18:23 +0000836 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000837
838 /* Schedule Router ID Update. */
paul86752842006-01-10 20:34:46 +0000839 if (ospf->router_id.s_addr == 0)
paulb29800a2005-11-20 14:50:45 +0000840 ospf_router_id_update (ospf);
841
paul718e3742002-12-13 20:15:29 +0000842 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000843 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000844 {
paul1eb8ef22005-04-07 07:30:20 +0000845 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000846
paul718e3742002-12-13 20:15:29 +0000847 if (memcmp (ifp->name, "VLINK", 5) == 0)
848 continue;
849
850 /* if interface prefix is match specified prefix,
851 then create socket and join multicast group. */
paul1eb8ef22005-04-07 07:30:20 +0000852 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
paul718e3742002-12-13 20:15:29 +0000853 {
paul718e3742002-12-13 20:15:29 +0000854 struct prefix *addr;
paul800dc102003-03-28 01:51:40 +0000855
paule7b050c2003-04-07 06:38:02 +0000856 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
857 continue;
paul718e3742002-12-13 20:15:29 +0000858
hasso3fb9cd62004-10-19 19:44:43 +0000859 if (CONNECTED_POINTOPOINT_HOST(co))
paul718e3742002-12-13 20:15:29 +0000860 addr = co->destination;
861 else
862 addr = co->address;
863
paulcb3f37d2003-02-18 23:26:37 +0000864 if (p->family == co->address->family
paul68980082003-03-25 05:07:42 +0000865 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
paulcb3f37d2003-02-18 23:26:37 +0000866 && ospf_network_match_iface(co,p))
paul570f7592003-01-25 06:47:41 +0000867 {
paul1eb8ef22005-04-07 07:30:20 +0000868 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000869
paul68980082003-03-25 05:07:42 +0000870 oi = ospf_if_new (ospf, ifp, co->address);
paul718e3742002-12-13 20:15:29 +0000871 oi->connected = co;
872
paul718e3742002-12-13 20:15:29 +0000873 oi->area = area;
874
875 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
876 oi->output_cost = ospf_if_get_output_cost (oi);
877
paul718e3742002-12-13 20:15:29 +0000878 /* Add pseudo neighbor. */
879 ospf_nbr_add_self (oi);
880
paul718e3742002-12-13 20:15:29 +0000881 /* Relate ospf interface to ospf instance. */
paul68980082003-03-25 05:07:42 +0000882 oi->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000883
884 /* update network type as interface flag */
885 /* If network type is specified previously,
886 skip network type setting. */
887 oi->type = IF_DEF_PARAMS (ifp)->type;
888
paul718e3742002-12-13 20:15:29 +0000889 ospf_area_add_if (oi->area, oi);
paulb29800a2005-11-20 14:50:45 +0000890
891 /* if router_id is not configured, dont bring up
892 * interfaces.
893 * ospf_router_id_update() will call ospf_if_update
894 * whenever r-id is configured instead.
895 */
paul86752842006-01-10 20:34:46 +0000896 if ((ospf->router_id.s_addr != 0)
paulb29800a2005-11-20 14:50:45 +0000897 && if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000898 ospf_if_up (oi);
paul718e3742002-12-13 20:15:29 +0000899 }
900 }
901 }
902}
903
904void
905ospf_ls_upd_queue_empty (struct ospf_interface *oi)
906{
907 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000908 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000909 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000910 struct ospf_lsa *lsa;
911
912 /* empty ls update queue */
913 for (rn = route_top (oi->ls_upd_queue); rn;
914 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000915 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000916 {
paul1eb8ef22005-04-07 07:30:20 +0000917 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000918 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000919 list_free (lst);
920 rn->info = NULL;
921 }
922
923 /* remove update event */
924 if (oi->t_ls_upd_event)
925 {
926 thread_cancel (oi->t_ls_upd_event);
927 oi->t_ls_upd_event = NULL;
928 }
929}
930
931void
paul68980082003-03-25 05:07:42 +0000932ospf_if_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000933{
934 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000935 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000936 struct ospf_network *network;
937 struct ospf_area *area;
paul1eb8ef22005-04-07 07:30:20 +0000938 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000939
paul68980082003-03-25 05:07:42 +0000940 if (ospf != NULL)
paul718e3742002-12-13 20:15:29 +0000941 {
paulb29800a2005-11-20 14:50:45 +0000942 /* Router-ID must be configured. */
paul86752842006-01-10 20:34:46 +0000943 if (ospf->router_id.s_addr == 0)
paulb29800a2005-11-20 14:50:45 +0000944 return;
945
paul718e3742002-12-13 20:15:29 +0000946 /* Find interfaces that not configured already. */
paul1eb8ef22005-04-07 07:30:20 +0000947 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +0000948 {
949 int found = 0;
paul718e3742002-12-13 20:15:29 +0000950 struct connected *co = oi->connected;
951
paul718e3742002-12-13 20:15:29 +0000952 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
953 continue;
954
paul68980082003-03-25 05:07:42 +0000955 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000956 {
957 if (rn->info == NULL)
958 continue;
959
paul570f7592003-01-25 06:47:41 +0000960 if (ospf_network_match_iface(co,&rn->p))
paul718e3742002-12-13 20:15:29 +0000961 {
962 found = 1;
963 route_unlock_node (rn);
964 break;
965 }
966 }
967
968 if (found == 0)
969 ospf_if_free (oi);
970 }
971
972 /* Run each interface. */
paul68980082003-03-25 05:07:42 +0000973 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000974 if (rn->info != NULL)
975 {
976 network = (struct ospf_network *) rn->info;
paul68980082003-03-25 05:07:42 +0000977 area = ospf_area_get (ospf, network->area_id, network->format);
978 ospf_network_run (ospf, &rn->p, area);
paul718e3742002-12-13 20:15:29 +0000979 }
980 }
981}
982
983void
paul68980082003-03-25 05:07:42 +0000984ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000985{
paul1eb8ef22005-04-07 07:30:20 +0000986 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000987 struct ospf_vl_data *vl_data;
988
paul1eb8ef22005-04-07 07:30:20 +0000989 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
990 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
991 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000992}
993
994
995struct message ospf_area_type_msg[] =
996{
997 { OSPF_AREA_DEFAULT, "Default" },
998 { OSPF_AREA_STUB, "Stub" },
999 { OSPF_AREA_NSSA, "NSSA" },
1000};
1001int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
1002
paul4dadc292005-05-06 21:37:42 +00001003static void
paul718e3742002-12-13 20:15:29 +00001004ospf_area_type_set (struct ospf_area *area, int type)
1005{
hasso52dc7ee2004-09-23 19:18:23 +00001006 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001007 struct ospf_interface *oi;
1008
1009 if (area->external_routing == type)
1010 {
1011 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001012 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001013 inet_ntoa (area->area_id));
1014 return;
1015 }
1016
1017 area->external_routing = type;
1018
1019 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001020 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001021 LOOKUP (ospf_area_type_msg, type));
1022
1023 switch (area->external_routing)
1024 {
1025 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001026 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1027 if (oi->nbr_self != NULL)
1028 {
1029 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1030 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1031 }
paul718e3742002-12-13 20:15:29 +00001032 break;
1033 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001034 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1035 if (oi->nbr_self != NULL)
1036 {
1037 if (IS_DEBUG_OSPF_EVENT)
1038 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1039 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1040 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1041 if (IS_DEBUG_OSPF_EVENT)
1042 zlog_debug ("options set on %s: %x",
1043 IF_NAME (oi), OPTIONS (oi));
1044 }
paul718e3742002-12-13 20:15:29 +00001045 break;
1046 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001047 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1048 if (oi->nbr_self != NULL)
1049 {
1050 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1051 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1052 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1053 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1054 }
paul718e3742002-12-13 20:15:29 +00001055 break;
1056 default:
1057 break;
1058 }
1059
1060 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001061 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001062}
1063
1064int
paul68980082003-03-25 05:07:42 +00001065ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001066{
1067 if (area->shortcut_configured == mode)
1068 return 0;
1069
1070 area->shortcut_configured = mode;
1071 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001072 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001073
paul68980082003-03-25 05:07:42 +00001074 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001075
1076 return 1;
1077}
1078
1079int
paul68980082003-03-25 05:07:42 +00001080ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001081{
1082 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1083 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001084 ospf_area_check_free (ospf, area->area_id);
1085 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001086
1087 return 1;
1088}
1089
paul4dadc292005-05-06 21:37:42 +00001090static int
paul718e3742002-12-13 20:15:29 +00001091ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1092{
1093 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001094 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001095 int count = 0;
1096
paul1eb8ef22005-04-07 07:30:20 +00001097 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1098 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1099 count++;
paul718e3742002-12-13 20:15:29 +00001100
1101 return count;
1102}
1103
1104int
1105ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1106{
1107 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001108 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001109
paul68980082003-03-25 05:07:42 +00001110 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001111 if (ospf_area_vlink_count (ospf, area))
1112 return 0;
1113
1114 if (area->external_routing != OSPF_AREA_STUB)
1115 ospf_area_type_set (area, OSPF_AREA_STUB);
1116
1117 return 1;
1118}
1119
1120int
1121ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1122{
1123 struct ospf_area *area;
1124
paul68980082003-03-25 05:07:42 +00001125 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001126 if (area == NULL)
1127 return 1;
1128
1129 if (area->external_routing == OSPF_AREA_STUB)
1130 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1131
paul68980082003-03-25 05:07:42 +00001132 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001133
1134 return 1;
1135}
1136
1137int
1138ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1139{
1140 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001141 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001142
paul68980082003-03-25 05:07:42 +00001143 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001144 area->no_summary = 1;
1145
1146 return 1;
1147}
1148
1149int
1150ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1151{
1152 struct ospf_area *area;
1153
paul68980082003-03-25 05:07:42 +00001154 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001155 if (area == NULL)
1156 return 0;
1157
1158 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001159 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001160
1161 return 1;
1162}
1163
1164int
1165ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1166{
1167 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001168 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001169
paul68980082003-03-25 05:07:42 +00001170 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001171 if (ospf_area_vlink_count (ospf, area))
1172 return 0;
1173
1174 if (area->external_routing != OSPF_AREA_NSSA)
1175 {
1176 ospf_area_type_set (area, OSPF_AREA_NSSA);
1177 ospf->anyNSSA++;
1178 }
1179
paul084c7842003-06-22 08:35:18 +00001180 /* set NSSA area defaults */
1181 area->no_summary = 0;
1182 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001183 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001184 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1185
paul718e3742002-12-13 20:15:29 +00001186 return 1;
1187}
1188
1189int
1190ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1191{
1192 struct ospf_area *area;
1193
paul68980082003-03-25 05:07:42 +00001194 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001195 if (area == NULL)
1196 return 0;
1197
1198 if (area->external_routing == OSPF_AREA_NSSA)
1199 {
1200 ospf->anyNSSA--;
1201 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1202 }
1203
paul68980082003-03-25 05:07:42 +00001204 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001205
1206 return 1;
1207}
1208
1209int
1210ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1211 int role)
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 = role;
paul718e3742002-12-13 20:15:29 +00001220
1221 return 1;
1222}
1223
paul4dadc292005-05-06 21:37:42 +00001224/* XXX: unused? Leave for symmetry? */
1225static int
paul718e3742002-12-13 20:15:29 +00001226ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1227 struct in_addr area_id)
1228{
1229 struct ospf_area *area;
1230
paul68980082003-03-25 05:07:42 +00001231 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001232 if (area == NULL)
1233 return 0;
1234
paul084c7842003-06-22 08:35:18 +00001235 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001236
paul68980082003-03-25 05:07:42 +00001237 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001238
1239 return 1;
1240}
1241
1242int
paul68980082003-03-25 05:07:42 +00001243ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001244 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001245{
1246 struct access_list *list;
1247 list = access_list_lookup (AFI_IP, list_name);
1248
1249 EXPORT_LIST (area) = list;
1250
1251 if (EXPORT_NAME (area))
1252 free (EXPORT_NAME (area));
1253
1254 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001255 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001256
1257 return 1;
1258}
1259
1260int
paul68980082003-03-25 05:07:42 +00001261ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001262{
1263
1264 EXPORT_LIST (area) = 0;
1265
1266 if (EXPORT_NAME (area))
1267 free (EXPORT_NAME (area));
1268
1269 EXPORT_NAME (area) = NULL;
1270
paul68980082003-03-25 05:07:42 +00001271 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001272
paul68980082003-03-25 05:07:42 +00001273 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001274
1275 return 1;
1276}
1277
1278int
paul6c835672004-10-11 11:00:30 +00001279ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1280 const char *name)
paul718e3742002-12-13 20:15:29 +00001281{
1282 struct access_list *list;
1283 list = access_list_lookup (AFI_IP, name);
1284
1285 IMPORT_LIST (area) = list;
1286
1287 if (IMPORT_NAME (area))
1288 free (IMPORT_NAME (area));
1289
1290 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001291 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001292
1293 return 1;
1294}
1295
1296int
paul68980082003-03-25 05:07:42 +00001297ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001298{
1299 IMPORT_LIST (area) = 0;
1300
1301 if (IMPORT_NAME (area))
1302 free (IMPORT_NAME (area));
1303
1304 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001305 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001306
paul68980082003-03-25 05:07:42 +00001307 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001308
1309 return 1;
1310}
1311
1312int
paul718e3742002-12-13 20:15:29 +00001313ospf_timers_refresh_set (struct ospf *ospf, int interval)
1314{
1315 int time_left;
1316
1317 if (ospf->lsa_refresh_interval == interval)
1318 return 1;
1319
1320 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001321 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001322
1323 if (time_left > interval)
1324 {
1325 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1326 ospf->t_lsa_refresher =
1327 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1328 }
1329 ospf->lsa_refresh_interval = interval;
1330
1331 return 1;
1332}
1333
1334int
1335ospf_timers_refresh_unset (struct ospf *ospf)
1336{
1337 int time_left;
1338
1339 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001340 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001341
1342 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1343 {
1344 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1345 ospf->t_lsa_refresher =
1346 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1347 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1348 }
1349
1350 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1351
1352 return 1;
1353}
1354
1355
paul4dadc292005-05-06 21:37:42 +00001356static struct ospf_nbr_nbma *
1357ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001358{
1359 struct ospf_nbr_nbma *nbr_nbma;
1360
1361 nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1362 sizeof (struct ospf_nbr_nbma));
1363 memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));
1364
1365 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1366 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1367
1368 return nbr_nbma;
1369}
1370
paul4dadc292005-05-06 21:37:42 +00001371static void
paul718e3742002-12-13 20:15:29 +00001372ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1373{
1374 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1375}
1376
paul4dadc292005-05-06 21:37:42 +00001377static void
paul718e3742002-12-13 20:15:29 +00001378ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1379{
1380 struct route_node *rn;
1381 struct prefix_ipv4 p;
1382
1383 p.family = AF_INET;
1384 p.prefix = nbr_nbma->addr;
1385 p.prefixlen = IPV4_MAX_BITLEN;
1386
1387 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1388 if (rn)
1389 {
1390 ospf_nbr_nbma_free (rn->info);
1391 rn->info = NULL;
1392 route_unlock_node (rn);
1393 route_unlock_node (rn);
1394 }
1395}
1396
paul4dadc292005-05-06 21:37:42 +00001397static void
paul718e3742002-12-13 20:15:29 +00001398ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1399{
1400 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1401
1402 if (nbr_nbma->nbr)
1403 {
1404 nbr_nbma->nbr->nbr_nbma = NULL;
1405 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1406 }
1407
1408 if (nbr_nbma->oi)
1409 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1410}
1411
paul4dadc292005-05-06 21:37:42 +00001412static void
paul718e3742002-12-13 20:15:29 +00001413ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1414 struct ospf_interface *oi)
1415{
1416 struct ospf_neighbor *nbr;
1417 struct route_node *rn;
1418 struct prefix p;
1419
1420 if (oi->type != OSPF_IFTYPE_NBMA)
1421 return;
1422
1423 if (nbr_nbma->nbr != NULL)
1424 return;
1425
1426 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1427 return;
1428
1429 nbr_nbma->oi = oi;
1430 listnode_add (oi->nbr_nbma, nbr_nbma);
1431
1432 /* Get neighbor information from table. */
1433 p.family = AF_INET;
1434 p.prefixlen = IPV4_MAX_BITLEN;
1435 p.u.prefix4 = nbr_nbma->addr;
1436
1437 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1438 if (rn->info)
1439 {
1440 nbr = rn->info;
1441 nbr->nbr_nbma = nbr_nbma;
1442 nbr_nbma->nbr = nbr;
1443
1444 route_unlock_node (rn);
1445 }
1446 else
1447 {
1448 nbr = rn->info = ospf_nbr_new (oi);
1449 nbr->state = NSM_Down;
1450 nbr->src = nbr_nbma->addr;
1451 nbr->nbr_nbma = nbr_nbma;
1452 nbr->priority = nbr_nbma->priority;
1453 nbr->address = p;
1454
1455 nbr_nbma->nbr = nbr;
1456
1457 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1458 }
1459}
1460
1461void
paul68980082003-03-25 05:07:42 +00001462ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001463{
1464 struct ospf_nbr_nbma *nbr_nbma;
1465 struct route_node *rn;
1466 struct prefix_ipv4 p;
1467
1468 if (oi->type != OSPF_IFTYPE_NBMA)
1469 return;
1470
paul68980082003-03-25 05:07:42 +00001471 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001472 if ((nbr_nbma = rn->info))
1473 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1474 {
1475 p.family = AF_INET;
1476 p.prefix = nbr_nbma->addr;
1477 p.prefixlen = IPV4_MAX_BITLEN;
1478
1479 if (prefix_match (oi->address, (struct prefix *)&p))
1480 ospf_nbr_nbma_add (nbr_nbma, oi);
1481 }
1482}
1483
1484struct ospf_nbr_nbma *
1485ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1486{
1487 struct route_node *rn;
1488 struct prefix_ipv4 p;
1489
1490 p.family = AF_INET;
1491 p.prefix = nbr_addr;
1492 p.prefixlen = IPV4_MAX_BITLEN;
1493
1494 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1495 if (rn)
1496 {
1497 route_unlock_node (rn);
1498 return rn->info;
1499 }
1500 return NULL;
1501}
1502
1503struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001504ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001505{
1506#if 0
1507 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001508 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001509#endif
1510
paul68980082003-03-25 05:07:42 +00001511 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001512 return NULL;
1513
1514#if 0
paul1eb8ef22005-04-07 07:30:20 +00001515 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001516 {
paul718e3742002-12-13 20:15:29 +00001517 if (first)
1518 {
1519 *addr = nbr_nbma->addr;
1520 return nbr_nbma;
1521 }
1522 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1523 {
1524 *addr = nbr_nbma->addr;
1525 return nbr_nbma;
1526 }
1527 }
1528#endif
1529 return NULL;
1530}
1531
1532int
1533ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1534{
1535 struct ospf_nbr_nbma *nbr_nbma;
1536 struct ospf_interface *oi;
1537 struct prefix_ipv4 p;
1538 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001539 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001540
1541 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1542 if (nbr_nbma)
1543 return 0;
1544
1545 nbr_nbma = ospf_nbr_nbma_new ();
1546 nbr_nbma->addr = nbr_addr;
1547
1548 p.family = AF_INET;
1549 p.prefix = nbr_addr;
1550 p.prefixlen = IPV4_MAX_BITLEN;
1551
1552 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1553 rn->info = nbr_nbma;
1554
paul1eb8ef22005-04-07 07:30:20 +00001555 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001556 {
paul718e3742002-12-13 20:15:29 +00001557 if (oi->type == OSPF_IFTYPE_NBMA)
1558 if (prefix_match (oi->address, (struct prefix *)&p))
1559 {
1560 ospf_nbr_nbma_add (nbr_nbma, oi);
1561 break;
1562 }
1563 }
1564
1565 return 1;
1566}
1567
1568int
1569ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
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 ospf_nbr_nbma_down (nbr_nbma);
1578 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1579
1580 return 1;
1581}
1582
1583int
1584ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1585 u_char priority)
1586{
1587 struct ospf_nbr_nbma *nbr_nbma;
1588
1589 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1590 if (nbr_nbma == NULL)
1591 return 0;
1592
1593 if (nbr_nbma->priority != priority)
1594 nbr_nbma->priority = priority;
1595
1596 return 1;
1597}
1598
1599int
1600ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1601{
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 != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1609 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1610
1611 return 1;
1612}
1613
1614int
1615ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001616 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001617{
1618 struct ospf_nbr_nbma *nbr_nbma;
1619
1620 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1621 if (nbr_nbma == NULL)
1622 return 0;
1623
1624 if (nbr_nbma->v_poll != interval)
1625 {
1626 nbr_nbma->v_poll = interval;
1627 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1628 {
1629 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1630 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1631 nbr_nbma->v_poll);
1632 }
1633 }
1634
1635 return 1;
1636}
1637
1638int
1639ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1640{
1641 struct ospf_nbr_nbma *nbr_nbma;
1642
1643 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1644 if (nbr_nbma == NULL)
1645 return 0;
1646
1647 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1648 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1649
1650 return 1;
1651}
1652
paul718e3742002-12-13 20:15:29 +00001653void
paul020709f2003-04-04 02:44:16 +00001654ospf_master_init ()
1655{
1656 memset (&ospf_master, 0, sizeof (struct ospf_master));
1657
1658 om = &ospf_master;
1659 om->ospf = list_new ();
1660 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001661 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001662}