blob: 1a549c3aa0de4856f51f9946296a32bf74f94c64 [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
David Lamparter6b0655a2014-06-04 06:53:35 +020056
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
David Lamparter6b0655a2014-06-04 06:53:35 +020067
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
David Lamparter6b0655a2014-06-04 06:53:35 +020079
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))
Joakim Tjernlund94266fa2009-11-19 15:27:30 +0100115 {
116 /* Some nbrs are identified by router_id, these needs
117 * to be rebuilt. Possible optimization would be to do
118 * oi->nbr_self->router_id = router_id for
119 * !(virtual | ptop) links
120 */
Paul Jakmac920e512015-09-08 15:31:45 +0100121 ospf_nbr_self_reset (oi);
Joakim Tjernlund94266fa2009-11-19 15:27:30 +0100122 }
paul718e3742002-12-13 20:15:29 +0000123
124 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000125 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000126 {
127 int type;
128 /* Originate each redistributed external route. */
129 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000130 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000131 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000132 ospf, type);
paul718e3742002-12-13 20:15:29 +0000133 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000134 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
Paul Jakma4021b602006-05-12 22:55:41 +0000135 thread_add_event (master, ospf_default_originate_timer, ospf, 0);
paul718e3742002-12-13 20:15:29 +0000136
paul68980082003-03-25 05:07:42 +0000137 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000138 }
139
Paul Jakmac363d382010-01-24 22:42:13 +0000140 /* update router-lsa's for each area */
141 ospf_router_lsa_update (ospf);
paulb29800a2005-11-20 14:50:45 +0000142
143 /* update ospf_interface's */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100144 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
145 ospf_if_update (ospf, ifp);
paul718e3742002-12-13 20:15:29 +0000146 }
147}
David Lamparter6b0655a2014-06-04 06:53:35 +0200148
paul718e3742002-12-13 20:15:29 +0000149/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000150static int
paul718e3742002-12-13 20:15:29 +0000151ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
152{
153 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
154 return 1;
155 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
156 return -1;
157 return 0;
158}
159
160/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000161static struct ospf *
162ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000163{
164 int i;
165
166 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
167
168 new->router_id.s_addr = htonl (0);
169 new->router_id_static.s_addr = htonl (0);
170
pauld57834f2005-07-12 20:04:22 +0000171 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000172 new->oiflist = list_new ();
173 new->vlinks = list_new ();
174 new->areas = list_new ();
175 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
176 new->networks = route_table_init ();
177 new->nbr_nbma = route_table_init ();
178
179 new->lsdb = ospf_lsdb_new ();
180
181 new->default_originate = DEFAULT_ORIGINATE_NONE;
182
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000183 new->passive_interface_default = OSPF_IF_ACTIVE;
184
paul718e3742002-12-13 20:15:29 +0000185 new->new_external_route = route_table_init ();
186 new->old_external_route = route_table_init ();
187 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000188
189 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000190 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800191 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
192
paul718e3742002-12-13 20:15:29 +0000193 /* Distribute parameter init. */
194 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
195 {
196 new->dmetric[i].type = -1;
197 new->dmetric[i].value = -1;
198 }
199 new->default_metric = -1;
200 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
201
202 /* SPF timer value init. */
203 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
204 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000205 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
206 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000207
208 /* MaxAge init. */
Dinesh Dutt2449fcd2013-08-24 07:54:17 +0000209 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800210 new->maxage_lsa = route_table_init();
paul718e3742002-12-13 20:15:29 +0000211 new->t_maxage_walker =
212 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000213 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000214
215 /* Distance table init. */
216 new->distance_table = route_table_init ();
217
218 new->lsa_refresh_queue.index = 0;
219 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
220 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
221 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000222 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000223
ajs5c333492005-02-23 15:43:01 +0000224 if ((new->fd = ospf_sock_init()) < 0)
225 {
226 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
227 "a socket");
228 exit(1);
229 }
Denis Ovsienkof102e752007-09-18 09:01:13 +0000230 new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
231 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
Andrew Certain0798cee2012-12-04 13:43:42 -0800232 zlog_debug ("%s: starting with OSPF send buffer size %u",
Denis Ovsienkof102e752007-09-18 09:01:13 +0000233 __func__, new->maxsndbuflen);
ajs5c333492005-02-23 15:43:01 +0000234 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
235 {
236 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
237 OSPF_MAX_PACKET_SIZE+1);
238 exit(1);
239 }
240 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000241 new->oi_write_q = list_new ();
242
243 return new;
244}
245
246struct ospf *
paul020709f2003-04-04 02:44:16 +0000247ospf_lookup ()
248{
249 if (listcount (om->ospf) == 0)
250 return NULL;
251
paul1eb8ef22005-04-07 07:30:20 +0000252 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000253}
254
paul4dadc292005-05-06 21:37:42 +0000255static void
paul020709f2003-04-04 02:44:16 +0000256ospf_add (struct ospf *ospf)
257{
258 listnode_add (om->ospf, ospf);
259}
260
paul4dadc292005-05-06 21:37:42 +0000261static void
paul020709f2003-04-04 02:44:16 +0000262ospf_delete (struct ospf *ospf)
263{
264 listnode_delete (om->ospf, ospf);
265}
266
267struct ospf *
paul718e3742002-12-13 20:15:29 +0000268ospf_get ()
269{
paul020709f2003-04-04 02:44:16 +0000270 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000271
paul020709f2003-04-04 02:44:16 +0000272 ospf = ospf_lookup ();
273 if (ospf == NULL)
274 {
275 ospf = ospf_new ();
276 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000277
paul020709f2003-04-04 02:44:16 +0000278 if (ospf->router_id_static.s_addr == 0)
279 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000280
281#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000282 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000283#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000284 }
paul68980082003-03-25 05:07:42 +0000285
286 return ospf;
paul718e3742002-12-13 20:15:29 +0000287}
David Lamparter6b0655a2014-06-04 06:53:35 +0200288
paulc9c93d52005-11-26 13:31:11 +0000289/* Handle the second half of deferred shutdown. This is called either
290 * from the deferred-shutdown timer thread, or directly through
291 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000292 *
293 * Function is to cleanup G-R state, if required then call ospf_finish_final
294 * to complete shutdown of this ospf instance. Possibly exit if the
295 * whole process is being shutdown and this was the last OSPF instance.
296 */
297static void
paulc9c93d52005-11-26 13:31:11 +0000298ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000299{
300 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000301 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000302
303 ospf_finish_final (ospf);
304
305 /* *ospf is now invalid */
306
307 /* ospfd being shut-down? If so, was this the last ospf instance? */
308 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
309 && (listcount (om->ospf) == 0))
310 exit (0);
311
312 return;
313}
314
315/* Timer thread for G-R */
316static int
paulc9c93d52005-11-26 13:31:11 +0000317ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000318{
319 struct ospf *ospf = THREAD_ARG(t);
320
paulc9c93d52005-11-26 13:31:11 +0000321 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000322
323 return 0;
324}
325
paulc9c93d52005-11-26 13:31:11 +0000326/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000327 * down directly into second-half of instance shutdown.
328 */
329static void
paulc9c93d52005-11-26 13:31:11 +0000330ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000331{
332 unsigned long timeout;
333 struct listnode *ln;
334 struct ospf_area *area;
335
paulc9c93d52005-11-26 13:31:11 +0000336 /* deferred shutdown already running? */
337 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000338 return;
339
340 /* Should we try push out max-metric LSAs? */
341 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
342 {
343 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
344 {
345 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
346
347 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
Paul Jakmac363d382010-01-24 22:42:13 +0000348 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000349 }
350 timeout = ospf->stub_router_shutdown_time;
351 }
352 else
paulc9c93d52005-11-26 13:31:11 +0000353 {
354 /* No timer needed */
355 ospf_deferred_shutdown_finish (ospf);
356 return;
357 }
paul88d6cf32005-10-29 12:50:09 +0000358
paulc9c93d52005-11-26 13:31:11 +0000359 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000360 timeout);
361 return;
362}
David Lamparter6b0655a2014-06-04 06:53:35 +0200363
paul88d6cf32005-10-29 12:50:09 +0000364/* Shut down the entire process */
365void
366ospf_terminate (void)
367{
368 struct ospf *ospf;
369 struct listnode *node, *nnode;
370
371 /* shutdown already in progress */
372 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
373 return;
374
375 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
376
Andrew J. Schorr4056a542007-02-27 13:55:46 +0000377 /* exit immediately if OSPF not actually running */
378 if (listcount(om->ospf) == 0)
379 exit(0);
380
paul88d6cf32005-10-29 12:50:09 +0000381 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
382 ospf_finish (ospf);
383
384 /* Deliberately go back up, hopefully to thread scheduler, as
385 * One or more ospf_finish()'s may have deferred shutdown to a timer
386 * thread
387 */
388}
paul718e3742002-12-13 20:15:29 +0000389
390void
391ospf_finish (struct ospf *ospf)
392{
paulc9c93d52005-11-26 13:31:11 +0000393 /* let deferred shutdown decide */
394 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000395
paulc9c93d52005-11-26 13:31:11 +0000396 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000397 * deferred to expiry of G-S timer thread. Return back up, hopefully
398 * to thread scheduler.
399 */
paulc9c93d52005-11-26 13:31:11 +0000400 return;
paul88d6cf32005-10-29 12:50:09 +0000401}
402
403/* Final cleanup of ospf instance */
404static void
405ospf_finish_final (struct ospf *ospf)
406{
paul718e3742002-12-13 20:15:29 +0000407 struct route_node *rn;
408 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000409 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000410 struct ospf_interface *oi;
411 struct ospf_area *area;
412 struct ospf_vl_data *vl_data;
413 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000414 int i;
415
416#ifdef HAVE_OPAQUE_LSA
417 ospf_opaque_type11_lsa_term (ospf);
418#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000419
420 /* be nice if this worked, but it doesn't */
421 /*ospf_flush_self_originated_lsas_now (ospf);*/
422
423 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000424 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000425 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000426 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000427
paul1eb8ef22005-04-07 07:30:20 +0000428 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
429 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000430
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
432 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000433
434 list_delete (ospf->vlinks);
435
436 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000437 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
438 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000439
440 /* Clear static neighbors */
441 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
442 if ((nbr_nbma = rn->info))
443 {
444 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
445
446 if (nbr_nbma->nbr)
447 {
448 nbr_nbma->nbr->nbr_nbma = NULL;
449 nbr_nbma->nbr = NULL;
450 }
451
452 if (nbr_nbma->oi)
453 {
454 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
455 nbr_nbma->oi = NULL;
456 }
457
458 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
459 }
460
461 route_table_finish (ospf->nbr_nbma);
462
463 /* Clear networks and Areas. */
464 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
465 {
466 struct ospf_network *network;
467
468 if ((network = rn->info) != NULL)
469 {
paul68980082003-03-25 05:07:42 +0000470 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000471 rn->info = NULL;
472 route_unlock_node (rn);
473 }
474 }
475
paul1eb8ef22005-04-07 07:30:20 +0000476 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000477 {
paul718e3742002-12-13 20:15:29 +0000478 listnode_delete (ospf->areas, area);
479 ospf_area_free (area);
480 }
481
482 /* Cancel all timers. */
483 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000484 OSPF_TIMER_OFF (ospf->t_spf_calc);
485 OSPF_TIMER_OFF (ospf->t_ase_calc);
486 OSPF_TIMER_OFF (ospf->t_maxage);
487 OSPF_TIMER_OFF (ospf->t_maxage_walker);
488 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000489 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000490 OSPF_TIMER_OFF (ospf->t_distribute_update);
491 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
492 OSPF_TIMER_OFF (ospf->t_read);
493 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000494#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000495 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000496#endif
paul718e3742002-12-13 20:15:29 +0000497
498 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000499 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000500
501#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000502 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
503 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000504#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000505 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
506 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
507
paul718e3742002-12-13 20:15:29 +0000508 ospf_lsdb_delete_all (ospf->lsdb);
509 ospf_lsdb_free (ospf->lsdb);
510
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800511 for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
512 {
513 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000514
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800515 if ((lsa = rn->info) != NULL)
516 {
517 ospf_lsa_unlock (&lsa);
518 rn->info = NULL;
519 }
520 route_unlock_node (rn);
521 }
522 route_table_finish (ospf->maxage_lsa);
paul718e3742002-12-13 20:15:29 +0000523
524 if (ospf->old_table)
525 ospf_route_table_free (ospf->old_table);
526 if (ospf->new_table)
527 {
528 ospf_route_delete (ospf->new_table);
529 ospf_route_table_free (ospf->new_table);
530 }
531 if (ospf->old_rtrs)
532 ospf_rtrs_free (ospf->old_rtrs);
533 if (ospf->new_rtrs)
534 ospf_rtrs_free (ospf->new_rtrs);
535 if (ospf->new_external_route)
536 {
537 ospf_route_delete (ospf->new_external_route);
538 ospf_route_table_free (ospf->new_external_route);
539 }
540 if (ospf->old_external_route)
541 {
542 ospf_route_delete (ospf->old_external_route);
543 ospf_route_table_free (ospf->old_external_route);
544 }
545 if (ospf->external_lsas)
546 {
547 ospf_ase_external_lsas_finish (ospf->external_lsas);
548 }
549
550 list_delete (ospf->areas);
551
552 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
553 if (EXTERNAL_INFO (i) != NULL)
554 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
555 {
556 if (rn->info == NULL)
557 continue;
558
559 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
560 rn->info = NULL;
561 route_unlock_node (rn);
562 }
563
paul68980082003-03-25 05:07:42 +0000564 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000565 route_table_finish (ospf->distance_table);
566
paul020709f2003-04-04 02:44:16 +0000567 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000568
paul020709f2003-04-04 02:44:16 +0000569 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000570}
571
David Lamparter6b0655a2014-06-04 06:53:35 +0200572
paul718e3742002-12-13 20:15:29 +0000573/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000574static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000575ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000576{
577 struct ospf_area *new;
578
579 /* Allocate new config_network. */
580 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
581
paul68980082003-03-25 05:07:42 +0000582 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000583
584 new->area_id = area_id;
585
586 new->external_routing = OSPF_AREA_DEFAULT;
587 new->default_cost = 1;
588 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000589
paul718e3742002-12-13 20:15:29 +0000590 /* New LSDB init. */
591 new->lsdb = ospf_lsdb_new ();
592
593 /* Self-originated LSAs initialize. */
594 new->router_lsa_self = NULL;
595
596#ifdef HAVE_OPAQUE_LSA
597 ospf_opaque_type10_lsa_init (new);
598#endif /* HAVE_OPAQUE_LSA */
599
600 new->oiflist = list_new ();
601 new->ranges = route_table_init ();
602
603 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000604 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000605
606 return new;
607}
608
Stephen Hemminger917e2992009-12-03 19:07:00 +0300609static void
paul718e3742002-12-13 20:15:29 +0000610ospf_area_free (struct ospf_area *area)
611{
paul68980082003-03-25 05:07:42 +0000612 struct route_node *rn;
613 struct ospf_lsa *lsa;
614
paul718e3742002-12-13 20:15:29 +0000615 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000616 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
617 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
618 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
619 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
620 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
621 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
622 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
623 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000624
paul68980082003-03-25 05:07:42 +0000625 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
626 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000627#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000628 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
629 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
630 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
631 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000632#endif /* HAVE_OPAQUE_LSA */
633
634 ospf_lsdb_delete_all (area->lsdb);
635 ospf_lsdb_free (area->lsdb);
636
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000637 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000638
639 route_table_finish (area->ranges);
640 list_delete (area->oiflist);
641
642 if (EXPORT_NAME (area))
643 free (EXPORT_NAME (area));
644
645 if (IMPORT_NAME (area))
646 free (IMPORT_NAME (area));
647
648 /* Cancel timer. */
paul88d6cf32005-10-29 12:50:09 +0000649 OSPF_TIMER_OFF (area->t_stub_router);
650#ifdef HAVE_OPAQUE_LSA
651 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
652#endif /* HAVE_OPAQUE_LSA */
653
paul718e3742002-12-13 20:15:29 +0000654 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000655 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000656
657 XFREE (MTYPE_OSPF_AREA, area);
658}
659
660void
paul68980082003-03-25 05:07:42 +0000661ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000662{
663 struct ospf_area *area;
664
paul68980082003-03-25 05:07:42 +0000665 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000666 if (area &&
667 listcount (area->oiflist) == 0 &&
668 area->ranges->top == NULL &&
669 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
670 area->external_routing == OSPF_AREA_DEFAULT &&
671 area->no_summary == 0 &&
672 area->default_cost == 1 &&
673 EXPORT_NAME (area) == NULL &&
674 IMPORT_NAME (area) == NULL &&
675 area->auth_type == OSPF_AUTH_NULL)
676 {
paul68980082003-03-25 05:07:42 +0000677 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000678 ospf_area_free (area);
679 }
680}
681
682struct ospf_area *
paul68980082003-03-25 05:07:42 +0000683ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000684{
685 struct ospf_area *area;
686
paul68980082003-03-25 05:07:42 +0000687 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000688 if (!area)
689 {
paul68980082003-03-25 05:07:42 +0000690 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000691 area->format = format;
paul68980082003-03-25 05:07:42 +0000692 listnode_add_sort (ospf->areas, area);
693 ospf_check_abr_status (ospf);
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800694 if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
695 {
696 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
697 }
paul718e3742002-12-13 20:15:29 +0000698 }
699
700 return area;
701}
702
703struct ospf_area *
paul68980082003-03-25 05:07:42 +0000704ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000705{
706 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000707 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000708
paul1eb8ef22005-04-07 07:30:20 +0000709 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
710 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
711 return area;
paul718e3742002-12-13 20:15:29 +0000712
713 return NULL;
714}
715
716void
717ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
718{
719 listnode_add (area->oiflist, oi);
720}
721
722void
723ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
724{
725 listnode_delete (area->oiflist, oi);
726}
727
David Lamparter6b0655a2014-06-04 06:53:35 +0200728
paul718e3742002-12-13 20:15:29 +0000729/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000730static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000731ospf_network_new (struct in_addr area_id, int format)
732{
733 struct ospf_network *new;
734 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
735
736 new->area_id = area_id;
737 new->format = format;
738
739 return new;
740}
741
Stephen Hemminger917e2992009-12-03 19:07:00 +0300742static void
paul68980082003-03-25 05:07:42 +0000743ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000744{
paul68980082003-03-25 05:07:42 +0000745 ospf_area_check_free (ospf, network->area_id);
746 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000747 XFREE (MTYPE_OSPF_NETWORK, network);
748}
749
750int
751ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
752 struct in_addr area_id)
753{
754 struct ospf_network *network;
755 struct ospf_area *area;
756 struct route_node *rn;
757 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000758 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000759
760 rn = route_node_get (ospf->networks, (struct prefix *)p);
761 if (rn->info)
762 {
763 /* There is already same network statement. */
764 route_unlock_node (rn);
765 return 0;
766 }
767
768 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000769 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000770
771 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100772 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000773
774 /* Update connected redistribute. */
775 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
776 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
777 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
778 rn; rn = route_next (rn))
779 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000780 if (ospf_external_info_find_lsa (ospf, &ei->p))
781 if (!ospf_distribute_check_connected (ospf, ei))
782 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000783 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000784
paul68980082003-03-25 05:07:42 +0000785 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000786
787 return 1;
788}
789
790int
791ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
792 struct in_addr area_id)
793{
794 struct route_node *rn;
795 struct ospf_network *network;
796 struct external_info *ei;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100797 struct listnode *node, *nnode;
798 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000799
800 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
801 if (rn == NULL)
802 return 0;
803
804 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700805 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000806 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
807 return 0;
808
paul68980082003-03-25 05:07:42 +0000809 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000810 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700811 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000812
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100813 /* Find interfaces that not configured already. */
814 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
815 {
816 int found = 0;
817 struct connected *co = oi->connected;
818
819 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
820 continue;
821
822 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
823 {
824 if (rn->info == NULL)
825 continue;
826
827 if (ospf_network_match_iface(co,&rn->p))
828 {
829 found = 1;
830 route_unlock_node (rn);
831 break;
832 }
833 }
834
835 if (found == 0)
Joakim Tjernlund6b274d92010-03-09 06:42:30 +0000836 {
837 ospf_if_free (oi);
838 ospf_area_check_free (ospf, area_id);
839 }
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100840 }
paul718e3742002-12-13 20:15:29 +0000841
842 /* Update connected redistribute. */
843 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
844 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
845 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
846 rn; rn = route_next (rn))
847 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000848 if (!ospf_external_info_find_lsa (ospf, &ei->p))
849 if (ospf_distribute_check_connected (ospf, ei))
850 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000851
852 return 1;
853}
854
paul570f7592003-01-25 06:47:41 +0000855/* Check whether interface matches given network
856 * returns: 1, true. 0, false
857 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300858static int
859ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000860{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000861 /* new approach: more elegant and conceptually clean */
862 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000863}
864
Stephen Hemminger917e2992009-12-03 19:07:00 +0300865static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100866ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
867 struct interface *ifp)
868{
869 struct listnode *cnode;
870 struct connected *co;
871
872 if (memcmp (ifp->name, "VLINK", 5) == 0)
873 return;
874
875 /* if interface prefix is match specified prefix,
876 then create socket and join multicast group. */
877 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
878 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200879
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100880 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
881 continue;
882
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100883 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200884 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100885 && ospf_network_match_iface(co,p))
886 {
887 struct ospf_interface *oi;
888
889 oi = ospf_if_new (area->ospf, ifp, co->address);
890 oi->connected = co;
891
892 oi->area = area;
893
894 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
895 oi->output_cost = ospf_if_get_output_cost (oi);
896
897 /* Add pseudo neighbor. */
898 ospf_nbr_add_self (oi);
899
900 /* Relate ospf interface to ospf instance. */
901 oi->ospf = area->ospf;
902
903 /* update network type as interface flag */
904 /* If network type is specified previously,
905 skip network type setting. */
906 oi->type = IF_DEF_PARAMS (ifp)->type;
907
908 ospf_area_add_if (oi->area, oi);
909
910 /* if router_id is not configured, dont bring up
911 * interfaces.
912 * ospf_router_id_update() will call ospf_if_update
913 * whenever r-id is configured instead.
914 */
915 if ((area->ospf->router_id.s_addr != 0)
916 && if_is_operative (ifp))
917 ospf_if_up (oi);
918 }
919 }
920}
921
Stephen Hemminger917e2992009-12-03 19:07:00 +0300922static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100923ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000924{
925 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000926 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000927
928 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100929 if (area->ospf->router_id.s_addr == 0)
930 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000931
paul718e3742002-12-13 20:15:29 +0000932 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000933 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100934 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000935}
936
937void
938ospf_ls_upd_queue_empty (struct ospf_interface *oi)
939{
940 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000941 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000942 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000943 struct ospf_lsa *lsa;
944
945 /* empty ls update queue */
946 for (rn = route_top (oi->ls_upd_queue); rn;
947 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000948 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000949 {
paul1eb8ef22005-04-07 07:30:20 +0000950 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000951 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000952 list_free (lst);
953 rn->info = NULL;
954 }
955
956 /* remove update event */
957 if (oi->t_ls_upd_event)
958 {
959 thread_cancel (oi->t_ls_upd_event);
960 oi->t_ls_upd_event = NULL;
961 }
962}
963
964void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100965ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000966{
967 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000968 struct ospf_network *network;
969 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100970
971 if (!ospf)
972 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000973
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100974 /* OSPF must be on and Router-ID must be configured. */
975 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100976 return;
977
978 /* Run each netowrk for this interface. */
979 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
980 if (rn->info != NULL)
981 {
982 network = (struct ospf_network *) rn->info;
983 area = ospf_area_get (ospf, network->area_id, network->format);
984 ospf_network_run_interface (&rn->p, area, ifp);
985 }
paul718e3742002-12-13 20:15:29 +0000986}
987
988void
paul68980082003-03-25 05:07:42 +0000989ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000990{
paul1eb8ef22005-04-07 07:30:20 +0000991 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000992 struct ospf_vl_data *vl_data;
993
paul1eb8ef22005-04-07 07:30:20 +0000994 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
995 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
996 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000997}
998
David Lamparter6b0655a2014-06-04 06:53:35 +0200999
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001000static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +00001001{
1002 { OSPF_AREA_DEFAULT, "Default" },
1003 { OSPF_AREA_STUB, "Stub" },
1004 { OSPF_AREA_NSSA, "NSSA" },
1005};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001006static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +00001007
paul4dadc292005-05-06 21:37:42 +00001008static void
paul718e3742002-12-13 20:15:29 +00001009ospf_area_type_set (struct ospf_area *area, int type)
1010{
hasso52dc7ee2004-09-23 19:18:23 +00001011 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001012 struct ospf_interface *oi;
1013
1014 if (area->external_routing == type)
1015 {
1016 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001017 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001018 inet_ntoa (area->area_id));
1019 return;
1020 }
1021
1022 area->external_routing = type;
1023
1024 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001025 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001026 LOOKUP (ospf_area_type_msg, type));
1027
1028 switch (area->external_routing)
1029 {
1030 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001031 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1032 if (oi->nbr_self != NULL)
1033 {
1034 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1035 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1036 }
paul718e3742002-12-13 20:15:29 +00001037 break;
1038 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001039 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1040 if (oi->nbr_self != NULL)
1041 {
1042 if (IS_DEBUG_OSPF_EVENT)
1043 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1044 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1045 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1046 if (IS_DEBUG_OSPF_EVENT)
1047 zlog_debug ("options set on %s: %x",
1048 IF_NAME (oi), OPTIONS (oi));
1049 }
paul718e3742002-12-13 20:15:29 +00001050 break;
1051 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001052 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1053 if (oi->nbr_self != NULL)
1054 {
1055 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1056 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1057 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1058 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1059 }
paul718e3742002-12-13 20:15:29 +00001060 break;
1061 default:
1062 break;
1063 }
1064
Paul Jakmac363d382010-01-24 22:42:13 +00001065 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001066 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001067}
1068
1069int
paul68980082003-03-25 05:07:42 +00001070ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001071{
1072 if (area->shortcut_configured == mode)
1073 return 0;
1074
1075 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001076 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001077 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001078
paul68980082003-03-25 05:07:42 +00001079 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001080
1081 return 1;
1082}
1083
1084int
paul68980082003-03-25 05:07:42 +00001085ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001086{
1087 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001088 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001089 ospf_area_check_free (ospf, area->area_id);
1090 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001091
1092 return 1;
1093}
1094
paul4dadc292005-05-06 21:37:42 +00001095static int
paul718e3742002-12-13 20:15:29 +00001096ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1097{
1098 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001099 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001100 int count = 0;
1101
paul1eb8ef22005-04-07 07:30:20 +00001102 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1103 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1104 count++;
paul718e3742002-12-13 20:15:29 +00001105
1106 return count;
1107}
1108
1109int
1110ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1111{
1112 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001113 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001114
paul68980082003-03-25 05:07:42 +00001115 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001116 if (ospf_area_vlink_count (ospf, area))
1117 return 0;
1118
1119 if (area->external_routing != OSPF_AREA_STUB)
1120 ospf_area_type_set (area, OSPF_AREA_STUB);
1121
1122 return 1;
1123}
1124
1125int
1126ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1127{
1128 struct ospf_area *area;
1129
paul68980082003-03-25 05:07:42 +00001130 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001131 if (area == NULL)
1132 return 1;
1133
1134 if (area->external_routing == OSPF_AREA_STUB)
1135 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1136
paul68980082003-03-25 05:07:42 +00001137 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001138
1139 return 1;
1140}
1141
1142int
1143ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1144{
1145 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001146 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001147
paul68980082003-03-25 05:07:42 +00001148 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001149 area->no_summary = 1;
1150
1151 return 1;
1152}
1153
1154int
1155ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1156{
1157 struct ospf_area *area;
1158
paul68980082003-03-25 05:07:42 +00001159 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001160 if (area == NULL)
1161 return 0;
1162
1163 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001164 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001165
1166 return 1;
1167}
1168
1169int
1170ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1171{
1172 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001173 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001174
paul68980082003-03-25 05:07:42 +00001175 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001176 if (ospf_area_vlink_count (ospf, area))
1177 return 0;
1178
1179 if (area->external_routing != OSPF_AREA_NSSA)
1180 {
1181 ospf_area_type_set (area, OSPF_AREA_NSSA);
1182 ospf->anyNSSA++;
1183 }
1184
paul084c7842003-06-22 08:35:18 +00001185 /* set NSSA area defaults */
1186 area->no_summary = 0;
1187 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001188 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001189 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1190
paul718e3742002-12-13 20:15:29 +00001191 return 1;
1192}
1193
1194int
1195ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1196{
1197 struct ospf_area *area;
1198
paul68980082003-03-25 05:07:42 +00001199 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001200 if (area == NULL)
1201 return 0;
1202
1203 if (area->external_routing == OSPF_AREA_NSSA)
1204 {
1205 ospf->anyNSSA--;
1206 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1207 }
1208
paul68980082003-03-25 05:07:42 +00001209 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001210
1211 return 1;
1212}
1213
1214int
1215ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1216 int role)
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 = role;
paul718e3742002-12-13 20:15:29 +00001225
1226 return 1;
1227}
1228
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001229#if 0
paul4dadc292005-05-06 21:37:42 +00001230/* XXX: unused? Leave for symmetry? */
1231static int
paul718e3742002-12-13 20:15:29 +00001232ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1233 struct in_addr area_id)
1234{
1235 struct ospf_area *area;
1236
paul68980082003-03-25 05:07:42 +00001237 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001238 if (area == NULL)
1239 return 0;
1240
paul084c7842003-06-22 08:35:18 +00001241 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001242
paul68980082003-03-25 05:07:42 +00001243 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001244
1245 return 1;
1246}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001247#endif
paul718e3742002-12-13 20:15:29 +00001248
1249int
paul68980082003-03-25 05:07:42 +00001250ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001251 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001252{
1253 struct access_list *list;
1254 list = access_list_lookup (AFI_IP, list_name);
1255
1256 EXPORT_LIST (area) = list;
1257
1258 if (EXPORT_NAME (area))
1259 free (EXPORT_NAME (area));
1260
1261 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001262 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001263
1264 return 1;
1265}
1266
1267int
paul68980082003-03-25 05:07:42 +00001268ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001269{
1270
1271 EXPORT_LIST (area) = 0;
1272
1273 if (EXPORT_NAME (area))
1274 free (EXPORT_NAME (area));
1275
1276 EXPORT_NAME (area) = NULL;
1277
paul68980082003-03-25 05:07:42 +00001278 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001279
paul68980082003-03-25 05:07:42 +00001280 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001281
1282 return 1;
1283}
1284
1285int
paul6c835672004-10-11 11:00:30 +00001286ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1287 const char *name)
paul718e3742002-12-13 20:15:29 +00001288{
1289 struct access_list *list;
1290 list = access_list_lookup (AFI_IP, name);
1291
1292 IMPORT_LIST (area) = list;
1293
1294 if (IMPORT_NAME (area))
1295 free (IMPORT_NAME (area));
1296
1297 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001298 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001299
1300 return 1;
1301}
1302
1303int
paul68980082003-03-25 05:07:42 +00001304ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001305{
1306 IMPORT_LIST (area) = 0;
1307
1308 if (IMPORT_NAME (area))
1309 free (IMPORT_NAME (area));
1310
1311 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001312 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001313
paul68980082003-03-25 05:07:42 +00001314 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001315
1316 return 1;
1317}
1318
1319int
paul718e3742002-12-13 20:15:29 +00001320ospf_timers_refresh_set (struct ospf *ospf, int interval)
1321{
1322 int time_left;
1323
1324 if (ospf->lsa_refresh_interval == interval)
1325 return 1;
1326
1327 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001328 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001329
1330 if (time_left > interval)
1331 {
1332 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1333 ospf->t_lsa_refresher =
1334 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1335 }
1336 ospf->lsa_refresh_interval = interval;
1337
1338 return 1;
1339}
1340
1341int
1342ospf_timers_refresh_unset (struct ospf *ospf)
1343{
1344 int time_left;
1345
1346 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001347 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001348
1349 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1350 {
1351 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1352 ospf->t_lsa_refresher =
1353 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1354 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1355 }
1356
1357 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1358
1359 return 1;
1360}
1361
David Lamparter6b0655a2014-06-04 06:53:35 +02001362
paul4dadc292005-05-06 21:37:42 +00001363static struct ospf_nbr_nbma *
1364ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001365{
1366 struct ospf_nbr_nbma *nbr_nbma;
1367
Stephen Hemminger393deb92008-08-18 14:13:29 -07001368 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001369 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001370
1371 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1372 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1373
1374 return nbr_nbma;
1375}
1376
paul4dadc292005-05-06 21:37:42 +00001377static void
paul718e3742002-12-13 20:15:29 +00001378ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1379{
1380 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1381}
1382
paul4dadc292005-05-06 21:37:42 +00001383static void
paul718e3742002-12-13 20:15:29 +00001384ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1385{
1386 struct route_node *rn;
1387 struct prefix_ipv4 p;
1388
1389 p.family = AF_INET;
1390 p.prefix = nbr_nbma->addr;
1391 p.prefixlen = IPV4_MAX_BITLEN;
1392
1393 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1394 if (rn)
1395 {
1396 ospf_nbr_nbma_free (rn->info);
1397 rn->info = NULL;
1398 route_unlock_node (rn);
1399 route_unlock_node (rn);
1400 }
1401}
1402
paul4dadc292005-05-06 21:37:42 +00001403static void
paul718e3742002-12-13 20:15:29 +00001404ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1405{
1406 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1407
1408 if (nbr_nbma->nbr)
1409 {
1410 nbr_nbma->nbr->nbr_nbma = NULL;
1411 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1412 }
1413
1414 if (nbr_nbma->oi)
1415 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1416}
1417
paul4dadc292005-05-06 21:37:42 +00001418static void
paul718e3742002-12-13 20:15:29 +00001419ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1420 struct ospf_interface *oi)
1421{
1422 struct ospf_neighbor *nbr;
1423 struct route_node *rn;
1424 struct prefix p;
1425
1426 if (oi->type != OSPF_IFTYPE_NBMA)
1427 return;
1428
1429 if (nbr_nbma->nbr != NULL)
1430 return;
1431
1432 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1433 return;
1434
1435 nbr_nbma->oi = oi;
1436 listnode_add (oi->nbr_nbma, nbr_nbma);
1437
1438 /* Get neighbor information from table. */
1439 p.family = AF_INET;
1440 p.prefixlen = IPV4_MAX_BITLEN;
1441 p.u.prefix4 = nbr_nbma->addr;
1442
1443 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1444 if (rn->info)
1445 {
1446 nbr = rn->info;
1447 nbr->nbr_nbma = nbr_nbma;
1448 nbr_nbma->nbr = nbr;
1449
1450 route_unlock_node (rn);
1451 }
1452 else
1453 {
1454 nbr = rn->info = ospf_nbr_new (oi);
1455 nbr->state = NSM_Down;
1456 nbr->src = nbr_nbma->addr;
1457 nbr->nbr_nbma = nbr_nbma;
1458 nbr->priority = nbr_nbma->priority;
1459 nbr->address = p;
1460
1461 nbr_nbma->nbr = nbr;
1462
1463 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1464 }
1465}
1466
1467void
paul68980082003-03-25 05:07:42 +00001468ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001469{
1470 struct ospf_nbr_nbma *nbr_nbma;
1471 struct route_node *rn;
1472 struct prefix_ipv4 p;
1473
1474 if (oi->type != OSPF_IFTYPE_NBMA)
1475 return;
1476
paul68980082003-03-25 05:07:42 +00001477 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001478 if ((nbr_nbma = rn->info))
1479 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1480 {
1481 p.family = AF_INET;
1482 p.prefix = nbr_nbma->addr;
1483 p.prefixlen = IPV4_MAX_BITLEN;
1484
1485 if (prefix_match (oi->address, (struct prefix *)&p))
1486 ospf_nbr_nbma_add (nbr_nbma, oi);
1487 }
1488}
1489
1490struct ospf_nbr_nbma *
1491ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1492{
1493 struct route_node *rn;
1494 struct prefix_ipv4 p;
1495
1496 p.family = AF_INET;
1497 p.prefix = nbr_addr;
1498 p.prefixlen = IPV4_MAX_BITLEN;
1499
1500 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1501 if (rn)
1502 {
1503 route_unlock_node (rn);
1504 return rn->info;
1505 }
1506 return NULL;
1507}
1508
1509struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001510ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001511{
1512#if 0
1513 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001514 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001515#endif
1516
paul68980082003-03-25 05:07:42 +00001517 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001518 return NULL;
1519
1520#if 0
paul1eb8ef22005-04-07 07:30:20 +00001521 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001522 {
paul718e3742002-12-13 20:15:29 +00001523 if (first)
1524 {
1525 *addr = nbr_nbma->addr;
1526 return nbr_nbma;
1527 }
1528 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1529 {
1530 *addr = nbr_nbma->addr;
1531 return nbr_nbma;
1532 }
1533 }
1534#endif
1535 return NULL;
1536}
1537
1538int
1539ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1540{
1541 struct ospf_nbr_nbma *nbr_nbma;
1542 struct ospf_interface *oi;
1543 struct prefix_ipv4 p;
1544 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001545 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001546
1547 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1548 if (nbr_nbma)
1549 return 0;
1550
1551 nbr_nbma = ospf_nbr_nbma_new ();
1552 nbr_nbma->addr = nbr_addr;
1553
1554 p.family = AF_INET;
1555 p.prefix = nbr_addr;
1556 p.prefixlen = IPV4_MAX_BITLEN;
1557
1558 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
Joakim Tjernlund4de398e2010-03-08 13:58:14 +01001559 if (rn->info)
1560 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001561 rn->info = nbr_nbma;
1562
paul1eb8ef22005-04-07 07:30:20 +00001563 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001564 {
paul718e3742002-12-13 20:15:29 +00001565 if (oi->type == OSPF_IFTYPE_NBMA)
1566 if (prefix_match (oi->address, (struct prefix *)&p))
1567 {
1568 ospf_nbr_nbma_add (nbr_nbma, oi);
1569 break;
1570 }
1571 }
1572
1573 return 1;
1574}
1575
1576int
1577ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1578{
1579 struct ospf_nbr_nbma *nbr_nbma;
1580
1581 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1582 if (nbr_nbma == NULL)
1583 return 0;
1584
1585 ospf_nbr_nbma_down (nbr_nbma);
1586 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1587
1588 return 1;
1589}
1590
1591int
1592ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1593 u_char priority)
1594{
1595 struct ospf_nbr_nbma *nbr_nbma;
1596
1597 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1598 if (nbr_nbma == NULL)
1599 return 0;
1600
1601 if (nbr_nbma->priority != priority)
1602 nbr_nbma->priority = priority;
1603
1604 return 1;
1605}
1606
1607int
1608ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1609{
1610 struct ospf_nbr_nbma *nbr_nbma;
1611
1612 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1613 if (nbr_nbma == NULL)
1614 return 0;
1615
1616 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1617 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1618
1619 return 1;
1620}
1621
1622int
1623ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001624 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001625{
1626 struct ospf_nbr_nbma *nbr_nbma;
1627
1628 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1629 if (nbr_nbma == NULL)
1630 return 0;
1631
1632 if (nbr_nbma->v_poll != interval)
1633 {
1634 nbr_nbma->v_poll = interval;
1635 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1636 {
1637 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1638 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1639 nbr_nbma->v_poll);
1640 }
1641 }
1642
1643 return 1;
1644}
1645
1646int
1647ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1648{
1649 struct ospf_nbr_nbma *nbr_nbma;
1650
1651 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1652 if (nbr_nbma == NULL)
1653 return 0;
1654
1655 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1656 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1657
1658 return 1;
1659}
1660
paul718e3742002-12-13 20:15:29 +00001661void
paul020709f2003-04-04 02:44:16 +00001662ospf_master_init ()
1663{
1664 memset (&ospf_master, 0, sizeof (struct ospf_master));
1665
1666 om = &ospf_master;
1667 om->ospf = list_new ();
1668 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001669 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001670}