blob: 8c151d98a2fc060d5639ee715ae2928a00f035f2 [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
170 new->new_external_route = route_table_init ();
171 new->old_external_route = route_table_init ();
172 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000173
174 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000175 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul88d6cf32005-10-29 12:50:09 +0000176
paul718e3742002-12-13 20:15:29 +0000177 /* Distribute parameter init. */
178 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
179 {
180 new->dmetric[i].type = -1;
181 new->dmetric[i].value = -1;
182 }
183 new->default_metric = -1;
184 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
185
186 /* SPF timer value init. */
187 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
188 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000189 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
190 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000191
192 /* MaxAge init. */
193 new->maxage_lsa = list_new ();
194 new->t_maxage_walker =
195 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000196 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000197
198 /* Distance table init. */
199 new->distance_table = route_table_init ();
200
201 new->lsa_refresh_queue.index = 0;
202 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
203 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
204 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000205 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000206
ajs5c333492005-02-23 15:43:01 +0000207 if ((new->fd = ospf_sock_init()) < 0)
208 {
209 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
210 "a socket");
211 exit(1);
212 }
213 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
214 {
215 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
216 OSPF_MAX_PACKET_SIZE+1);
217 exit(1);
218 }
219 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000220 new->oi_write_q = list_new ();
221
222 return new;
223}
224
225struct ospf *
paul020709f2003-04-04 02:44:16 +0000226ospf_lookup ()
227{
228 if (listcount (om->ospf) == 0)
229 return NULL;
230
paul1eb8ef22005-04-07 07:30:20 +0000231 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000232}
233
paul4dadc292005-05-06 21:37:42 +0000234static void
paul020709f2003-04-04 02:44:16 +0000235ospf_add (struct ospf *ospf)
236{
237 listnode_add (om->ospf, ospf);
238}
239
paul4dadc292005-05-06 21:37:42 +0000240static void
paul020709f2003-04-04 02:44:16 +0000241ospf_delete (struct ospf *ospf)
242{
243 listnode_delete (om->ospf, ospf);
244}
245
246struct ospf *
paul718e3742002-12-13 20:15:29 +0000247ospf_get ()
248{
paul020709f2003-04-04 02:44:16 +0000249 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000250
paul020709f2003-04-04 02:44:16 +0000251 ospf = ospf_lookup ();
252 if (ospf == NULL)
253 {
254 ospf = ospf_new ();
255 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000256
paul020709f2003-04-04 02:44:16 +0000257 if (ospf->router_id_static.s_addr == 0)
258 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000259
260#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000261 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000262#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000263 }
paul68980082003-03-25 05:07:42 +0000264
265 return ospf;
paul718e3742002-12-13 20:15:29 +0000266}
paul88d6cf32005-10-29 12:50:09 +0000267
paulc9c93d52005-11-26 13:31:11 +0000268/* Handle the second half of deferred shutdown. This is called either
269 * from the deferred-shutdown timer thread, or directly through
270 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000271 *
272 * Function is to cleanup G-R state, if required then call ospf_finish_final
273 * to complete shutdown of this ospf instance. Possibly exit if the
274 * whole process is being shutdown and this was the last OSPF instance.
275 */
276static void
paulc9c93d52005-11-26 13:31:11 +0000277ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000278{
279 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000280 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000281
282 ospf_finish_final (ospf);
283
284 /* *ospf is now invalid */
285
286 /* ospfd being shut-down? If so, was this the last ospf instance? */
287 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
288 && (listcount (om->ospf) == 0))
289 exit (0);
290
291 return;
292}
293
294/* Timer thread for G-R */
295static int
paulc9c93d52005-11-26 13:31:11 +0000296ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000297{
298 struct ospf *ospf = THREAD_ARG(t);
299
paulc9c93d52005-11-26 13:31:11 +0000300 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000301
302 return 0;
303}
304
paulc9c93d52005-11-26 13:31:11 +0000305/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000306 * down directly into second-half of instance shutdown.
307 */
308static void
paulc9c93d52005-11-26 13:31:11 +0000309ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000310{
311 unsigned long timeout;
312 struct listnode *ln;
313 struct ospf_area *area;
314
paulc9c93d52005-11-26 13:31:11 +0000315 /* deferred shutdown already running? */
316 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000317 return;
318
319 /* Should we try push out max-metric LSAs? */
320 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
321 {
322 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
323 {
324 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
325
326 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
327 ospf_router_lsa_timer_add (area);
328 }
329 timeout = ospf->stub_router_shutdown_time;
330 }
331 else
paulc9c93d52005-11-26 13:31:11 +0000332 {
333 /* No timer needed */
334 ospf_deferred_shutdown_finish (ospf);
335 return;
336 }
paul88d6cf32005-10-29 12:50:09 +0000337
paulc9c93d52005-11-26 13:31:11 +0000338 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000339 timeout);
340 return;
341}
342
343/* Shut down the entire process */
344void
345ospf_terminate (void)
346{
347 struct ospf *ospf;
348 struct listnode *node, *nnode;
349
350 /* shutdown already in progress */
351 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
352 return;
353
354 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
355
356 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
357 ospf_finish (ospf);
358
359 /* Deliberately go back up, hopefully to thread scheduler, as
360 * One or more ospf_finish()'s may have deferred shutdown to a timer
361 * thread
362 */
363}
paul718e3742002-12-13 20:15:29 +0000364
365void
366ospf_finish (struct ospf *ospf)
367{
paulc9c93d52005-11-26 13:31:11 +0000368 /* let deferred shutdown decide */
369 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000370
paulc9c93d52005-11-26 13:31:11 +0000371 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000372 * deferred to expiry of G-S timer thread. Return back up, hopefully
373 * to thread scheduler.
374 */
paulc9c93d52005-11-26 13:31:11 +0000375 return;
paul88d6cf32005-10-29 12:50:09 +0000376}
377
378/* Final cleanup of ospf instance */
379static void
380ospf_finish_final (struct ospf *ospf)
381{
paul718e3742002-12-13 20:15:29 +0000382 struct route_node *rn;
383 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000384 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000385 struct ospf_interface *oi;
386 struct ospf_area *area;
387 struct ospf_vl_data *vl_data;
388 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000389 int i;
390
391#ifdef HAVE_OPAQUE_LSA
392 ospf_opaque_type11_lsa_term (ospf);
393#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000394
395 /* be nice if this worked, but it doesn't */
396 /*ospf_flush_self_originated_lsas_now (ospf);*/
397
398 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000399 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000400 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000401 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000402
paul1eb8ef22005-04-07 07:30:20 +0000403 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
404 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000405
paul1eb8ef22005-04-07 07:30:20 +0000406 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
407 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000408
409 list_delete (ospf->vlinks);
410
411 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000412 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
413 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000414
415 /* Clear static neighbors */
416 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
417 if ((nbr_nbma = rn->info))
418 {
419 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
420
421 if (nbr_nbma->nbr)
422 {
423 nbr_nbma->nbr->nbr_nbma = NULL;
424 nbr_nbma->nbr = NULL;
425 }
426
427 if (nbr_nbma->oi)
428 {
429 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
430 nbr_nbma->oi = NULL;
431 }
432
433 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
434 }
435
436 route_table_finish (ospf->nbr_nbma);
437
438 /* Clear networks and Areas. */
439 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
440 {
441 struct ospf_network *network;
442
443 if ((network = rn->info) != NULL)
444 {
paul68980082003-03-25 05:07:42 +0000445 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000446 rn->info = NULL;
447 route_unlock_node (rn);
448 }
449 }
450
paul1eb8ef22005-04-07 07:30:20 +0000451 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000452 {
paul718e3742002-12-13 20:15:29 +0000453 listnode_delete (ospf->areas, area);
454 ospf_area_free (area);
455 }
456
457 /* Cancel all timers. */
458 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000459 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
460 OSPF_TIMER_OFF (ospf->t_spf_calc);
461 OSPF_TIMER_OFF (ospf->t_ase_calc);
462 OSPF_TIMER_OFF (ospf->t_maxage);
463 OSPF_TIMER_OFF (ospf->t_maxage_walker);
464 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000465 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000466 OSPF_TIMER_OFF (ospf->t_distribute_update);
467 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
468 OSPF_TIMER_OFF (ospf->t_read);
469 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000470#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000471 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000472#endif
paul718e3742002-12-13 20:15:29 +0000473
474 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000475 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000476
477#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000478 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
479 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000480#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000481 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
482 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
483
paul718e3742002-12-13 20:15:29 +0000484 ospf_lsdb_delete_all (ospf->lsdb);
485 ospf_lsdb_free (ospf->lsdb);
486
paul1eb8ef22005-04-07 07:30:20 +0000487 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000488 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +0000489
490 list_delete (ospf->maxage_lsa);
491
492 if (ospf->old_table)
493 ospf_route_table_free (ospf->old_table);
494 if (ospf->new_table)
495 {
496 ospf_route_delete (ospf->new_table);
497 ospf_route_table_free (ospf->new_table);
498 }
499 if (ospf->old_rtrs)
500 ospf_rtrs_free (ospf->old_rtrs);
501 if (ospf->new_rtrs)
502 ospf_rtrs_free (ospf->new_rtrs);
503 if (ospf->new_external_route)
504 {
505 ospf_route_delete (ospf->new_external_route);
506 ospf_route_table_free (ospf->new_external_route);
507 }
508 if (ospf->old_external_route)
509 {
510 ospf_route_delete (ospf->old_external_route);
511 ospf_route_table_free (ospf->old_external_route);
512 }
513 if (ospf->external_lsas)
514 {
515 ospf_ase_external_lsas_finish (ospf->external_lsas);
516 }
517
518 list_delete (ospf->areas);
519
520 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
521 if (EXTERNAL_INFO (i) != NULL)
522 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
523 {
524 if (rn->info == NULL)
525 continue;
526
527 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
528 rn->info = NULL;
529 route_unlock_node (rn);
530 }
531
paul68980082003-03-25 05:07:42 +0000532 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000533 route_table_finish (ospf->distance_table);
534
paul020709f2003-04-04 02:44:16 +0000535 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000536
paul020709f2003-04-04 02:44:16 +0000537 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000538}
539
540
541/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000542static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000543ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000544{
545 struct ospf_area *new;
546
547 /* Allocate new config_network. */
548 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
549
paul68980082003-03-25 05:07:42 +0000550 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000551
552 new->area_id = area_id;
553
554 new->external_routing = OSPF_AREA_DEFAULT;
555 new->default_cost = 1;
556 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000557
paul718e3742002-12-13 20:15:29 +0000558 /* New LSDB init. */
559 new->lsdb = ospf_lsdb_new ();
560
561 /* Self-originated LSAs initialize. */
562 new->router_lsa_self = NULL;
563
564#ifdef HAVE_OPAQUE_LSA
565 ospf_opaque_type10_lsa_init (new);
566#endif /* HAVE_OPAQUE_LSA */
567
568 new->oiflist = list_new ();
569 new->ranges = route_table_init ();
570
571 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000572 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000573
574 return new;
575}
576
577void
578ospf_area_free (struct ospf_area *area)
579{
paul68980082003-03-25 05:07:42 +0000580 struct route_node *rn;
581 struct ospf_lsa *lsa;
582
paul718e3742002-12-13 20:15:29 +0000583 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000584 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
585 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
586 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
587 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
588 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
589 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
590 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
591 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000592
paul68980082003-03-25 05:07:42 +0000593 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
594 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000595#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000596 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
597 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
598 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
599 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000600#endif /* HAVE_OPAQUE_LSA */
601
602 ospf_lsdb_delete_all (area->lsdb);
603 ospf_lsdb_free (area->lsdb);
604
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000605 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000606
607 route_table_finish (area->ranges);
608 list_delete (area->oiflist);
609
610 if (EXPORT_NAME (area))
611 free (EXPORT_NAME (area));
612
613 if (IMPORT_NAME (area))
614 free (IMPORT_NAME (area));
615
616 /* Cancel timer. */
617 OSPF_TIMER_OFF (area->t_router_lsa_self);
paul88d6cf32005-10-29 12:50:09 +0000618 OSPF_TIMER_OFF (area->t_stub_router);
619#ifdef HAVE_OPAQUE_LSA
620 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
621#endif /* HAVE_OPAQUE_LSA */
622
paul718e3742002-12-13 20:15:29 +0000623 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000624 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000625
626 XFREE (MTYPE_OSPF_AREA, area);
627}
628
629void
paul68980082003-03-25 05:07:42 +0000630ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000631{
632 struct ospf_area *area;
633
paul68980082003-03-25 05:07:42 +0000634 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000635 if (area &&
636 listcount (area->oiflist) == 0 &&
637 area->ranges->top == NULL &&
638 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
639 area->external_routing == OSPF_AREA_DEFAULT &&
640 area->no_summary == 0 &&
641 area->default_cost == 1 &&
642 EXPORT_NAME (area) == NULL &&
643 IMPORT_NAME (area) == NULL &&
644 area->auth_type == OSPF_AUTH_NULL)
645 {
paul68980082003-03-25 05:07:42 +0000646 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000647 ospf_area_free (area);
648 }
649}
650
651struct ospf_area *
paul68980082003-03-25 05:07:42 +0000652ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000653{
654 struct ospf_area *area;
655
paul68980082003-03-25 05:07:42 +0000656 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000657 if (!area)
658 {
paul68980082003-03-25 05:07:42 +0000659 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000660 area->format = format;
paul68980082003-03-25 05:07:42 +0000661 listnode_add_sort (ospf->areas, area);
662 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000663 }
664
665 return area;
666}
667
668struct ospf_area *
paul68980082003-03-25 05:07:42 +0000669ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000670{
671 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000672 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000673
paul1eb8ef22005-04-07 07:30:20 +0000674 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
675 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
676 return area;
paul718e3742002-12-13 20:15:29 +0000677
678 return NULL;
679}
680
681void
682ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
683{
684 listnode_add (area->oiflist, oi);
685}
686
687void
688ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
689{
690 listnode_delete (area->oiflist, oi);
691}
692
693
694/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000695static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000696ospf_network_new (struct in_addr area_id, int format)
697{
698 struct ospf_network *new;
699 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
700
701 new->area_id = area_id;
702 new->format = format;
703
704 return new;
705}
706
707void
paul68980082003-03-25 05:07:42 +0000708ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000709{
paul68980082003-03-25 05:07:42 +0000710 ospf_area_check_free (ospf, network->area_id);
711 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000712 XFREE (MTYPE_OSPF_NETWORK, network);
713}
714
715int
716ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
717 struct in_addr area_id)
718{
719 struct ospf_network *network;
720 struct ospf_area *area;
721 struct route_node *rn;
722 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000723 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000724
725 rn = route_node_get (ospf->networks, (struct prefix *)p);
726 if (rn->info)
727 {
728 /* There is already same network statement. */
729 route_unlock_node (rn);
730 return 0;
731 }
732
733 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000734 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000735
736 /* Run network config now. */
737 ospf_network_run (ospf, (struct prefix *)p, area);
738
739 /* Update connected redistribute. */
740 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
741 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
742 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
743 rn; rn = route_next (rn))
744 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000745 if (ospf_external_info_find_lsa (ospf, &ei->p))
746 if (!ospf_distribute_check_connected (ospf, ei))
747 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000748 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000749
paul68980082003-03-25 05:07:42 +0000750 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000751
752 return 1;
753}
754
755int
756ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
757 struct in_addr area_id)
758{
759 struct route_node *rn;
760 struct ospf_network *network;
761 struct external_info *ei;
762
763 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
764 if (rn == NULL)
765 return 0;
766
767 network = rn->info;
768 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
769 return 0;
770
paul68980082003-03-25 05:07:42 +0000771 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000772 rn->info = NULL;
773 route_unlock_node (rn);
774
paul68980082003-03-25 05:07:42 +0000775 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000776
777 /* Update connected redistribute. */
778 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
779 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
780 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
781 rn; rn = route_next (rn))
782 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000783 if (!ospf_external_info_find_lsa (ospf, &ei->p))
784 if (ospf_distribute_check_connected (ospf, ei))
785 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000786
787 return 1;
788}
789
paul570f7592003-01-25 06:47:41 +0000790/* Check whether interface matches given network
791 * returns: 1, true. 0, false
792 */
793int
794ospf_network_match_iface(struct connected *co, struct prefix *net)
795{
796 /* Behaviour to match both Cisco where:
797 * iface address lies within network specified -> ospf
798 * and zebra 0.9[2ish-3]:
799 * PtP special case: network specified == iface peer addr -> ospf
800 */
gdt8f40e892003-12-05 14:01:43 +0000801
paulf3ae74c2004-11-04 20:35:31 +0000802 /* For PtP, match if peer address matches network address exactly.
803 * This can be addr/32 or addr/p for p < 32, but the addr must match
804 * exactly; this is not a test for falling within the prefix. This
gdt8f40e892003-12-05 14:01:43 +0000805 * test is solely for compatibility with zebra.
gdt8f40e892003-12-05 14:01:43 +0000806 */
paulf3ae74c2004-11-04 20:35:31 +0000807 if (if_is_pointopoint (co->ifp) && co->destination &&
808 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
809 return 1;
810
811#if 0
812 /* Decline to accept PtP if dst address does not match the
813 * prefix. (ifdefed out because this is a workaround, not the
814 * desired behavior.) */
815 if (if_is_pointopoint (co->ifp) &&
816 ! prefix_match (net, co->destination))
817 return 0;
818#endif
819
820 /* If the address is within the prefix, accept. Note that this
821 * applies to PtP as well as other types.
822 */
823 if (prefix_match (net, co->address))
824 return 1;
825
826 return 0; /* no match */
paul570f7592003-01-25 06:47:41 +0000827}
828
paul718e3742002-12-13 20:15:29 +0000829void
830ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
831{
832 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000833 struct connected *co;
hasso52dc7ee2004-09-23 19:18:23 +0000834 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000835
836 /* Schedule Router ID Update. */
paul86752842006-01-10 20:34:46 +0000837 if (ospf->router_id.s_addr == 0)
paulb29800a2005-11-20 14:50:45 +0000838 ospf_router_id_update (ospf);
839
paul718e3742002-12-13 20:15:29 +0000840 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000841 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000842 {
paul1eb8ef22005-04-07 07:30:20 +0000843 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000844
paul718e3742002-12-13 20:15:29 +0000845 if (memcmp (ifp->name, "VLINK", 5) == 0)
846 continue;
847
848 /* if interface prefix is match specified prefix,
849 then create socket and join multicast group. */
paul1eb8ef22005-04-07 07:30:20 +0000850 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
paul718e3742002-12-13 20:15:29 +0000851 {
paul718e3742002-12-13 20:15:29 +0000852 struct prefix *addr;
paul800dc102003-03-28 01:51:40 +0000853
paule7b050c2003-04-07 06:38:02 +0000854 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
855 continue;
paul718e3742002-12-13 20:15:29 +0000856
hasso3fb9cd62004-10-19 19:44:43 +0000857 if (CONNECTED_POINTOPOINT_HOST(co))
paul718e3742002-12-13 20:15:29 +0000858 addr = co->destination;
859 else
860 addr = co->address;
861
paulcb3f37d2003-02-18 23:26:37 +0000862 if (p->family == co->address->family
paul68980082003-03-25 05:07:42 +0000863 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
paulcb3f37d2003-02-18 23:26:37 +0000864 && ospf_network_match_iface(co,p))
paul570f7592003-01-25 06:47:41 +0000865 {
paul1eb8ef22005-04-07 07:30:20 +0000866 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000867
paul68980082003-03-25 05:07:42 +0000868 oi = ospf_if_new (ospf, ifp, co->address);
paul718e3742002-12-13 20:15:29 +0000869 oi->connected = co;
870
paul718e3742002-12-13 20:15:29 +0000871 oi->area = area;
872
873 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
874 oi->output_cost = ospf_if_get_output_cost (oi);
875
paul718e3742002-12-13 20:15:29 +0000876 /* Add pseudo neighbor. */
877 ospf_nbr_add_self (oi);
878
paul718e3742002-12-13 20:15:29 +0000879 /* Relate ospf interface to ospf instance. */
paul68980082003-03-25 05:07:42 +0000880 oi->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000881
882 /* update network type as interface flag */
883 /* If network type is specified previously,
884 skip network type setting. */
885 oi->type = IF_DEF_PARAMS (ifp)->type;
886
paul718e3742002-12-13 20:15:29 +0000887 ospf_area_add_if (oi->area, oi);
paulb29800a2005-11-20 14:50:45 +0000888
889 /* if router_id is not configured, dont bring up
890 * interfaces.
891 * ospf_router_id_update() will call ospf_if_update
892 * whenever r-id is configured instead.
893 */
paul86752842006-01-10 20:34:46 +0000894 if ((ospf->router_id.s_addr != 0)
paulb29800a2005-11-20 14:50:45 +0000895 && if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000896 ospf_if_up (oi);
897
898 break;
899 }
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}