blob: 11a2dc5c1b1b5463b5da9e182dbc75209e9a8a4a [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* OSPF version 2 daemon program.
2 Copyright (C) 1999, 2000 Toshiaki Takada
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "vty.h"
25#include "command.h"
26#include "linklist.h"
27#include "prefix.h"
28#include "table.h"
29#include "if.h"
30#include "memory.h"
31#include "stream.h"
32#include "log.h"
33#include "sockunion.h" /* for inet_aton () */
34#include "zclient.h"
35#include "plist.h"
Denis Ovsienkof102e752007-09-18 09:01:13 +000036#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_network.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_lsdb.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_packet.h"
49#include "ospfd/ospf_dump.h"
50#include "ospfd/ospf_zebra.h"
51#include "ospfd/ospf_abr.h"
52#include "ospfd/ospf_flood.h"
53#include "ospfd/ospf_route.h"
54#include "ospfd/ospf_ase.h"
55
paul020709f2003-04-04 02:44:16 +000056
pauledd7c242003-06-04 13:59:38 +000057
paul020709f2003-04-04 02:44:16 +000058/* OSPF process wide configuration. */
59static struct ospf_master ospf_master;
60
61/* OSPF process wide configuration pointer to export. */
62struct ospf_master *om;
paul718e3742002-12-13 20:15:29 +000063
64extern struct zclient *zclient;
hasso18a6dce2004-10-03 18:18:34 +000065extern struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000066
67
paul88d6cf32005-10-29 12:50:09 +000068static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
69static void ospf_network_free (struct ospf *, struct ospf_network *);
70static void ospf_area_free (struct ospf_area *);
Joakim Tjernlunda49eb302008-09-02 19:06:31 +010071static void ospf_network_run (struct prefix *, struct ospf_area *);
72static void ospf_network_run_interface (struct prefix *, struct ospf_area *,
73 struct interface *);
Stephen Hemminger917e2992009-12-03 19:07:00 +030074static int ospf_network_match_iface (const struct connected *,
75 const struct prefix *);
paul88d6cf32005-10-29 12:50:09 +000076static void ospf_finish_final (struct ospf *);
paul718e3742002-12-13 20:15:29 +000077
paul718e3742002-12-13 20:15:29 +000078#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
paul88d6cf32005-10-29 12:50:09 +000079
paul718e3742002-12-13 20:15:29 +000080void
paul68980082003-03-25 05:07:42 +000081ospf_router_id_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +000082{
paul718e3742002-12-13 20:15:29 +000083 struct in_addr router_id, router_id_old;
paul1eb8ef22005-04-07 07:30:20 +000084 struct ospf_interface *oi;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +010085 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +000086 struct listnode *node;
paul718e3742002-12-13 20:15:29 +000087
88 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +000089 zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +000090
paul68980082003-03-25 05:07:42 +000091 router_id_old = ospf->router_id;
paul718e3742002-12-13 20:15:29 +000092
Andrew J. Schorr16700082006-07-27 22:29:06 +000093 /* Select the router ID based on these priorities:
94 1. Statically assigned router ID is always the first choice.
95 2. If there is no statically assigned router ID, then try to stick
96 with the most recent value, since changing router ID's is very
97 disruptive.
98 3. Last choice: just go with whatever the zebra daemon recommends.
99 */
paul68980082003-03-25 05:07:42 +0000100 if (ospf->router_id_static.s_addr != 0)
101 router_id = ospf->router_id_static;
Andrew J. Schorr16700082006-07-27 22:29:06 +0000102 else if (ospf->router_id.s_addr != 0)
103 router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000104 else
hasso18a6dce2004-10-03 18:18:34 +0000105 router_id = router_id_zebra;
paul718e3742002-12-13 20:15:29 +0000106
paul68980082003-03-25 05:07:42 +0000107 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000108
109 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000110 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000111
112 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
113 {
paul1eb8ef22005-04-07 07:30:20 +0000114 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
115 /* Update self-neighbor's router_id. */
116 oi->nbr_self->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000117
118 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000119 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000120 {
121 int type;
122 /* Originate each redistributed external route. */
123 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000124 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000125 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000126 ospf, type);
paul718e3742002-12-13 20:15:29 +0000127 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000128 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
Paul Jakma4021b602006-05-12 22:55:41 +0000129 thread_add_event (master, ospf_default_originate_timer, ospf, 0);
paul718e3742002-12-13 20:15:29 +0000130
paul68980082003-03-25 05:07:42 +0000131 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000132 }
133
Paul Jakmac363d382010-01-24 22:42:13 +0000134 /* update router-lsa's for each area */
135 ospf_router_lsa_update (ospf);
paulb29800a2005-11-20 14:50:45 +0000136
137 /* update ospf_interface's */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100138 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
139 ospf_if_update (ospf, ifp);
paul718e3742002-12-13 20:15:29 +0000140 }
141}
paul718e3742002-12-13 20:15:29 +0000142
143/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000144static int
paul718e3742002-12-13 20:15:29 +0000145ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
146{
147 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
148 return 1;
149 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
150 return -1;
151 return 0;
152}
153
154/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000155static struct ospf *
156ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000157{
158 int i;
159
160 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
161
162 new->router_id.s_addr = htonl (0);
163 new->router_id_static.s_addr = htonl (0);
164
pauld57834f2005-07-12 20:04:22 +0000165 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000166 new->oiflist = list_new ();
167 new->vlinks = list_new ();
168 new->areas = list_new ();
169 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
170 new->networks = route_table_init ();
171 new->nbr_nbma = route_table_init ();
172
173 new->lsdb = ospf_lsdb_new ();
174
175 new->default_originate = DEFAULT_ORIGINATE_NONE;
176
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000177 new->passive_interface_default = OSPF_IF_ACTIVE;
178
paul718e3742002-12-13 20:15:29 +0000179 new->new_external_route = route_table_init ();
180 new->old_external_route = route_table_init ();
181 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000182
183 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000184 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800185 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
186
paul718e3742002-12-13 20:15:29 +0000187 /* Distribute parameter init. */
188 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
189 {
190 new->dmetric[i].type = -1;
191 new->dmetric[i].value = -1;
192 }
193 new->default_metric = -1;
194 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
195
196 /* SPF timer value init. */
197 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
198 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000199 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
200 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000201
202 /* MaxAge init. */
Paul Jakma02d942c2010-01-24 23:36:20 +0000203 new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000204 new->maxage_lsa = list_new ();
205 new->t_maxage_walker =
206 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000207 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000208
209 /* Distance table init. */
210 new->distance_table = route_table_init ();
211
212 new->lsa_refresh_queue.index = 0;
213 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
214 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
215 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000216 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000217
ajs5c333492005-02-23 15:43:01 +0000218 if ((new->fd = ospf_sock_init()) < 0)
219 {
220 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
221 "a socket");
222 exit(1);
223 }
Denis Ovsienkof102e752007-09-18 09:01:13 +0000224 new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
225 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
226 zlog_debug ("%s: starting with OSPF send buffer size %d",
227 __func__, new->maxsndbuflen);
ajs5c333492005-02-23 15:43:01 +0000228 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
229 {
230 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
231 OSPF_MAX_PACKET_SIZE+1);
232 exit(1);
233 }
234 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000235 new->oi_write_q = list_new ();
236
237 return new;
238}
239
240struct ospf *
paul020709f2003-04-04 02:44:16 +0000241ospf_lookup ()
242{
243 if (listcount (om->ospf) == 0)
244 return NULL;
245
paul1eb8ef22005-04-07 07:30:20 +0000246 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000247}
248
paul4dadc292005-05-06 21:37:42 +0000249static void
paul020709f2003-04-04 02:44:16 +0000250ospf_add (struct ospf *ospf)
251{
252 listnode_add (om->ospf, ospf);
253}
254
paul4dadc292005-05-06 21:37:42 +0000255static void
paul020709f2003-04-04 02:44:16 +0000256ospf_delete (struct ospf *ospf)
257{
258 listnode_delete (om->ospf, ospf);
259}
260
261struct ospf *
paul718e3742002-12-13 20:15:29 +0000262ospf_get ()
263{
paul020709f2003-04-04 02:44:16 +0000264 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000265
paul020709f2003-04-04 02:44:16 +0000266 ospf = ospf_lookup ();
267 if (ospf == NULL)
268 {
269 ospf = ospf_new ();
270 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000271
paul020709f2003-04-04 02:44:16 +0000272 if (ospf->router_id_static.s_addr == 0)
273 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000274
275#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000276 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000277#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000278 }
paul68980082003-03-25 05:07:42 +0000279
280 return ospf;
paul718e3742002-12-13 20:15:29 +0000281}
paul88d6cf32005-10-29 12:50:09 +0000282
paulc9c93d52005-11-26 13:31:11 +0000283/* Handle the second half of deferred shutdown. This is called either
284 * from the deferred-shutdown timer thread, or directly through
285 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000286 *
287 * Function is to cleanup G-R state, if required then call ospf_finish_final
288 * to complete shutdown of this ospf instance. Possibly exit if the
289 * whole process is being shutdown and this was the last OSPF instance.
290 */
291static void
paulc9c93d52005-11-26 13:31:11 +0000292ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000293{
294 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000295 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000296
297 ospf_finish_final (ospf);
298
299 /* *ospf is now invalid */
300
301 /* ospfd being shut-down? If so, was this the last ospf instance? */
302 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
303 && (listcount (om->ospf) == 0))
304 exit (0);
305
306 return;
307}
308
309/* Timer thread for G-R */
310static int
paulc9c93d52005-11-26 13:31:11 +0000311ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000312{
313 struct ospf *ospf = THREAD_ARG(t);
314
paulc9c93d52005-11-26 13:31:11 +0000315 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000316
317 return 0;
318}
319
paulc9c93d52005-11-26 13:31:11 +0000320/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000321 * down directly into second-half of instance shutdown.
322 */
323static void
paulc9c93d52005-11-26 13:31:11 +0000324ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000325{
326 unsigned long timeout;
327 struct listnode *ln;
328 struct ospf_area *area;
329
paulc9c93d52005-11-26 13:31:11 +0000330 /* deferred shutdown already running? */
331 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000332 return;
333
334 /* Should we try push out max-metric LSAs? */
335 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
336 {
337 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
338 {
339 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
340
341 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
Paul Jakmac363d382010-01-24 22:42:13 +0000342 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000343 }
344 timeout = ospf->stub_router_shutdown_time;
345 }
346 else
paulc9c93d52005-11-26 13:31:11 +0000347 {
348 /* No timer needed */
349 ospf_deferred_shutdown_finish (ospf);
350 return;
351 }
paul88d6cf32005-10-29 12:50:09 +0000352
paulc9c93d52005-11-26 13:31:11 +0000353 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000354 timeout);
355 return;
356}
357
358/* Shut down the entire process */
359void
360ospf_terminate (void)
361{
362 struct ospf *ospf;
363 struct listnode *node, *nnode;
364
365 /* shutdown already in progress */
366 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
367 return;
368
369 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
370
Andrew J. Schorr4056a542007-02-27 13:55:46 +0000371 /* exit immediately if OSPF not actually running */
372 if (listcount(om->ospf) == 0)
373 exit(0);
374
paul88d6cf32005-10-29 12:50:09 +0000375 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
376 ospf_finish (ospf);
377
378 /* Deliberately go back up, hopefully to thread scheduler, as
379 * One or more ospf_finish()'s may have deferred shutdown to a timer
380 * thread
381 */
382}
paul718e3742002-12-13 20:15:29 +0000383
384void
385ospf_finish (struct ospf *ospf)
386{
paulc9c93d52005-11-26 13:31:11 +0000387 /* let deferred shutdown decide */
388 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000389
paulc9c93d52005-11-26 13:31:11 +0000390 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000391 * deferred to expiry of G-S timer thread. Return back up, hopefully
392 * to thread scheduler.
393 */
paulc9c93d52005-11-26 13:31:11 +0000394 return;
paul88d6cf32005-10-29 12:50:09 +0000395}
396
397/* Final cleanup of ospf instance */
398static void
399ospf_finish_final (struct ospf *ospf)
400{
paul718e3742002-12-13 20:15:29 +0000401 struct route_node *rn;
402 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000403 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000404 struct ospf_interface *oi;
405 struct ospf_area *area;
406 struct ospf_vl_data *vl_data;
407 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000408 int i;
409
410#ifdef HAVE_OPAQUE_LSA
411 ospf_opaque_type11_lsa_term (ospf);
412#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000413
414 /* be nice if this worked, but it doesn't */
415 /*ospf_flush_self_originated_lsas_now (ospf);*/
416
417 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000418 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000419 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000420 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000421
paul1eb8ef22005-04-07 07:30:20 +0000422 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
423 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000424
paul1eb8ef22005-04-07 07:30:20 +0000425 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
426 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000427
428 list_delete (ospf->vlinks);
429
430 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
432 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000433
434 /* Clear static neighbors */
435 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
436 if ((nbr_nbma = rn->info))
437 {
438 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
439
440 if (nbr_nbma->nbr)
441 {
442 nbr_nbma->nbr->nbr_nbma = NULL;
443 nbr_nbma->nbr = NULL;
444 }
445
446 if (nbr_nbma->oi)
447 {
448 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
449 nbr_nbma->oi = NULL;
450 }
451
452 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
453 }
454
455 route_table_finish (ospf->nbr_nbma);
456
457 /* Clear networks and Areas. */
458 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
459 {
460 struct ospf_network *network;
461
462 if ((network = rn->info) != NULL)
463 {
paul68980082003-03-25 05:07:42 +0000464 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000465 rn->info = NULL;
466 route_unlock_node (rn);
467 }
468 }
469
paul1eb8ef22005-04-07 07:30:20 +0000470 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000471 {
paul718e3742002-12-13 20:15:29 +0000472 listnode_delete (ospf->areas, area);
473 ospf_area_free (area);
474 }
475
476 /* Cancel all timers. */
477 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000478 OSPF_TIMER_OFF (ospf->t_spf_calc);
479 OSPF_TIMER_OFF (ospf->t_ase_calc);
480 OSPF_TIMER_OFF (ospf->t_maxage);
481 OSPF_TIMER_OFF (ospf->t_maxage_walker);
482 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000483 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000484 OSPF_TIMER_OFF (ospf->t_distribute_update);
485 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
486 OSPF_TIMER_OFF (ospf->t_read);
487 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000488#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000489 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000490#endif
paul718e3742002-12-13 20:15:29 +0000491
492 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000493 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000494
495#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000496 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
497 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000498#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000499 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
500 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
501
paul718e3742002-12-13 20:15:29 +0000502 ospf_lsdb_delete_all (ospf->lsdb);
503 ospf_lsdb_free (ospf->lsdb);
504
paul1eb8ef22005-04-07 07:30:20 +0000505 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000506 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +0000507
508 list_delete (ospf->maxage_lsa);
509
510 if (ospf->old_table)
511 ospf_route_table_free (ospf->old_table);
512 if (ospf->new_table)
513 {
514 ospf_route_delete (ospf->new_table);
515 ospf_route_table_free (ospf->new_table);
516 }
517 if (ospf->old_rtrs)
518 ospf_rtrs_free (ospf->old_rtrs);
519 if (ospf->new_rtrs)
520 ospf_rtrs_free (ospf->new_rtrs);
521 if (ospf->new_external_route)
522 {
523 ospf_route_delete (ospf->new_external_route);
524 ospf_route_table_free (ospf->new_external_route);
525 }
526 if (ospf->old_external_route)
527 {
528 ospf_route_delete (ospf->old_external_route);
529 ospf_route_table_free (ospf->old_external_route);
530 }
531 if (ospf->external_lsas)
532 {
533 ospf_ase_external_lsas_finish (ospf->external_lsas);
534 }
535
536 list_delete (ospf->areas);
537
538 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
539 if (EXTERNAL_INFO (i) != NULL)
540 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
541 {
542 if (rn->info == NULL)
543 continue;
544
545 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
546 rn->info = NULL;
547 route_unlock_node (rn);
548 }
549
paul68980082003-03-25 05:07:42 +0000550 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000551 route_table_finish (ospf->distance_table);
552
paul020709f2003-04-04 02:44:16 +0000553 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000554
paul020709f2003-04-04 02:44:16 +0000555 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000556}
557
558
559/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000560static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000561ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000562{
563 struct ospf_area *new;
564
565 /* Allocate new config_network. */
566 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
567
paul68980082003-03-25 05:07:42 +0000568 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000569
570 new->area_id = area_id;
571
572 new->external_routing = OSPF_AREA_DEFAULT;
573 new->default_cost = 1;
574 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000575
paul718e3742002-12-13 20:15:29 +0000576 /* New LSDB init. */
577 new->lsdb = ospf_lsdb_new ();
578
579 /* Self-originated LSAs initialize. */
580 new->router_lsa_self = NULL;
581
582#ifdef HAVE_OPAQUE_LSA
583 ospf_opaque_type10_lsa_init (new);
584#endif /* HAVE_OPAQUE_LSA */
585
586 new->oiflist = list_new ();
587 new->ranges = route_table_init ();
588
589 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000590 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000591
592 return new;
593}
594
Stephen Hemminger917e2992009-12-03 19:07:00 +0300595static void
paul718e3742002-12-13 20:15:29 +0000596ospf_area_free (struct ospf_area *area)
597{
paul68980082003-03-25 05:07:42 +0000598 struct route_node *rn;
599 struct ospf_lsa *lsa;
600
paul718e3742002-12-13 20:15:29 +0000601 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000602 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
603 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
604 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
605 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
606 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
607 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
608 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
609 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000610
paul68980082003-03-25 05:07:42 +0000611 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
612 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000613#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000614 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
615 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
616 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
617 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000618#endif /* HAVE_OPAQUE_LSA */
619
620 ospf_lsdb_delete_all (area->lsdb);
621 ospf_lsdb_free (area->lsdb);
622
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000623 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000624
625 route_table_finish (area->ranges);
626 list_delete (area->oiflist);
627
628 if (EXPORT_NAME (area))
629 free (EXPORT_NAME (area));
630
631 if (IMPORT_NAME (area))
632 free (IMPORT_NAME (area));
633
634 /* Cancel timer. */
paul88d6cf32005-10-29 12:50:09 +0000635 OSPF_TIMER_OFF (area->t_stub_router);
636#ifdef HAVE_OPAQUE_LSA
637 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
638#endif /* HAVE_OPAQUE_LSA */
639
paul718e3742002-12-13 20:15:29 +0000640 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000641 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000642
643 XFREE (MTYPE_OSPF_AREA, area);
644}
645
646void
paul68980082003-03-25 05:07:42 +0000647ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000648{
649 struct ospf_area *area;
650
paul68980082003-03-25 05:07:42 +0000651 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000652 if (area &&
653 listcount (area->oiflist) == 0 &&
654 area->ranges->top == NULL &&
655 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
656 area->external_routing == OSPF_AREA_DEFAULT &&
657 area->no_summary == 0 &&
658 area->default_cost == 1 &&
659 EXPORT_NAME (area) == NULL &&
660 IMPORT_NAME (area) == NULL &&
661 area->auth_type == OSPF_AUTH_NULL)
662 {
paul68980082003-03-25 05:07:42 +0000663 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000664 ospf_area_free (area);
665 }
666}
667
668struct ospf_area *
paul68980082003-03-25 05:07:42 +0000669ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000670{
671 struct ospf_area *area;
672
paul68980082003-03-25 05:07:42 +0000673 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000674 if (!area)
675 {
paul68980082003-03-25 05:07:42 +0000676 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000677 area->format = format;
paul68980082003-03-25 05:07:42 +0000678 listnode_add_sort (ospf->areas, area);
679 ospf_check_abr_status (ospf);
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800680 if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
681 {
682 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
683 }
paul718e3742002-12-13 20:15:29 +0000684 }
685
686 return area;
687}
688
689struct ospf_area *
paul68980082003-03-25 05:07:42 +0000690ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000691{
692 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000693 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000694
paul1eb8ef22005-04-07 07:30:20 +0000695 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
696 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
697 return area;
paul718e3742002-12-13 20:15:29 +0000698
699 return NULL;
700}
701
702void
703ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
704{
705 listnode_add (area->oiflist, oi);
706}
707
708void
709ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
710{
711 listnode_delete (area->oiflist, oi);
712}
713
714
715/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000716static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000717ospf_network_new (struct in_addr area_id, int format)
718{
719 struct ospf_network *new;
720 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
721
722 new->area_id = area_id;
723 new->format = format;
724
725 return new;
726}
727
Stephen Hemminger917e2992009-12-03 19:07:00 +0300728static void
paul68980082003-03-25 05:07:42 +0000729ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000730{
paul68980082003-03-25 05:07:42 +0000731 ospf_area_check_free (ospf, network->area_id);
732 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000733 XFREE (MTYPE_OSPF_NETWORK, network);
734}
735
736int
737ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
738 struct in_addr area_id)
739{
740 struct ospf_network *network;
741 struct ospf_area *area;
742 struct route_node *rn;
743 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000744 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000745
746 rn = route_node_get (ospf->networks, (struct prefix *)p);
747 if (rn->info)
748 {
749 /* There is already same network statement. */
750 route_unlock_node (rn);
751 return 0;
752 }
753
754 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000755 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000756
757 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100758 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000759
760 /* Update connected redistribute. */
761 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
762 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
763 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
764 rn; rn = route_next (rn))
765 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000766 if (ospf_external_info_find_lsa (ospf, &ei->p))
767 if (!ospf_distribute_check_connected (ospf, ei))
768 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000769 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000770
paul68980082003-03-25 05:07:42 +0000771 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000772
773 return 1;
774}
775
776int
777ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
778 struct in_addr area_id)
779{
780 struct route_node *rn;
781 struct ospf_network *network;
782 struct external_info *ei;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100783 struct listnode *node, *nnode;
784 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000785
786 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
787 if (rn == NULL)
788 return 0;
789
790 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700791 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000792 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
793 return 0;
794
paul68980082003-03-25 05:07:42 +0000795 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000796 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700797 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000798
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100799 /* Find interfaces that not configured already. */
800 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
801 {
802 int found = 0;
803 struct connected *co = oi->connected;
804
805 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
806 continue;
807
808 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
809 {
810 if (rn->info == NULL)
811 continue;
812
813 if (ospf_network_match_iface(co,&rn->p))
814 {
815 found = 1;
816 route_unlock_node (rn);
817 break;
818 }
819 }
820
821 if (found == 0)
822 ospf_if_free (oi);
823 }
paul718e3742002-12-13 20:15:29 +0000824
825 /* Update connected redistribute. */
826 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
827 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
828 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
829 rn; rn = route_next (rn))
830 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000831 if (!ospf_external_info_find_lsa (ospf, &ei->p))
832 if (ospf_distribute_check_connected (ospf, ei))
833 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000834
835 return 1;
836}
837
paul570f7592003-01-25 06:47:41 +0000838/* Check whether interface matches given network
839 * returns: 1, true. 0, false
840 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300841static int
842ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000843{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000844 /* new approach: more elegant and conceptually clean */
845 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000846}
847
Stephen Hemminger917e2992009-12-03 19:07:00 +0300848static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100849ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
850 struct interface *ifp)
851{
852 struct listnode *cnode;
853 struct connected *co;
854
855 if (memcmp (ifp->name, "VLINK", 5) == 0)
856 return;
857
858 /* if interface prefix is match specified prefix,
859 then create socket and join multicast group. */
860 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
861 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200862
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100863 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
864 continue;
865
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100866 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200867 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100868 && ospf_network_match_iface(co,p))
869 {
870 struct ospf_interface *oi;
871
872 oi = ospf_if_new (area->ospf, ifp, co->address);
873 oi->connected = co;
874
875 oi->area = area;
876
877 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
878 oi->output_cost = ospf_if_get_output_cost (oi);
879
880 /* Add pseudo neighbor. */
881 ospf_nbr_add_self (oi);
882
883 /* Relate ospf interface to ospf instance. */
884 oi->ospf = area->ospf;
885
886 /* update network type as interface flag */
887 /* If network type is specified previously,
888 skip network type setting. */
889 oi->type = IF_DEF_PARAMS (ifp)->type;
890
891 ospf_area_add_if (oi->area, oi);
892
893 /* if router_id is not configured, dont bring up
894 * interfaces.
895 * ospf_router_id_update() will call ospf_if_update
896 * whenever r-id is configured instead.
897 */
898 if ((area->ospf->router_id.s_addr != 0)
899 && if_is_operative (ifp))
900 ospf_if_up (oi);
901 }
902 }
903}
904
Stephen Hemminger917e2992009-12-03 19:07:00 +0300905static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100906ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000907{
908 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000909 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000910
911 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100912 if (area->ospf->router_id.s_addr == 0)
913 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000914
paul718e3742002-12-13 20:15:29 +0000915 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000916 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100917 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000918}
919
920void
921ospf_ls_upd_queue_empty (struct ospf_interface *oi)
922{
923 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000924 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000925 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000926 struct ospf_lsa *lsa;
927
928 /* empty ls update queue */
929 for (rn = route_top (oi->ls_upd_queue); rn;
930 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000931 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000932 {
paul1eb8ef22005-04-07 07:30:20 +0000933 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000934 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000935 list_free (lst);
936 rn->info = NULL;
937 }
938
939 /* remove update event */
940 if (oi->t_ls_upd_event)
941 {
942 thread_cancel (oi->t_ls_upd_event);
943 oi->t_ls_upd_event = NULL;
944 }
945}
946
947void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100948ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000949{
950 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000951 struct ospf_network *network;
952 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100953
954 if (!ospf)
955 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000956
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100957 /* OSPF must be on and Router-ID must be configured. */
958 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100959 return;
960
961 /* Run each netowrk for this interface. */
962 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
963 if (rn->info != NULL)
964 {
965 network = (struct ospf_network *) rn->info;
966 area = ospf_area_get (ospf, network->area_id, network->format);
967 ospf_network_run_interface (&rn->p, area, ifp);
968 }
paul718e3742002-12-13 20:15:29 +0000969}
970
971void
paul68980082003-03-25 05:07:42 +0000972ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000973{
paul1eb8ef22005-04-07 07:30:20 +0000974 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000975 struct ospf_vl_data *vl_data;
976
paul1eb8ef22005-04-07 07:30:20 +0000977 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
978 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
979 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000980}
981
982
Stephen Hemminger7ba82f72009-05-15 10:47:45 -0700983static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +0000984{
985 { OSPF_AREA_DEFAULT, "Default" },
986 { OSPF_AREA_STUB, "Stub" },
987 { OSPF_AREA_NSSA, "NSSA" },
988};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -0700989static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +0000990
paul4dadc292005-05-06 21:37:42 +0000991static void
paul718e3742002-12-13 20:15:29 +0000992ospf_area_type_set (struct ospf_area *area, int type)
993{
hasso52dc7ee2004-09-23 19:18:23 +0000994 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000995 struct ospf_interface *oi;
996
997 if (area->external_routing == type)
998 {
999 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001000 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001001 inet_ntoa (area->area_id));
1002 return;
1003 }
1004
1005 area->external_routing = type;
1006
1007 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001008 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001009 LOOKUP (ospf_area_type_msg, type));
1010
1011 switch (area->external_routing)
1012 {
1013 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001014 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1015 if (oi->nbr_self != NULL)
1016 {
1017 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1018 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1019 }
paul718e3742002-12-13 20:15:29 +00001020 break;
1021 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001022 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1023 if (oi->nbr_self != NULL)
1024 {
1025 if (IS_DEBUG_OSPF_EVENT)
1026 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1027 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1028 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1029 if (IS_DEBUG_OSPF_EVENT)
1030 zlog_debug ("options set on %s: %x",
1031 IF_NAME (oi), OPTIONS (oi));
1032 }
paul718e3742002-12-13 20:15:29 +00001033 break;
1034 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001035 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1036 if (oi->nbr_self != NULL)
1037 {
1038 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1039 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1040 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1041 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1042 }
paul718e3742002-12-13 20:15:29 +00001043 break;
1044 default:
1045 break;
1046 }
1047
Paul Jakmac363d382010-01-24 22:42:13 +00001048 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001049 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001050}
1051
1052int
paul68980082003-03-25 05:07:42 +00001053ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001054{
1055 if (area->shortcut_configured == mode)
1056 return 0;
1057
1058 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001059 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001060 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001061
paul68980082003-03-25 05:07:42 +00001062 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001063
1064 return 1;
1065}
1066
1067int
paul68980082003-03-25 05:07:42 +00001068ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001069{
1070 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001071 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001072 ospf_area_check_free (ospf, area->area_id);
1073 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001074
1075 return 1;
1076}
1077
paul4dadc292005-05-06 21:37:42 +00001078static int
paul718e3742002-12-13 20:15:29 +00001079ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1080{
1081 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001082 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001083 int count = 0;
1084
paul1eb8ef22005-04-07 07:30:20 +00001085 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1086 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1087 count++;
paul718e3742002-12-13 20:15:29 +00001088
1089 return count;
1090}
1091
1092int
1093ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1094{
1095 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001096 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001097
paul68980082003-03-25 05:07:42 +00001098 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001099 if (ospf_area_vlink_count (ospf, area))
1100 return 0;
1101
1102 if (area->external_routing != OSPF_AREA_STUB)
1103 ospf_area_type_set (area, OSPF_AREA_STUB);
1104
1105 return 1;
1106}
1107
1108int
1109ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1110{
1111 struct ospf_area *area;
1112
paul68980082003-03-25 05:07:42 +00001113 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001114 if (area == NULL)
1115 return 1;
1116
1117 if (area->external_routing == OSPF_AREA_STUB)
1118 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1119
paul68980082003-03-25 05:07:42 +00001120 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001121
1122 return 1;
1123}
1124
1125int
1126ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1127{
1128 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001129 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001130
paul68980082003-03-25 05:07:42 +00001131 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001132 area->no_summary = 1;
1133
1134 return 1;
1135}
1136
1137int
1138ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1139{
1140 struct ospf_area *area;
1141
paul68980082003-03-25 05:07:42 +00001142 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001143 if (area == NULL)
1144 return 0;
1145
1146 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001147 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001148
1149 return 1;
1150}
1151
1152int
1153ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1154{
1155 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001156 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001157
paul68980082003-03-25 05:07:42 +00001158 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001159 if (ospf_area_vlink_count (ospf, area))
1160 return 0;
1161
1162 if (area->external_routing != OSPF_AREA_NSSA)
1163 {
1164 ospf_area_type_set (area, OSPF_AREA_NSSA);
1165 ospf->anyNSSA++;
1166 }
1167
paul084c7842003-06-22 08:35:18 +00001168 /* set NSSA area defaults */
1169 area->no_summary = 0;
1170 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001171 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001172 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1173
paul718e3742002-12-13 20:15:29 +00001174 return 1;
1175}
1176
1177int
1178ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1179{
1180 struct ospf_area *area;
1181
paul68980082003-03-25 05:07:42 +00001182 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001183 if (area == NULL)
1184 return 0;
1185
1186 if (area->external_routing == OSPF_AREA_NSSA)
1187 {
1188 ospf->anyNSSA--;
1189 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1190 }
1191
paul68980082003-03-25 05:07:42 +00001192 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001193
1194 return 1;
1195}
1196
1197int
1198ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1199 int role)
1200{
1201 struct ospf_area *area;
1202
paul68980082003-03-25 05:07:42 +00001203 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001204 if (area == NULL)
1205 return 0;
1206
paul084c7842003-06-22 08:35:18 +00001207 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001208
1209 return 1;
1210}
1211
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001212#if 0
paul4dadc292005-05-06 21:37:42 +00001213/* XXX: unused? Leave for symmetry? */
1214static int
paul718e3742002-12-13 20:15:29 +00001215ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1216 struct in_addr area_id)
1217{
1218 struct ospf_area *area;
1219
paul68980082003-03-25 05:07:42 +00001220 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001221 if (area == NULL)
1222 return 0;
1223
paul084c7842003-06-22 08:35:18 +00001224 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001225
paul68980082003-03-25 05:07:42 +00001226 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001227
1228 return 1;
1229}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001230#endif
paul718e3742002-12-13 20:15:29 +00001231
1232int
paul68980082003-03-25 05:07:42 +00001233ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001234 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001235{
1236 struct access_list *list;
1237 list = access_list_lookup (AFI_IP, list_name);
1238
1239 EXPORT_LIST (area) = list;
1240
1241 if (EXPORT_NAME (area))
1242 free (EXPORT_NAME (area));
1243
1244 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001245 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001246
1247 return 1;
1248}
1249
1250int
paul68980082003-03-25 05:07:42 +00001251ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001252{
1253
1254 EXPORT_LIST (area) = 0;
1255
1256 if (EXPORT_NAME (area))
1257 free (EXPORT_NAME (area));
1258
1259 EXPORT_NAME (area) = NULL;
1260
paul68980082003-03-25 05:07:42 +00001261 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001262
paul68980082003-03-25 05:07:42 +00001263 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001264
1265 return 1;
1266}
1267
1268int
paul6c835672004-10-11 11:00:30 +00001269ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1270 const char *name)
paul718e3742002-12-13 20:15:29 +00001271{
1272 struct access_list *list;
1273 list = access_list_lookup (AFI_IP, name);
1274
1275 IMPORT_LIST (area) = list;
1276
1277 if (IMPORT_NAME (area))
1278 free (IMPORT_NAME (area));
1279
1280 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001281 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001282
1283 return 1;
1284}
1285
1286int
paul68980082003-03-25 05:07:42 +00001287ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001288{
1289 IMPORT_LIST (area) = 0;
1290
1291 if (IMPORT_NAME (area))
1292 free (IMPORT_NAME (area));
1293
1294 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001295 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001296
paul68980082003-03-25 05:07:42 +00001297 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001298
1299 return 1;
1300}
1301
1302int
paul718e3742002-12-13 20:15:29 +00001303ospf_timers_refresh_set (struct ospf *ospf, int interval)
1304{
1305 int time_left;
1306
1307 if (ospf->lsa_refresh_interval == interval)
1308 return 1;
1309
1310 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001311 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001312
1313 if (time_left > interval)
1314 {
1315 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1316 ospf->t_lsa_refresher =
1317 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1318 }
1319 ospf->lsa_refresh_interval = interval;
1320
1321 return 1;
1322}
1323
1324int
1325ospf_timers_refresh_unset (struct ospf *ospf)
1326{
1327 int time_left;
1328
1329 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001330 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001331
1332 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1333 {
1334 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1335 ospf->t_lsa_refresher =
1336 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1337 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1338 }
1339
1340 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1341
1342 return 1;
1343}
1344
1345
paul4dadc292005-05-06 21:37:42 +00001346static struct ospf_nbr_nbma *
1347ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001348{
1349 struct ospf_nbr_nbma *nbr_nbma;
1350
Stephen Hemminger393deb92008-08-18 14:13:29 -07001351 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001352 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001353
1354 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1355 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1356
1357 return nbr_nbma;
1358}
1359
paul4dadc292005-05-06 21:37:42 +00001360static void
paul718e3742002-12-13 20:15:29 +00001361ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1362{
1363 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1364}
1365
paul4dadc292005-05-06 21:37:42 +00001366static void
paul718e3742002-12-13 20:15:29 +00001367ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1368{
1369 struct route_node *rn;
1370 struct prefix_ipv4 p;
1371
1372 p.family = AF_INET;
1373 p.prefix = nbr_nbma->addr;
1374 p.prefixlen = IPV4_MAX_BITLEN;
1375
1376 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1377 if (rn)
1378 {
1379 ospf_nbr_nbma_free (rn->info);
1380 rn->info = NULL;
1381 route_unlock_node (rn);
1382 route_unlock_node (rn);
1383 }
1384}
1385
paul4dadc292005-05-06 21:37:42 +00001386static void
paul718e3742002-12-13 20:15:29 +00001387ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1388{
1389 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1390
1391 if (nbr_nbma->nbr)
1392 {
1393 nbr_nbma->nbr->nbr_nbma = NULL;
1394 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1395 }
1396
1397 if (nbr_nbma->oi)
1398 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1399}
1400
paul4dadc292005-05-06 21:37:42 +00001401static void
paul718e3742002-12-13 20:15:29 +00001402ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1403 struct ospf_interface *oi)
1404{
1405 struct ospf_neighbor *nbr;
1406 struct route_node *rn;
1407 struct prefix p;
1408
1409 if (oi->type != OSPF_IFTYPE_NBMA)
1410 return;
1411
1412 if (nbr_nbma->nbr != NULL)
1413 return;
1414
1415 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1416 return;
1417
1418 nbr_nbma->oi = oi;
1419 listnode_add (oi->nbr_nbma, nbr_nbma);
1420
1421 /* Get neighbor information from table. */
1422 p.family = AF_INET;
1423 p.prefixlen = IPV4_MAX_BITLEN;
1424 p.u.prefix4 = nbr_nbma->addr;
1425
1426 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1427 if (rn->info)
1428 {
1429 nbr = rn->info;
1430 nbr->nbr_nbma = nbr_nbma;
1431 nbr_nbma->nbr = nbr;
1432
1433 route_unlock_node (rn);
1434 }
1435 else
1436 {
1437 nbr = rn->info = ospf_nbr_new (oi);
1438 nbr->state = NSM_Down;
1439 nbr->src = nbr_nbma->addr;
1440 nbr->nbr_nbma = nbr_nbma;
1441 nbr->priority = nbr_nbma->priority;
1442 nbr->address = p;
1443
1444 nbr_nbma->nbr = nbr;
1445
1446 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1447 }
1448}
1449
1450void
paul68980082003-03-25 05:07:42 +00001451ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001452{
1453 struct ospf_nbr_nbma *nbr_nbma;
1454 struct route_node *rn;
1455 struct prefix_ipv4 p;
1456
1457 if (oi->type != OSPF_IFTYPE_NBMA)
1458 return;
1459
paul68980082003-03-25 05:07:42 +00001460 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001461 if ((nbr_nbma = rn->info))
1462 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1463 {
1464 p.family = AF_INET;
1465 p.prefix = nbr_nbma->addr;
1466 p.prefixlen = IPV4_MAX_BITLEN;
1467
1468 if (prefix_match (oi->address, (struct prefix *)&p))
1469 ospf_nbr_nbma_add (nbr_nbma, oi);
1470 }
1471}
1472
1473struct ospf_nbr_nbma *
1474ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1475{
1476 struct route_node *rn;
1477 struct prefix_ipv4 p;
1478
1479 p.family = AF_INET;
1480 p.prefix = nbr_addr;
1481 p.prefixlen = IPV4_MAX_BITLEN;
1482
1483 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1484 if (rn)
1485 {
1486 route_unlock_node (rn);
1487 return rn->info;
1488 }
1489 return NULL;
1490}
1491
1492struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001493ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001494{
1495#if 0
1496 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001497 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001498#endif
1499
paul68980082003-03-25 05:07:42 +00001500 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001501 return NULL;
1502
1503#if 0
paul1eb8ef22005-04-07 07:30:20 +00001504 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001505 {
paul718e3742002-12-13 20:15:29 +00001506 if (first)
1507 {
1508 *addr = nbr_nbma->addr;
1509 return nbr_nbma;
1510 }
1511 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1512 {
1513 *addr = nbr_nbma->addr;
1514 return nbr_nbma;
1515 }
1516 }
1517#endif
1518 return NULL;
1519}
1520
1521int
1522ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1523{
1524 struct ospf_nbr_nbma *nbr_nbma;
1525 struct ospf_interface *oi;
1526 struct prefix_ipv4 p;
1527 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001528 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001529
1530 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1531 if (nbr_nbma)
1532 return 0;
1533
1534 nbr_nbma = ospf_nbr_nbma_new ();
1535 nbr_nbma->addr = nbr_addr;
1536
1537 p.family = AF_INET;
1538 p.prefix = nbr_addr;
1539 p.prefixlen = IPV4_MAX_BITLEN;
1540
1541 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1542 rn->info = nbr_nbma;
1543
paul1eb8ef22005-04-07 07:30:20 +00001544 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001545 {
paul718e3742002-12-13 20:15:29 +00001546 if (oi->type == OSPF_IFTYPE_NBMA)
1547 if (prefix_match (oi->address, (struct prefix *)&p))
1548 {
1549 ospf_nbr_nbma_add (nbr_nbma, oi);
1550 break;
1551 }
1552 }
1553
1554 return 1;
1555}
1556
1557int
1558ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1559{
1560 struct ospf_nbr_nbma *nbr_nbma;
1561
1562 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1563 if (nbr_nbma == NULL)
1564 return 0;
1565
1566 ospf_nbr_nbma_down (nbr_nbma);
1567 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1568
1569 return 1;
1570}
1571
1572int
1573ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1574 u_char priority)
1575{
1576 struct ospf_nbr_nbma *nbr_nbma;
1577
1578 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1579 if (nbr_nbma == NULL)
1580 return 0;
1581
1582 if (nbr_nbma->priority != priority)
1583 nbr_nbma->priority = priority;
1584
1585 return 1;
1586}
1587
1588int
1589ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1590{
1591 struct ospf_nbr_nbma *nbr_nbma;
1592
1593 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1594 if (nbr_nbma == NULL)
1595 return 0;
1596
1597 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1598 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1599
1600 return 1;
1601}
1602
1603int
1604ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001605 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001606{
1607 struct ospf_nbr_nbma *nbr_nbma;
1608
1609 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1610 if (nbr_nbma == NULL)
1611 return 0;
1612
1613 if (nbr_nbma->v_poll != interval)
1614 {
1615 nbr_nbma->v_poll = interval;
1616 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1617 {
1618 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1619 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1620 nbr_nbma->v_poll);
1621 }
1622 }
1623
1624 return 1;
1625}
1626
1627int
1628ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1629{
1630 struct ospf_nbr_nbma *nbr_nbma;
1631
1632 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1633 if (nbr_nbma == NULL)
1634 return 0;
1635
1636 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1637 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1638
1639 return 1;
1640}
1641
paul718e3742002-12-13 20:15:29 +00001642void
paul020709f2003-04-04 02:44:16 +00001643ospf_master_init ()
1644{
1645 memset (&ospf_master, 0, sizeof (struct ospf_master));
1646
1647 om = &ospf_master;
1648 om->ospf = list_new ();
1649 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001650 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001651}