blob: 7c9fb8f05b9c0d07dd711f6069cbfeae95893768 [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
paul68980082003-03-25 05:07:42 +000087 if (ospf->router_id_static.s_addr != 0)
88 router_id = ospf->router_id_static;
paul718e3742002-12-13 20:15:29 +000089 else
hasso18a6dce2004-10-03 18:18:34 +000090 router_id = router_id_zebra;
paul718e3742002-12-13 20:15:29 +000091
paul68980082003-03-25 05:07:42 +000092 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +000093
94 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +000095 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +000096
97 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
98 {
paul1eb8ef22005-04-07 07:30:20 +000099 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
100 /* Update self-neighbor's router_id. */
101 oi->nbr_self->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000102
103 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000104 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000105 {
106 int type;
107 /* Originate each redistributed external route. */
108 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000109 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000110 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000111 ospf, type);
paul718e3742002-12-13 20:15:29 +0000112 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000113 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
paul718e3742002-12-13 20:15:29 +0000114 thread_add_event (master, ospf_default_originate_timer,
paul68980082003-03-25 05:07:42 +0000115 &ospf->default_originate, 0);
paul718e3742002-12-13 20:15:29 +0000116
paul68980082003-03-25 05:07:42 +0000117 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000118 }
119
paul68980082003-03-25 05:07:42 +0000120 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000121 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
paulb29800a2005-11-20 14:50:45 +0000122
123 /* update ospf_interface's */
124 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000125 }
126}
paul718e3742002-12-13 20:15:29 +0000127
128/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000129static int
paul718e3742002-12-13 20:15:29 +0000130ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
131{
132 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
133 return 1;
134 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
135 return -1;
136 return 0;
137}
138
139/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000140static struct ospf *
141ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000142{
143 int i;
144
145 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
146
147 new->router_id.s_addr = htonl (0);
148 new->router_id_static.s_addr = htonl (0);
149
pauld57834f2005-07-12 20:04:22 +0000150 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000151 new->oiflist = list_new ();
152 new->vlinks = list_new ();
153 new->areas = list_new ();
154 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
155 new->networks = route_table_init ();
156 new->nbr_nbma = route_table_init ();
157
158 new->lsdb = ospf_lsdb_new ();
159
160 new->default_originate = DEFAULT_ORIGINATE_NONE;
161
162 new->new_external_route = route_table_init ();
163 new->old_external_route = route_table_init ();
164 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000165
166 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000167 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul88d6cf32005-10-29 12:50:09 +0000168
paul718e3742002-12-13 20:15:29 +0000169 /* Distribute parameter init. */
170 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
171 {
172 new->dmetric[i].type = -1;
173 new->dmetric[i].value = -1;
174 }
175 new->default_metric = -1;
176 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
177
178 /* SPF timer value init. */
179 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
180 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000181 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
182 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000183
184 /* MaxAge init. */
185 new->maxage_lsa = list_new ();
186 new->t_maxage_walker =
187 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000188 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000189
190 /* Distance table init. */
191 new->distance_table = route_table_init ();
192
193 new->lsa_refresh_queue.index = 0;
194 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
195 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
196 new, new->lsa_refresh_interval);
197 new->lsa_refresher_started = time (NULL);
198
ajs5c333492005-02-23 15:43:01 +0000199 if ((new->fd = ospf_sock_init()) < 0)
200 {
201 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
202 "a socket");
203 exit(1);
204 }
205 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
206 {
207 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
208 OSPF_MAX_PACKET_SIZE+1);
209 exit(1);
210 }
211 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000212 new->oi_write_q = list_new ();
213
214 return new;
215}
216
217struct ospf *
paul020709f2003-04-04 02:44:16 +0000218ospf_lookup ()
219{
220 if (listcount (om->ospf) == 0)
221 return NULL;
222
paul1eb8ef22005-04-07 07:30:20 +0000223 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000224}
225
paul4dadc292005-05-06 21:37:42 +0000226static void
paul020709f2003-04-04 02:44:16 +0000227ospf_add (struct ospf *ospf)
228{
229 listnode_add (om->ospf, ospf);
230}
231
paul4dadc292005-05-06 21:37:42 +0000232static void
paul020709f2003-04-04 02:44:16 +0000233ospf_delete (struct ospf *ospf)
234{
235 listnode_delete (om->ospf, ospf);
236}
237
238struct ospf *
paul718e3742002-12-13 20:15:29 +0000239ospf_get ()
240{
paul020709f2003-04-04 02:44:16 +0000241 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000242
paul020709f2003-04-04 02:44:16 +0000243 ospf = ospf_lookup ();
244 if (ospf == NULL)
245 {
246 ospf = ospf_new ();
247 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000248
paul020709f2003-04-04 02:44:16 +0000249 if (ospf->router_id_static.s_addr == 0)
250 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000251
252#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000253 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000254#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000255 }
paul68980082003-03-25 05:07:42 +0000256
257 return ospf;
paul718e3742002-12-13 20:15:29 +0000258}
paul88d6cf32005-10-29 12:50:09 +0000259
260/* Handle the second half of graceful shutdown. This is called either
261 * from the graceful-shutdown timer thread, or directly through
262 * ospf_graceful_shutdown_check.
263 *
264 * Function is to cleanup G-R state, if required then call ospf_finish_final
265 * to complete shutdown of this ospf instance. Possibly exit if the
266 * whole process is being shutdown and this was the last OSPF instance.
267 */
268static void
269ospf_graceful_shutdown_finish (struct ospf *ospf)
270{
271 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
272 OSPF_TIMER_OFF (ospf->t_graceful_shutdown);
273
274 ospf_finish_final (ospf);
275
276 /* *ospf is now invalid */
277
278 /* ospfd being shut-down? If so, was this the last ospf instance? */
279 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
280 && (listcount (om->ospf) == 0))
281 exit (0);
282
283 return;
284}
285
286/* Timer thread for G-R */
287static int
288ospf_graceful_shutdown_timer (struct thread *t)
289{
290 struct ospf *ospf = THREAD_ARG(t);
291
292 ospf_graceful_shutdown_finish (ospf);
293
294 return 0;
295}
296
297/* Check whether graceful-shutdown must be scheduled, otherwise call
298 * down directly into second-half of instance shutdown.
299 */
300static void
301ospf_graceful_shutdown_check (struct ospf *ospf)
302{
303 unsigned long timeout;
304 struct listnode *ln;
305 struct ospf_area *area;
306
307 /* graceful shutdown already running? */
308 if (ospf->t_graceful_shutdown)
309 return;
310
311 /* Should we try push out max-metric LSAs? */
312 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
313 {
314 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
315 {
316 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
317
318 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
319 ospf_router_lsa_timer_add (area);
320 }
321 timeout = ospf->stub_router_shutdown_time;
322 }
323 else
324 /* No timer needed */
325 return ospf_graceful_shutdown_finish (ospf);
326
327 OSPF_TIMER_ON (ospf->t_graceful_shutdown, ospf_graceful_shutdown_timer,
328 timeout);
329 return;
330}
331
332/* Shut down the entire process */
333void
334ospf_terminate (void)
335{
336 struct ospf *ospf;
337 struct listnode *node, *nnode;
338
339 /* shutdown already in progress */
340 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
341 return;
342
343 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
344
345 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
346 ospf_finish (ospf);
347
348 /* Deliberately go back up, hopefully to thread scheduler, as
349 * One or more ospf_finish()'s may have deferred shutdown to a timer
350 * thread
351 */
352}
paul718e3742002-12-13 20:15:29 +0000353
354void
355ospf_finish (struct ospf *ospf)
356{
paul88d6cf32005-10-29 12:50:09 +0000357 /* let graceful shutdown decide */
358 return ospf_graceful_shutdown_check (ospf);
359
360 /* if ospf_graceful_shutdown returns, then ospf_finish_final is
361 * deferred to expiry of G-S timer thread. Return back up, hopefully
362 * to thread scheduler.
363 */
364}
365
366/* Final cleanup of ospf instance */
367static void
368ospf_finish_final (struct ospf *ospf)
369{
paul718e3742002-12-13 20:15:29 +0000370 struct route_node *rn;
371 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000372 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000373 struct ospf_interface *oi;
374 struct ospf_area *area;
375 struct ospf_vl_data *vl_data;
376 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000377 int i;
378
379#ifdef HAVE_OPAQUE_LSA
380 ospf_opaque_type11_lsa_term (ospf);
381#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000382
383 /* be nice if this worked, but it doesn't */
384 /*ospf_flush_self_originated_lsas_now (ospf);*/
385
386 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000387 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000388 ospf_redistribute_unset (ospf, i);
paul718e3742002-12-13 20:15:29 +0000389
paul1eb8ef22005-04-07 07:30:20 +0000390 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
391 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000392
paul1eb8ef22005-04-07 07:30:20 +0000393 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
394 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000395
396 list_delete (ospf->vlinks);
397
398 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000399 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
400 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000401
402 /* Clear static neighbors */
403 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
404 if ((nbr_nbma = rn->info))
405 {
406 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
407
408 if (nbr_nbma->nbr)
409 {
410 nbr_nbma->nbr->nbr_nbma = NULL;
411 nbr_nbma->nbr = NULL;
412 }
413
414 if (nbr_nbma->oi)
415 {
416 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
417 nbr_nbma->oi = NULL;
418 }
419
420 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
421 }
422
423 route_table_finish (ospf->nbr_nbma);
424
425 /* Clear networks and Areas. */
426 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
427 {
428 struct ospf_network *network;
429
430 if ((network = rn->info) != NULL)
431 {
paul68980082003-03-25 05:07:42 +0000432 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000433 rn->info = NULL;
434 route_unlock_node (rn);
435 }
436 }
437
paul1eb8ef22005-04-07 07:30:20 +0000438 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000439 {
paul718e3742002-12-13 20:15:29 +0000440 listnode_delete (ospf->areas, area);
441 ospf_area_free (area);
442 }
443
444 /* Cancel all timers. */
445 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000446 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
447 OSPF_TIMER_OFF (ospf->t_spf_calc);
448 OSPF_TIMER_OFF (ospf->t_ase_calc);
449 OSPF_TIMER_OFF (ospf->t_maxage);
450 OSPF_TIMER_OFF (ospf->t_maxage_walker);
451 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000452 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000453 OSPF_TIMER_OFF (ospf->t_distribute_update);
454 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
455 OSPF_TIMER_OFF (ospf->t_read);
456 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000457#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000458 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000459#endif
paul718e3742002-12-13 20:15:29 +0000460
461 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000462 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000463
464#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000465 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
466 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000467#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000468 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
469 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
470
paul718e3742002-12-13 20:15:29 +0000471 ospf_lsdb_delete_all (ospf->lsdb);
472 ospf_lsdb_free (ospf->lsdb);
473
paul1eb8ef22005-04-07 07:30:20 +0000474 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
475 ospf_lsa_unlock (lsa);
paul718e3742002-12-13 20:15:29 +0000476
477 list_delete (ospf->maxage_lsa);
478
479 if (ospf->old_table)
480 ospf_route_table_free (ospf->old_table);
481 if (ospf->new_table)
482 {
483 ospf_route_delete (ospf->new_table);
484 ospf_route_table_free (ospf->new_table);
485 }
486 if (ospf->old_rtrs)
487 ospf_rtrs_free (ospf->old_rtrs);
488 if (ospf->new_rtrs)
489 ospf_rtrs_free (ospf->new_rtrs);
490 if (ospf->new_external_route)
491 {
492 ospf_route_delete (ospf->new_external_route);
493 ospf_route_table_free (ospf->new_external_route);
494 }
495 if (ospf->old_external_route)
496 {
497 ospf_route_delete (ospf->old_external_route);
498 ospf_route_table_free (ospf->old_external_route);
499 }
500 if (ospf->external_lsas)
501 {
502 ospf_ase_external_lsas_finish (ospf->external_lsas);
503 }
504
505 list_delete (ospf->areas);
506
507 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
508 if (EXTERNAL_INFO (i) != NULL)
509 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
510 {
511 if (rn->info == NULL)
512 continue;
513
514 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
515 rn->info = NULL;
516 route_unlock_node (rn);
517 }
518
paul68980082003-03-25 05:07:42 +0000519 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000520 route_table_finish (ospf->distance_table);
521
paul020709f2003-04-04 02:44:16 +0000522 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000523
paul020709f2003-04-04 02:44:16 +0000524 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000525}
526
527
528/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000529static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000530ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000531{
532 struct ospf_area *new;
533
534 /* Allocate new config_network. */
535 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
536
paul68980082003-03-25 05:07:42 +0000537 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000538
539 new->area_id = area_id;
540
541 new->external_routing = OSPF_AREA_DEFAULT;
542 new->default_cost = 1;
543 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000544
paul718e3742002-12-13 20:15:29 +0000545 /* New LSDB init. */
546 new->lsdb = ospf_lsdb_new ();
547
548 /* Self-originated LSAs initialize. */
549 new->router_lsa_self = NULL;
550
551#ifdef HAVE_OPAQUE_LSA
552 ospf_opaque_type10_lsa_init (new);
553#endif /* HAVE_OPAQUE_LSA */
554
555 new->oiflist = list_new ();
556 new->ranges = route_table_init ();
557
558 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000559 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000560
561 return new;
562}
563
564void
565ospf_area_free (struct ospf_area *area)
566{
paul68980082003-03-25 05:07:42 +0000567 struct route_node *rn;
568 struct ospf_lsa *lsa;
569
paul718e3742002-12-13 20:15:29 +0000570 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000571 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
572 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
573 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
574 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
575 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
576 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
577 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
578 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000579
paul68980082003-03-25 05:07:42 +0000580 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
581 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000582#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000583 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
584 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
585 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
586 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000587#endif /* HAVE_OPAQUE_LSA */
588
589 ospf_lsdb_delete_all (area->lsdb);
590 ospf_lsdb_free (area->lsdb);
591
paul718e3742002-12-13 20:15:29 +0000592 ospf_lsa_unlock (area->router_lsa_self);
593
594 route_table_finish (area->ranges);
595 list_delete (area->oiflist);
596
597 if (EXPORT_NAME (area))
598 free (EXPORT_NAME (area));
599
600 if (IMPORT_NAME (area))
601 free (IMPORT_NAME (area));
602
603 /* Cancel timer. */
604 OSPF_TIMER_OFF (area->t_router_lsa_self);
paul88d6cf32005-10-29 12:50:09 +0000605 OSPF_TIMER_OFF (area->t_stub_router);
606#ifdef HAVE_OPAQUE_LSA
607 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
608#endif /* HAVE_OPAQUE_LSA */
609
paul718e3742002-12-13 20:15:29 +0000610 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000611 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000612
613 XFREE (MTYPE_OSPF_AREA, area);
614}
615
616void
paul68980082003-03-25 05:07:42 +0000617ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000618{
619 struct ospf_area *area;
620
paul68980082003-03-25 05:07:42 +0000621 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000622 if (area &&
623 listcount (area->oiflist) == 0 &&
624 area->ranges->top == NULL &&
625 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
626 area->external_routing == OSPF_AREA_DEFAULT &&
627 area->no_summary == 0 &&
628 area->default_cost == 1 &&
629 EXPORT_NAME (area) == NULL &&
630 IMPORT_NAME (area) == NULL &&
631 area->auth_type == OSPF_AUTH_NULL)
632 {
paul68980082003-03-25 05:07:42 +0000633 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000634 ospf_area_free (area);
635 }
636}
637
638struct ospf_area *
paul68980082003-03-25 05:07:42 +0000639ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000640{
641 struct ospf_area *area;
642
paul68980082003-03-25 05:07:42 +0000643 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000644 if (!area)
645 {
paul68980082003-03-25 05:07:42 +0000646 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000647 area->format = format;
paul68980082003-03-25 05:07:42 +0000648 listnode_add_sort (ospf->areas, area);
649 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000650 }
651
652 return area;
653}
654
655struct ospf_area *
paul68980082003-03-25 05:07:42 +0000656ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000657{
658 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000659 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000660
paul1eb8ef22005-04-07 07:30:20 +0000661 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
662 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
663 return area;
paul718e3742002-12-13 20:15:29 +0000664
665 return NULL;
666}
667
668void
669ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
670{
671 listnode_add (area->oiflist, oi);
672}
673
674void
675ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
676{
677 listnode_delete (area->oiflist, oi);
678}
679
680
681/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000682static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000683ospf_network_new (struct in_addr area_id, int format)
684{
685 struct ospf_network *new;
686 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
687
688 new->area_id = area_id;
689 new->format = format;
690
691 return new;
692}
693
694void
paul68980082003-03-25 05:07:42 +0000695ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000696{
paul68980082003-03-25 05:07:42 +0000697 ospf_area_check_free (ospf, network->area_id);
698 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000699 XFREE (MTYPE_OSPF_NETWORK, network);
700}
701
702int
703ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
704 struct in_addr area_id)
705{
706 struct ospf_network *network;
707 struct ospf_area *area;
708 struct route_node *rn;
709 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000710 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000711
712 rn = route_node_get (ospf->networks, (struct prefix *)p);
713 if (rn->info)
714 {
715 /* There is already same network statement. */
716 route_unlock_node (rn);
717 return 0;
718 }
719
720 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000721 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000722
723 /* Run network config now. */
724 ospf_network_run (ospf, (struct prefix *)p, area);
725
726 /* Update connected redistribute. */
727 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
728 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
729 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
730 rn; rn = route_next (rn))
731 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000732 if (ospf_external_info_find_lsa (ospf, &ei->p))
733 if (!ospf_distribute_check_connected (ospf, ei))
734 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000735 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000736
paul68980082003-03-25 05:07:42 +0000737 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000738
739 return 1;
740}
741
742int
743ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
744 struct in_addr area_id)
745{
746 struct route_node *rn;
747 struct ospf_network *network;
748 struct external_info *ei;
749
750 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
751 if (rn == NULL)
752 return 0;
753
754 network = rn->info;
755 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
756 return 0;
757
paul68980082003-03-25 05:07:42 +0000758 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000759 rn->info = NULL;
760 route_unlock_node (rn);
761
paul68980082003-03-25 05:07:42 +0000762 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000763
764 /* Update connected redistribute. */
765 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
766 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
767 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
768 rn; rn = route_next (rn))
769 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000770 if (!ospf_external_info_find_lsa (ospf, &ei->p))
771 if (ospf_distribute_check_connected (ospf, ei))
772 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000773
774 return 1;
775}
776
paul570f7592003-01-25 06:47:41 +0000777/* Check whether interface matches given network
778 * returns: 1, true. 0, false
779 */
780int
781ospf_network_match_iface(struct connected *co, struct prefix *net)
782{
783 /* Behaviour to match both Cisco where:
784 * iface address lies within network specified -> ospf
785 * and zebra 0.9[2ish-3]:
786 * PtP special case: network specified == iface peer addr -> ospf
787 */
gdt8f40e892003-12-05 14:01:43 +0000788
paulf3ae74c2004-11-04 20:35:31 +0000789 /* For PtP, match if peer address matches network address exactly.
790 * This can be addr/32 or addr/p for p < 32, but the addr must match
791 * exactly; this is not a test for falling within the prefix. This
gdt8f40e892003-12-05 14:01:43 +0000792 * test is solely for compatibility with zebra.
gdt8f40e892003-12-05 14:01:43 +0000793 */
paulf3ae74c2004-11-04 20:35:31 +0000794 if (if_is_pointopoint (co->ifp) && co->destination &&
795 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
796 return 1;
797
798#if 0
799 /* Decline to accept PtP if dst address does not match the
800 * prefix. (ifdefed out because this is a workaround, not the
801 * desired behavior.) */
802 if (if_is_pointopoint (co->ifp) &&
803 ! prefix_match (net, co->destination))
804 return 0;
805#endif
806
807 /* If the address is within the prefix, accept. Note that this
808 * applies to PtP as well as other types.
809 */
810 if (prefix_match (net, co->address))
811 return 1;
812
813 return 0; /* no match */
paul570f7592003-01-25 06:47:41 +0000814}
815
paul718e3742002-12-13 20:15:29 +0000816void
817ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
818{
819 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000820 struct connected *co;
hasso52dc7ee2004-09-23 19:18:23 +0000821 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000822
823 /* Schedule Router ID Update. */
824 if (ospf->router_id_static.s_addr == 0)
paulb29800a2005-11-20 14:50:45 +0000825 ospf_router_id_update (ospf);
826
paul718e3742002-12-13 20:15:29 +0000827 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000828 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000829 {
paul1eb8ef22005-04-07 07:30:20 +0000830 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000831
paul718e3742002-12-13 20:15:29 +0000832 if (memcmp (ifp->name, "VLINK", 5) == 0)
833 continue;
834
835 /* if interface prefix is match specified prefix,
836 then create socket and join multicast group. */
paul1eb8ef22005-04-07 07:30:20 +0000837 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
paul718e3742002-12-13 20:15:29 +0000838 {
paul718e3742002-12-13 20:15:29 +0000839 struct prefix *addr;
paul800dc102003-03-28 01:51:40 +0000840
paule7b050c2003-04-07 06:38:02 +0000841 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
842 continue;
paul718e3742002-12-13 20:15:29 +0000843
hasso3fb9cd62004-10-19 19:44:43 +0000844 if (CONNECTED_POINTOPOINT_HOST(co))
paul718e3742002-12-13 20:15:29 +0000845 addr = co->destination;
846 else
847 addr = co->address;
848
paulcb3f37d2003-02-18 23:26:37 +0000849 if (p->family == co->address->family
paul68980082003-03-25 05:07:42 +0000850 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
paulcb3f37d2003-02-18 23:26:37 +0000851 && ospf_network_match_iface(co,p))
paul570f7592003-01-25 06:47:41 +0000852 {
paul1eb8ef22005-04-07 07:30:20 +0000853 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000854
paul68980082003-03-25 05:07:42 +0000855 oi = ospf_if_new (ospf, ifp, co->address);
paul718e3742002-12-13 20:15:29 +0000856 oi->connected = co;
857
858 oi->nbr_self->address = *oi->address;
859
paul718e3742002-12-13 20:15:29 +0000860 oi->area = area;
861
862 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
863 oi->output_cost = ospf_if_get_output_cost (oi);
864
865 if (area->external_routing != OSPF_AREA_DEFAULT)
866 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
867 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
868
869 /* Add pseudo neighbor. */
870 ospf_nbr_add_self (oi);
871
872 /* Make sure pseudo neighbor's router_id. */
paul68980082003-03-25 05:07:42 +0000873 oi->nbr_self->router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000874 oi->nbr_self->src = oi->address->u.prefix4;
875
876 /* Relate ospf interface to ospf instance. */
paul68980082003-03-25 05:07:42 +0000877 oi->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000878
879 /* update network type as interface flag */
880 /* If network type is specified previously,
881 skip network type setting. */
882 oi->type = IF_DEF_PARAMS (ifp)->type;
883
884 /* Set area flag. */
885 switch (area->external_routing)
886 {
887 case OSPF_AREA_DEFAULT:
888 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
889 break;
890 case OSPF_AREA_STUB:
891 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
892 break;
paul718e3742002-12-13 20:15:29 +0000893 case OSPF_AREA_NSSA:
894 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
895 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
896 break;
paul718e3742002-12-13 20:15:29 +0000897 }
898
899 ospf_area_add_if (oi->area, oi);
paulb29800a2005-11-20 14:50:45 +0000900
901 /* if router_id is not configured, dont bring up
902 * interfaces.
903 * ospf_router_id_update() will call ospf_if_update
904 * whenever r-id is configured instead.
905 */
906 if ((ospf->router_id_static.s_addr != 0)
907 && if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000908 ospf_if_up (oi);
909
910 break;
911 }
912 }
913 }
914}
915
916void
917ospf_ls_upd_queue_empty (struct ospf_interface *oi)
918{
919 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000920 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000921 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000922 struct ospf_lsa *lsa;
923
924 /* empty ls update queue */
925 for (rn = route_top (oi->ls_upd_queue); rn;
926 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000927 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000928 {
paul1eb8ef22005-04-07 07:30:20 +0000929 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
930 ospf_lsa_unlock (lsa);
paul718e3742002-12-13 20:15:29 +0000931 list_free (lst);
932 rn->info = NULL;
933 }
934
935 /* remove update event */
936 if (oi->t_ls_upd_event)
937 {
938 thread_cancel (oi->t_ls_upd_event);
939 oi->t_ls_upd_event = NULL;
940 }
941}
942
943void
paul68980082003-03-25 05:07:42 +0000944ospf_if_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000945{
946 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000947 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000948 struct ospf_network *network;
949 struct ospf_area *area;
paul1eb8ef22005-04-07 07:30:20 +0000950 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000951
paul68980082003-03-25 05:07:42 +0000952 if (ospf != NULL)
paul718e3742002-12-13 20:15:29 +0000953 {
paulb29800a2005-11-20 14:50:45 +0000954 /* Router-ID must be configured. */
paul68980082003-03-25 05:07:42 +0000955 if (ospf->router_id_static.s_addr == 0)
paulb29800a2005-11-20 14:50:45 +0000956 return;
957
paul718e3742002-12-13 20:15:29 +0000958 /* Find interfaces that not configured already. */
paul1eb8ef22005-04-07 07:30:20 +0000959 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +0000960 {
961 int found = 0;
paul718e3742002-12-13 20:15:29 +0000962 struct connected *co = oi->connected;
963
paul718e3742002-12-13 20:15:29 +0000964 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
965 continue;
966
paul68980082003-03-25 05:07:42 +0000967 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000968 {
969 if (rn->info == NULL)
970 continue;
971
paul570f7592003-01-25 06:47:41 +0000972 if (ospf_network_match_iface(co,&rn->p))
paul718e3742002-12-13 20:15:29 +0000973 {
974 found = 1;
975 route_unlock_node (rn);
976 break;
977 }
978 }
979
980 if (found == 0)
981 ospf_if_free (oi);
982 }
983
984 /* Run each interface. */
paul68980082003-03-25 05:07:42 +0000985 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000986 if (rn->info != NULL)
987 {
988 network = (struct ospf_network *) rn->info;
paul68980082003-03-25 05:07:42 +0000989 area = ospf_area_get (ospf, network->area_id, network->format);
990 ospf_network_run (ospf, &rn->p, area);
paul718e3742002-12-13 20:15:29 +0000991 }
992 }
993}
994
995void
paul68980082003-03-25 05:07:42 +0000996ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000997{
paul1eb8ef22005-04-07 07:30:20 +0000998 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000999 struct ospf_vl_data *vl_data;
1000
paul1eb8ef22005-04-07 07:30:20 +00001001 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
1002 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
1003 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +00001004}
1005
1006
1007struct message ospf_area_type_msg[] =
1008{
1009 { OSPF_AREA_DEFAULT, "Default" },
1010 { OSPF_AREA_STUB, "Stub" },
1011 { OSPF_AREA_NSSA, "NSSA" },
1012};
1013int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
1014
paul4dadc292005-05-06 21:37:42 +00001015static void
paul718e3742002-12-13 20:15:29 +00001016ospf_area_type_set (struct ospf_area *area, int type)
1017{
hasso52dc7ee2004-09-23 19:18:23 +00001018 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001019 struct ospf_interface *oi;
1020
1021 if (area->external_routing == type)
1022 {
1023 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001024 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001025 inet_ntoa (area->area_id));
1026 return;
1027 }
1028
1029 area->external_routing = type;
1030
1031 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001032 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001033 LOOKUP (ospf_area_type_msg, type));
1034
1035 switch (area->external_routing)
1036 {
1037 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001038 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1039 if (oi->nbr_self != NULL)
1040 {
1041 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1042 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1043 }
paul718e3742002-12-13 20:15:29 +00001044 break;
1045 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001046 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1047 if (oi->nbr_self != NULL)
1048 {
1049 if (IS_DEBUG_OSPF_EVENT)
1050 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1051 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1052 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1053 if (IS_DEBUG_OSPF_EVENT)
1054 zlog_debug ("options set on %s: %x",
1055 IF_NAME (oi), OPTIONS (oi));
1056 }
paul718e3742002-12-13 20:15:29 +00001057 break;
1058 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001059 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1060 if (oi->nbr_self != NULL)
1061 {
1062 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1063 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1064 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1065 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1066 }
paul718e3742002-12-13 20:15:29 +00001067 break;
1068 default:
1069 break;
1070 }
1071
1072 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001073 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001074}
1075
1076int
paul68980082003-03-25 05:07:42 +00001077ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001078{
1079 if (area->shortcut_configured == mode)
1080 return 0;
1081
1082 area->shortcut_configured = mode;
1083 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001084 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001085
paul68980082003-03-25 05:07:42 +00001086 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001087
1088 return 1;
1089}
1090
1091int
paul68980082003-03-25 05:07:42 +00001092ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001093{
1094 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1095 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001096 ospf_area_check_free (ospf, area->area_id);
1097 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001098
1099 return 1;
1100}
1101
paul4dadc292005-05-06 21:37:42 +00001102static int
paul718e3742002-12-13 20:15:29 +00001103ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1104{
1105 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001106 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001107 int count = 0;
1108
paul1eb8ef22005-04-07 07:30:20 +00001109 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1110 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1111 count++;
paul718e3742002-12-13 20:15:29 +00001112
1113 return count;
1114}
1115
1116int
1117ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1118{
1119 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001120 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001121
paul68980082003-03-25 05:07:42 +00001122 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001123 if (ospf_area_vlink_count (ospf, area))
1124 return 0;
1125
1126 if (area->external_routing != OSPF_AREA_STUB)
1127 ospf_area_type_set (area, OSPF_AREA_STUB);
1128
1129 return 1;
1130}
1131
1132int
1133ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1134{
1135 struct ospf_area *area;
1136
paul68980082003-03-25 05:07:42 +00001137 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001138 if (area == NULL)
1139 return 1;
1140
1141 if (area->external_routing == OSPF_AREA_STUB)
1142 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1143
paul68980082003-03-25 05:07:42 +00001144 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001145
1146 return 1;
1147}
1148
1149int
1150ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1151{
1152 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001153 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001154
paul68980082003-03-25 05:07:42 +00001155 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001156 area->no_summary = 1;
1157
1158 return 1;
1159}
1160
1161int
1162ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1163{
1164 struct ospf_area *area;
1165
paul68980082003-03-25 05:07:42 +00001166 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001167 if (area == NULL)
1168 return 0;
1169
1170 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001171 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001172
1173 return 1;
1174}
1175
1176int
1177ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1178{
1179 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001180 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001181
paul68980082003-03-25 05:07:42 +00001182 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001183 if (ospf_area_vlink_count (ospf, area))
1184 return 0;
1185
1186 if (area->external_routing != OSPF_AREA_NSSA)
1187 {
1188 ospf_area_type_set (area, OSPF_AREA_NSSA);
1189 ospf->anyNSSA++;
1190 }
1191
paul084c7842003-06-22 08:35:18 +00001192 /* set NSSA area defaults */
1193 area->no_summary = 0;
1194 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001195 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001196 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1197
paul718e3742002-12-13 20:15:29 +00001198 return 1;
1199}
1200
1201int
1202ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1203{
1204 struct ospf_area *area;
1205
paul68980082003-03-25 05:07:42 +00001206 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001207 if (area == NULL)
1208 return 0;
1209
1210 if (area->external_routing == OSPF_AREA_NSSA)
1211 {
1212 ospf->anyNSSA--;
1213 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1214 }
1215
paul68980082003-03-25 05:07:42 +00001216 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001217
1218 return 1;
1219}
1220
1221int
1222ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1223 int role)
1224{
1225 struct ospf_area *area;
1226
paul68980082003-03-25 05:07:42 +00001227 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001228 if (area == NULL)
1229 return 0;
1230
paul084c7842003-06-22 08:35:18 +00001231 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001232
1233 return 1;
1234}
1235
paul4dadc292005-05-06 21:37:42 +00001236/* XXX: unused? Leave for symmetry? */
1237static int
paul718e3742002-12-13 20:15:29 +00001238ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1239 struct in_addr area_id)
1240{
1241 struct ospf_area *area;
1242
paul68980082003-03-25 05:07:42 +00001243 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001244 if (area == NULL)
1245 return 0;
1246
paul084c7842003-06-22 08:35:18 +00001247 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001248
paul68980082003-03-25 05:07:42 +00001249 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001250
1251 return 1;
1252}
1253
1254int
paul68980082003-03-25 05:07:42 +00001255ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001256 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001257{
1258 struct access_list *list;
1259 list = access_list_lookup (AFI_IP, list_name);
1260
1261 EXPORT_LIST (area) = list;
1262
1263 if (EXPORT_NAME (area))
1264 free (EXPORT_NAME (area));
1265
1266 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001267 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001268
1269 return 1;
1270}
1271
1272int
paul68980082003-03-25 05:07:42 +00001273ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001274{
1275
1276 EXPORT_LIST (area) = 0;
1277
1278 if (EXPORT_NAME (area))
1279 free (EXPORT_NAME (area));
1280
1281 EXPORT_NAME (area) = NULL;
1282
paul68980082003-03-25 05:07:42 +00001283 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001284
paul68980082003-03-25 05:07:42 +00001285 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001286
1287 return 1;
1288}
1289
1290int
paul6c835672004-10-11 11:00:30 +00001291ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1292 const char *name)
paul718e3742002-12-13 20:15:29 +00001293{
1294 struct access_list *list;
1295 list = access_list_lookup (AFI_IP, name);
1296
1297 IMPORT_LIST (area) = list;
1298
1299 if (IMPORT_NAME (area))
1300 free (IMPORT_NAME (area));
1301
1302 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001303 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001304
1305 return 1;
1306}
1307
1308int
paul68980082003-03-25 05:07:42 +00001309ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001310{
1311 IMPORT_LIST (area) = 0;
1312
1313 if (IMPORT_NAME (area))
1314 free (IMPORT_NAME (area));
1315
1316 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001317 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001318
paul68980082003-03-25 05:07:42 +00001319 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001320
1321 return 1;
1322}
1323
1324int
paul718e3742002-12-13 20:15:29 +00001325ospf_timers_refresh_set (struct ospf *ospf, int interval)
1326{
1327 int time_left;
1328
1329 if (ospf->lsa_refresh_interval == interval)
1330 return 1;
1331
1332 time_left = ospf->lsa_refresh_interval -
1333 (time (NULL) - ospf->lsa_refresher_started);
1334
1335 if (time_left > interval)
1336 {
1337 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1338 ospf->t_lsa_refresher =
1339 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1340 }
1341 ospf->lsa_refresh_interval = interval;
1342
1343 return 1;
1344}
1345
1346int
1347ospf_timers_refresh_unset (struct ospf *ospf)
1348{
1349 int time_left;
1350
1351 time_left = ospf->lsa_refresh_interval -
1352 (time (NULL) - ospf->lsa_refresher_started);
1353
1354 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1355 {
1356 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1357 ospf->t_lsa_refresher =
1358 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1359 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1360 }
1361
1362 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1363
1364 return 1;
1365}
1366
1367
paul4dadc292005-05-06 21:37:42 +00001368static struct ospf_nbr_nbma *
1369ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001370{
1371 struct ospf_nbr_nbma *nbr_nbma;
1372
1373 nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1374 sizeof (struct ospf_nbr_nbma));
1375 memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));
1376
1377 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1378 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1379
1380 return nbr_nbma;
1381}
1382
paul4dadc292005-05-06 21:37:42 +00001383static void
paul718e3742002-12-13 20:15:29 +00001384ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1385{
1386 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1387}
1388
paul4dadc292005-05-06 21:37:42 +00001389static void
paul718e3742002-12-13 20:15:29 +00001390ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1391{
1392 struct route_node *rn;
1393 struct prefix_ipv4 p;
1394
1395 p.family = AF_INET;
1396 p.prefix = nbr_nbma->addr;
1397 p.prefixlen = IPV4_MAX_BITLEN;
1398
1399 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1400 if (rn)
1401 {
1402 ospf_nbr_nbma_free (rn->info);
1403 rn->info = NULL;
1404 route_unlock_node (rn);
1405 route_unlock_node (rn);
1406 }
1407}
1408
paul4dadc292005-05-06 21:37:42 +00001409static void
paul718e3742002-12-13 20:15:29 +00001410ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1411{
1412 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1413
1414 if (nbr_nbma->nbr)
1415 {
1416 nbr_nbma->nbr->nbr_nbma = NULL;
1417 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1418 }
1419
1420 if (nbr_nbma->oi)
1421 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1422}
1423
paul4dadc292005-05-06 21:37:42 +00001424static void
paul718e3742002-12-13 20:15:29 +00001425ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1426 struct ospf_interface *oi)
1427{
1428 struct ospf_neighbor *nbr;
1429 struct route_node *rn;
1430 struct prefix p;
1431
1432 if (oi->type != OSPF_IFTYPE_NBMA)
1433 return;
1434
1435 if (nbr_nbma->nbr != NULL)
1436 return;
1437
1438 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1439 return;
1440
1441 nbr_nbma->oi = oi;
1442 listnode_add (oi->nbr_nbma, nbr_nbma);
1443
1444 /* Get neighbor information from table. */
1445 p.family = AF_INET;
1446 p.prefixlen = IPV4_MAX_BITLEN;
1447 p.u.prefix4 = nbr_nbma->addr;
1448
1449 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1450 if (rn->info)
1451 {
1452 nbr = rn->info;
1453 nbr->nbr_nbma = nbr_nbma;
1454 nbr_nbma->nbr = nbr;
1455
1456 route_unlock_node (rn);
1457 }
1458 else
1459 {
1460 nbr = rn->info = ospf_nbr_new (oi);
1461 nbr->state = NSM_Down;
1462 nbr->src = nbr_nbma->addr;
1463 nbr->nbr_nbma = nbr_nbma;
1464 nbr->priority = nbr_nbma->priority;
1465 nbr->address = p;
1466
1467 nbr_nbma->nbr = nbr;
1468
1469 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1470 }
1471}
1472
1473void
paul68980082003-03-25 05:07:42 +00001474ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001475{
1476 struct ospf_nbr_nbma *nbr_nbma;
1477 struct route_node *rn;
1478 struct prefix_ipv4 p;
1479
1480 if (oi->type != OSPF_IFTYPE_NBMA)
1481 return;
1482
paul68980082003-03-25 05:07:42 +00001483 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001484 if ((nbr_nbma = rn->info))
1485 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1486 {
1487 p.family = AF_INET;
1488 p.prefix = nbr_nbma->addr;
1489 p.prefixlen = IPV4_MAX_BITLEN;
1490
1491 if (prefix_match (oi->address, (struct prefix *)&p))
1492 ospf_nbr_nbma_add (nbr_nbma, oi);
1493 }
1494}
1495
1496struct ospf_nbr_nbma *
1497ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1498{
1499 struct route_node *rn;
1500 struct prefix_ipv4 p;
1501
1502 p.family = AF_INET;
1503 p.prefix = nbr_addr;
1504 p.prefixlen = IPV4_MAX_BITLEN;
1505
1506 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1507 if (rn)
1508 {
1509 route_unlock_node (rn);
1510 return rn->info;
1511 }
1512 return NULL;
1513}
1514
1515struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001516ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001517{
1518#if 0
1519 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001520 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001521#endif
1522
paul68980082003-03-25 05:07:42 +00001523 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001524 return NULL;
1525
1526#if 0
paul1eb8ef22005-04-07 07:30:20 +00001527 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001528 {
paul718e3742002-12-13 20:15:29 +00001529 if (first)
1530 {
1531 *addr = nbr_nbma->addr;
1532 return nbr_nbma;
1533 }
1534 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1535 {
1536 *addr = nbr_nbma->addr;
1537 return nbr_nbma;
1538 }
1539 }
1540#endif
1541 return NULL;
1542}
1543
1544int
1545ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1546{
1547 struct ospf_nbr_nbma *nbr_nbma;
1548 struct ospf_interface *oi;
1549 struct prefix_ipv4 p;
1550 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001551 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001552
1553 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1554 if (nbr_nbma)
1555 return 0;
1556
1557 nbr_nbma = ospf_nbr_nbma_new ();
1558 nbr_nbma->addr = nbr_addr;
1559
1560 p.family = AF_INET;
1561 p.prefix = nbr_addr;
1562 p.prefixlen = IPV4_MAX_BITLEN;
1563
1564 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1565 rn->info = nbr_nbma;
1566
paul1eb8ef22005-04-07 07:30:20 +00001567 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001568 {
paul718e3742002-12-13 20:15:29 +00001569 if (oi->type == OSPF_IFTYPE_NBMA)
1570 if (prefix_match (oi->address, (struct prefix *)&p))
1571 {
1572 ospf_nbr_nbma_add (nbr_nbma, oi);
1573 break;
1574 }
1575 }
1576
1577 return 1;
1578}
1579
1580int
1581ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1582{
1583 struct ospf_nbr_nbma *nbr_nbma;
1584
1585 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1586 if (nbr_nbma == NULL)
1587 return 0;
1588
1589 ospf_nbr_nbma_down (nbr_nbma);
1590 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1591
1592 return 1;
1593}
1594
1595int
1596ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1597 u_char priority)
1598{
1599 struct ospf_nbr_nbma *nbr_nbma;
1600
1601 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1602 if (nbr_nbma == NULL)
1603 return 0;
1604
1605 if (nbr_nbma->priority != priority)
1606 nbr_nbma->priority = priority;
1607
1608 return 1;
1609}
1610
1611int
1612ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1613{
1614 struct ospf_nbr_nbma *nbr_nbma;
1615
1616 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1617 if (nbr_nbma == NULL)
1618 return 0;
1619
1620 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1621 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1622
1623 return 1;
1624}
1625
1626int
1627ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001628 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001629{
1630 struct ospf_nbr_nbma *nbr_nbma;
1631
1632 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1633 if (nbr_nbma == NULL)
1634 return 0;
1635
1636 if (nbr_nbma->v_poll != interval)
1637 {
1638 nbr_nbma->v_poll = interval;
1639 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1640 {
1641 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1642 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1643 nbr_nbma->v_poll);
1644 }
1645 }
1646
1647 return 1;
1648}
1649
1650int
1651ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1652{
1653 struct ospf_nbr_nbma *nbr_nbma;
1654
1655 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1656 if (nbr_nbma == NULL)
1657 return 0;
1658
1659 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1660 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1661
1662 return 1;
1663}
1664
paul718e3742002-12-13 20:15:29 +00001665void
paul020709f2003-04-04 02:44:16 +00001666ospf_master_init ()
1667{
1668 memset (&ospf_master, 0, sizeof (struct ospf_master));
1669
1670 om = &ospf_master;
1671 om->ospf = list_new ();
1672 om->master = thread_master_create ();
1673 om->start_time = time (NULL);
1674}