blob: 8c7d1c2febdea336cfef40471d104aa99c438b04 [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
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200202 /* LSA timers */
203 new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
204 new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
205
paul718e3742002-12-13 20:15:29 +0000206 /* SPF timer value init. */
207 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
208 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000209 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
210 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000211
212 /* MaxAge init. */
Dinesh Dutt2449fcd2013-08-24 07:54:17 +0000213 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800214 new->maxage_lsa = route_table_init();
paul718e3742002-12-13 20:15:29 +0000215 new->t_maxage_walker =
216 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000217 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000218
219 /* Distance table init. */
220 new->distance_table = route_table_init ();
221
222 new->lsa_refresh_queue.index = 0;
223 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
224 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
225 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000226 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000227
ajs5c333492005-02-23 15:43:01 +0000228 if ((new->fd = ospf_sock_init()) < 0)
229 {
230 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
231 "a socket");
232 exit(1);
233 }
Denis Ovsienkof102e752007-09-18 09:01:13 +0000234 new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
235 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
Andrew Certain0798cee2012-12-04 13:43:42 -0800236 zlog_debug ("%s: starting with OSPF send buffer size %u",
Denis Ovsienkof102e752007-09-18 09:01:13 +0000237 __func__, new->maxsndbuflen);
ajs5c333492005-02-23 15:43:01 +0000238 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
239 {
240 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
241 OSPF_MAX_PACKET_SIZE+1);
242 exit(1);
243 }
244 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000245 new->oi_write_q = list_new ();
246
247 return new;
248}
249
250struct ospf *
paul020709f2003-04-04 02:44:16 +0000251ospf_lookup ()
252{
253 if (listcount (om->ospf) == 0)
254 return NULL;
255
paul1eb8ef22005-04-07 07:30:20 +0000256 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000257}
258
paul4dadc292005-05-06 21:37:42 +0000259static void
paul020709f2003-04-04 02:44:16 +0000260ospf_add (struct ospf *ospf)
261{
262 listnode_add (om->ospf, ospf);
263}
264
paul4dadc292005-05-06 21:37:42 +0000265static void
paul020709f2003-04-04 02:44:16 +0000266ospf_delete (struct ospf *ospf)
267{
268 listnode_delete (om->ospf, ospf);
269}
270
271struct ospf *
paul718e3742002-12-13 20:15:29 +0000272ospf_get ()
273{
paul020709f2003-04-04 02:44:16 +0000274 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000275
paul020709f2003-04-04 02:44:16 +0000276 ospf = ospf_lookup ();
277 if (ospf == NULL)
278 {
279 ospf = ospf_new ();
280 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000281
paul020709f2003-04-04 02:44:16 +0000282 if (ospf->router_id_static.s_addr == 0)
283 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000284
285#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000286 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000287#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000288 }
paul68980082003-03-25 05:07:42 +0000289
290 return ospf;
paul718e3742002-12-13 20:15:29 +0000291}
David Lamparter6b0655a2014-06-04 06:53:35 +0200292
paulc9c93d52005-11-26 13:31:11 +0000293/* Handle the second half of deferred shutdown. This is called either
294 * from the deferred-shutdown timer thread, or directly through
295 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000296 *
297 * Function is to cleanup G-R state, if required then call ospf_finish_final
298 * to complete shutdown of this ospf instance. Possibly exit if the
299 * whole process is being shutdown and this was the last OSPF instance.
300 */
301static void
paulc9c93d52005-11-26 13:31:11 +0000302ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000303{
304 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000305 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000306
307 ospf_finish_final (ospf);
308
309 /* *ospf is now invalid */
310
311 /* ospfd being shut-down? If so, was this the last ospf instance? */
312 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
313 && (listcount (om->ospf) == 0))
314 exit (0);
315
316 return;
317}
318
319/* Timer thread for G-R */
320static int
paulc9c93d52005-11-26 13:31:11 +0000321ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000322{
323 struct ospf *ospf = THREAD_ARG(t);
324
paulc9c93d52005-11-26 13:31:11 +0000325 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000326
327 return 0;
328}
329
paulc9c93d52005-11-26 13:31:11 +0000330/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000331 * down directly into second-half of instance shutdown.
332 */
333static void
paulc9c93d52005-11-26 13:31:11 +0000334ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000335{
336 unsigned long timeout;
337 struct listnode *ln;
338 struct ospf_area *area;
339
paulc9c93d52005-11-26 13:31:11 +0000340 /* deferred shutdown already running? */
341 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000342 return;
343
344 /* Should we try push out max-metric LSAs? */
345 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
346 {
347 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
348 {
349 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
350
351 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
Paul Jakmac363d382010-01-24 22:42:13 +0000352 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000353 }
354 timeout = ospf->stub_router_shutdown_time;
355 }
356 else
paulc9c93d52005-11-26 13:31:11 +0000357 {
358 /* No timer needed */
359 ospf_deferred_shutdown_finish (ospf);
360 return;
361 }
paul88d6cf32005-10-29 12:50:09 +0000362
paulc9c93d52005-11-26 13:31:11 +0000363 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000364 timeout);
365 return;
366}
David Lamparter6b0655a2014-06-04 06:53:35 +0200367
paul88d6cf32005-10-29 12:50:09 +0000368/* Shut down the entire process */
369void
370ospf_terminate (void)
371{
372 struct ospf *ospf;
373 struct listnode *node, *nnode;
374
375 /* shutdown already in progress */
376 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
377 return;
378
379 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
380
Andrew J. Schorr4056a542007-02-27 13:55:46 +0000381 /* exit immediately if OSPF not actually running */
382 if (listcount(om->ospf) == 0)
383 exit(0);
384
paul88d6cf32005-10-29 12:50:09 +0000385 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
386 ospf_finish (ospf);
387
388 /* Deliberately go back up, hopefully to thread scheduler, as
389 * One or more ospf_finish()'s may have deferred shutdown to a timer
390 * thread
391 */
392}
paul718e3742002-12-13 20:15:29 +0000393
394void
395ospf_finish (struct ospf *ospf)
396{
paulc9c93d52005-11-26 13:31:11 +0000397 /* let deferred shutdown decide */
398 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000399
paulc9c93d52005-11-26 13:31:11 +0000400 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000401 * deferred to expiry of G-S timer thread. Return back up, hopefully
402 * to thread scheduler.
403 */
paulc9c93d52005-11-26 13:31:11 +0000404 return;
paul88d6cf32005-10-29 12:50:09 +0000405}
406
407/* Final cleanup of ospf instance */
408static void
409ospf_finish_final (struct ospf *ospf)
410{
paul718e3742002-12-13 20:15:29 +0000411 struct route_node *rn;
412 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000413 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000414 struct ospf_interface *oi;
415 struct ospf_area *area;
416 struct ospf_vl_data *vl_data;
417 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000418 int i;
419
420#ifdef HAVE_OPAQUE_LSA
421 ospf_opaque_type11_lsa_term (ospf);
422#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000423
424 /* be nice if this worked, but it doesn't */
425 /*ospf_flush_self_originated_lsas_now (ospf);*/
426
427 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000428 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000429 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000430 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000431
paul1eb8ef22005-04-07 07:30:20 +0000432 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
433 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000434
paul1eb8ef22005-04-07 07:30:20 +0000435 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
436 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000437
438 list_delete (ospf->vlinks);
439
440 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000441 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
442 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000443
444 /* Clear static neighbors */
445 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
446 if ((nbr_nbma = rn->info))
447 {
448 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
449
450 if (nbr_nbma->nbr)
451 {
452 nbr_nbma->nbr->nbr_nbma = NULL;
453 nbr_nbma->nbr = NULL;
454 }
455
456 if (nbr_nbma->oi)
457 {
458 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
459 nbr_nbma->oi = NULL;
460 }
461
462 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
463 }
464
465 route_table_finish (ospf->nbr_nbma);
466
467 /* Clear networks and Areas. */
468 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
469 {
470 struct ospf_network *network;
471
472 if ((network = rn->info) != NULL)
473 {
paul68980082003-03-25 05:07:42 +0000474 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000475 rn->info = NULL;
476 route_unlock_node (rn);
477 }
478 }
479
paul1eb8ef22005-04-07 07:30:20 +0000480 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000481 {
paul718e3742002-12-13 20:15:29 +0000482 listnode_delete (ospf->areas, area);
483 ospf_area_free (area);
484 }
485
486 /* Cancel all timers. */
487 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000488 OSPF_TIMER_OFF (ospf->t_spf_calc);
489 OSPF_TIMER_OFF (ospf->t_ase_calc);
490 OSPF_TIMER_OFF (ospf->t_maxage);
491 OSPF_TIMER_OFF (ospf->t_maxage_walker);
492 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000493 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000494 OSPF_TIMER_OFF (ospf->t_distribute_update);
495 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
496 OSPF_TIMER_OFF (ospf->t_read);
497 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000498#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000499 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000500#endif
paul718e3742002-12-13 20:15:29 +0000501
502 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000503 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000504
505#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000506 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
507 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000508#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000509 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
510 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
511
paul718e3742002-12-13 20:15:29 +0000512 ospf_lsdb_delete_all (ospf->lsdb);
513 ospf_lsdb_free (ospf->lsdb);
514
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800515 for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
516 {
517 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000518
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800519 if ((lsa = rn->info) != NULL)
520 {
521 ospf_lsa_unlock (&lsa);
522 rn->info = NULL;
523 }
524 route_unlock_node (rn);
525 }
526 route_table_finish (ospf->maxage_lsa);
paul718e3742002-12-13 20:15:29 +0000527
528 if (ospf->old_table)
529 ospf_route_table_free (ospf->old_table);
530 if (ospf->new_table)
531 {
532 ospf_route_delete (ospf->new_table);
533 ospf_route_table_free (ospf->new_table);
534 }
535 if (ospf->old_rtrs)
536 ospf_rtrs_free (ospf->old_rtrs);
537 if (ospf->new_rtrs)
538 ospf_rtrs_free (ospf->new_rtrs);
539 if (ospf->new_external_route)
540 {
541 ospf_route_delete (ospf->new_external_route);
542 ospf_route_table_free (ospf->new_external_route);
543 }
544 if (ospf->old_external_route)
545 {
546 ospf_route_delete (ospf->old_external_route);
547 ospf_route_table_free (ospf->old_external_route);
548 }
549 if (ospf->external_lsas)
550 {
551 ospf_ase_external_lsas_finish (ospf->external_lsas);
552 }
553
554 list_delete (ospf->areas);
555
556 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
557 if (EXTERNAL_INFO (i) != NULL)
558 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
559 {
560 if (rn->info == NULL)
561 continue;
562
563 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
564 rn->info = NULL;
565 route_unlock_node (rn);
566 }
567
paul68980082003-03-25 05:07:42 +0000568 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000569 route_table_finish (ospf->distance_table);
570
paul020709f2003-04-04 02:44:16 +0000571 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000572
paul020709f2003-04-04 02:44:16 +0000573 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000574}
575
David Lamparter6b0655a2014-06-04 06:53:35 +0200576
paul718e3742002-12-13 20:15:29 +0000577/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000578static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000579ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000580{
581 struct ospf_area *new;
582
583 /* Allocate new config_network. */
584 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
585
paul68980082003-03-25 05:07:42 +0000586 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000587
588 new->area_id = area_id;
589
590 new->external_routing = OSPF_AREA_DEFAULT;
591 new->default_cost = 1;
592 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000593
paul718e3742002-12-13 20:15:29 +0000594 /* New LSDB init. */
595 new->lsdb = ospf_lsdb_new ();
596
597 /* Self-originated LSAs initialize. */
598 new->router_lsa_self = NULL;
599
600#ifdef HAVE_OPAQUE_LSA
601 ospf_opaque_type10_lsa_init (new);
602#endif /* HAVE_OPAQUE_LSA */
603
604 new->oiflist = list_new ();
605 new->ranges = route_table_init ();
606
607 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000608 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000609
610 return new;
611}
612
Stephen Hemminger917e2992009-12-03 19:07:00 +0300613static void
paul718e3742002-12-13 20:15:29 +0000614ospf_area_free (struct ospf_area *area)
615{
paul68980082003-03-25 05:07:42 +0000616 struct route_node *rn;
617 struct ospf_lsa *lsa;
618
paul718e3742002-12-13 20:15:29 +0000619 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000620 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
621 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
622 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
623 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
624 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
625 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
626 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
627 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000628
paul68980082003-03-25 05:07:42 +0000629 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
630 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000631#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000632 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
633 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
634 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
635 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000636#endif /* HAVE_OPAQUE_LSA */
637
638 ospf_lsdb_delete_all (area->lsdb);
639 ospf_lsdb_free (area->lsdb);
640
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000641 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000642
643 route_table_finish (area->ranges);
644 list_delete (area->oiflist);
645
646 if (EXPORT_NAME (area))
647 free (EXPORT_NAME (area));
648
649 if (IMPORT_NAME (area))
650 free (IMPORT_NAME (area));
651
652 /* Cancel timer. */
paul88d6cf32005-10-29 12:50:09 +0000653 OSPF_TIMER_OFF (area->t_stub_router);
654#ifdef HAVE_OPAQUE_LSA
655 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
656#endif /* HAVE_OPAQUE_LSA */
657
paul718e3742002-12-13 20:15:29 +0000658 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000659 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000660
661 XFREE (MTYPE_OSPF_AREA, area);
662}
663
664void
paul68980082003-03-25 05:07:42 +0000665ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000666{
667 struct ospf_area *area;
668
paul68980082003-03-25 05:07:42 +0000669 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000670 if (area &&
671 listcount (area->oiflist) == 0 &&
672 area->ranges->top == NULL &&
673 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
674 area->external_routing == OSPF_AREA_DEFAULT &&
675 area->no_summary == 0 &&
676 area->default_cost == 1 &&
677 EXPORT_NAME (area) == NULL &&
678 IMPORT_NAME (area) == NULL &&
679 area->auth_type == OSPF_AUTH_NULL)
680 {
paul68980082003-03-25 05:07:42 +0000681 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000682 ospf_area_free (area);
683 }
684}
685
686struct ospf_area *
paul68980082003-03-25 05:07:42 +0000687ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000688{
689 struct ospf_area *area;
690
paul68980082003-03-25 05:07:42 +0000691 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000692 if (!area)
693 {
paul68980082003-03-25 05:07:42 +0000694 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000695 area->format = format;
paul68980082003-03-25 05:07:42 +0000696 listnode_add_sort (ospf->areas, area);
697 ospf_check_abr_status (ospf);
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800698 if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
699 {
700 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
701 }
paul718e3742002-12-13 20:15:29 +0000702 }
703
704 return area;
705}
706
707struct ospf_area *
paul68980082003-03-25 05:07:42 +0000708ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000709{
710 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000711 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000712
paul1eb8ef22005-04-07 07:30:20 +0000713 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
714 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
715 return area;
paul718e3742002-12-13 20:15:29 +0000716
717 return NULL;
718}
719
720void
721ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
722{
723 listnode_add (area->oiflist, oi);
724}
725
726void
727ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
728{
729 listnode_delete (area->oiflist, oi);
730}
731
David Lamparter6b0655a2014-06-04 06:53:35 +0200732
paul718e3742002-12-13 20:15:29 +0000733/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000734static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000735ospf_network_new (struct in_addr area_id, int format)
736{
737 struct ospf_network *new;
738 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
739
740 new->area_id = area_id;
741 new->format = format;
742
743 return new;
744}
745
Stephen Hemminger917e2992009-12-03 19:07:00 +0300746static void
paul68980082003-03-25 05:07:42 +0000747ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000748{
paul68980082003-03-25 05:07:42 +0000749 ospf_area_check_free (ospf, network->area_id);
750 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000751 XFREE (MTYPE_OSPF_NETWORK, network);
752}
753
754int
755ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
756 struct in_addr area_id)
757{
758 struct ospf_network *network;
759 struct ospf_area *area;
760 struct route_node *rn;
761 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000762 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000763
764 rn = route_node_get (ospf->networks, (struct prefix *)p);
765 if (rn->info)
766 {
767 /* There is already same network statement. */
768 route_unlock_node (rn);
769 return 0;
770 }
771
772 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000773 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000774
775 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100776 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000777
778 /* Update connected redistribute. */
779 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
780 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
781 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
782 rn; rn = route_next (rn))
783 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000784 if (ospf_external_info_find_lsa (ospf, &ei->p))
785 if (!ospf_distribute_check_connected (ospf, ei))
786 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000787 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000788
paul68980082003-03-25 05:07:42 +0000789 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000790
791 return 1;
792}
793
794int
795ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
796 struct in_addr area_id)
797{
798 struct route_node *rn;
799 struct ospf_network *network;
800 struct external_info *ei;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100801 struct listnode *node, *nnode;
802 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000803
804 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
805 if (rn == NULL)
806 return 0;
807
808 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700809 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000810 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
811 return 0;
812
paul68980082003-03-25 05:07:42 +0000813 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000814 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700815 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000816
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100817 /* Find interfaces that not configured already. */
818 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
819 {
820 int found = 0;
821 struct connected *co = oi->connected;
822
823 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
824 continue;
825
826 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
827 {
828 if (rn->info == NULL)
829 continue;
830
831 if (ospf_network_match_iface(co,&rn->p))
832 {
833 found = 1;
834 route_unlock_node (rn);
835 break;
836 }
837 }
838
839 if (found == 0)
Joakim Tjernlund6b274d92010-03-09 06:42:30 +0000840 {
841 ospf_if_free (oi);
842 ospf_area_check_free (ospf, area_id);
843 }
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100844 }
paul718e3742002-12-13 20:15:29 +0000845
846 /* Update connected redistribute. */
847 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
848 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
849 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
850 rn; rn = route_next (rn))
851 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000852 if (!ospf_external_info_find_lsa (ospf, &ei->p))
853 if (ospf_distribute_check_connected (ospf, ei))
854 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000855
856 return 1;
857}
858
paul570f7592003-01-25 06:47:41 +0000859/* Check whether interface matches given network
860 * returns: 1, true. 0, false
861 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300862static int
863ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000864{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000865 /* new approach: more elegant and conceptually clean */
866 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000867}
868
Stephen Hemminger917e2992009-12-03 19:07:00 +0300869static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100870ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
871 struct interface *ifp)
872{
873 struct listnode *cnode;
874 struct connected *co;
875
876 if (memcmp (ifp->name, "VLINK", 5) == 0)
877 return;
878
879 /* if interface prefix is match specified prefix,
880 then create socket and join multicast group. */
881 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
882 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200883
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100884 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
885 continue;
886
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100887 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200888 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100889 && ospf_network_match_iface(co,p))
890 {
891 struct ospf_interface *oi;
892
893 oi = ospf_if_new (area->ospf, ifp, co->address);
894 oi->connected = co;
895
896 oi->area = area;
897
898 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
899 oi->output_cost = ospf_if_get_output_cost (oi);
900
901 /* Add pseudo neighbor. */
902 ospf_nbr_add_self (oi);
903
904 /* Relate ospf interface to ospf instance. */
905 oi->ospf = area->ospf;
906
907 /* update network type as interface flag */
908 /* If network type is specified previously,
909 skip network type setting. */
910 oi->type = IF_DEF_PARAMS (ifp)->type;
911
912 ospf_area_add_if (oi->area, oi);
913
914 /* if router_id is not configured, dont bring up
915 * interfaces.
916 * ospf_router_id_update() will call ospf_if_update
917 * whenever r-id is configured instead.
918 */
919 if ((area->ospf->router_id.s_addr != 0)
920 && if_is_operative (ifp))
921 ospf_if_up (oi);
922 }
923 }
924}
925
Stephen Hemminger917e2992009-12-03 19:07:00 +0300926static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100927ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000928{
929 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000930 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000931
932 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100933 if (area->ospf->router_id.s_addr == 0)
934 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000935
paul718e3742002-12-13 20:15:29 +0000936 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000937 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100938 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000939}
940
941void
942ospf_ls_upd_queue_empty (struct ospf_interface *oi)
943{
944 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000945 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000946 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000947 struct ospf_lsa *lsa;
948
949 /* empty ls update queue */
950 for (rn = route_top (oi->ls_upd_queue); rn;
951 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000952 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000953 {
paul1eb8ef22005-04-07 07:30:20 +0000954 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000955 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000956 list_free (lst);
957 rn->info = NULL;
958 }
959
960 /* remove update event */
961 if (oi->t_ls_upd_event)
962 {
963 thread_cancel (oi->t_ls_upd_event);
964 oi->t_ls_upd_event = NULL;
965 }
966}
967
968void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100969ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000970{
971 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000972 struct ospf_network *network;
973 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100974
975 if (!ospf)
976 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000977
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100978 /* OSPF must be on and Router-ID must be configured. */
979 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100980 return;
981
982 /* Run each netowrk for this interface. */
983 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
984 if (rn->info != NULL)
985 {
986 network = (struct ospf_network *) rn->info;
987 area = ospf_area_get (ospf, network->area_id, network->format);
988 ospf_network_run_interface (&rn->p, area, ifp);
989 }
paul718e3742002-12-13 20:15:29 +0000990}
991
992void
paul68980082003-03-25 05:07:42 +0000993ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000994{
paul1eb8ef22005-04-07 07:30:20 +0000995 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000996 struct ospf_vl_data *vl_data;
997
paul1eb8ef22005-04-07 07:30:20 +0000998 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
999 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
1000 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +00001001}
1002
David Lamparter6b0655a2014-06-04 06:53:35 +02001003
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001004static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +00001005{
1006 { OSPF_AREA_DEFAULT, "Default" },
1007 { OSPF_AREA_STUB, "Stub" },
1008 { OSPF_AREA_NSSA, "NSSA" },
1009};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001010static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +00001011
paul4dadc292005-05-06 21:37:42 +00001012static void
paul718e3742002-12-13 20:15:29 +00001013ospf_area_type_set (struct ospf_area *area, int type)
1014{
hasso52dc7ee2004-09-23 19:18:23 +00001015 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001016 struct ospf_interface *oi;
1017
1018 if (area->external_routing == type)
1019 {
1020 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001021 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001022 inet_ntoa (area->area_id));
1023 return;
1024 }
1025
1026 area->external_routing = type;
1027
1028 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001029 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001030 LOOKUP (ospf_area_type_msg, type));
1031
1032 switch (area->external_routing)
1033 {
1034 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001035 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1036 if (oi->nbr_self != NULL)
1037 {
1038 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1039 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1040 }
paul718e3742002-12-13 20:15:29 +00001041 break;
1042 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001043 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1044 if (oi->nbr_self != NULL)
1045 {
1046 if (IS_DEBUG_OSPF_EVENT)
1047 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1048 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1049 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1050 if (IS_DEBUG_OSPF_EVENT)
1051 zlog_debug ("options set on %s: %x",
1052 IF_NAME (oi), OPTIONS (oi));
1053 }
paul718e3742002-12-13 20:15:29 +00001054 break;
1055 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001056 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1057 if (oi->nbr_self != NULL)
1058 {
1059 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1060 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1061 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1062 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1063 }
paul718e3742002-12-13 20:15:29 +00001064 break;
1065 default:
1066 break;
1067 }
1068
Paul Jakmac363d382010-01-24 22:42:13 +00001069 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001070 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001071}
1072
1073int
paul68980082003-03-25 05:07:42 +00001074ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001075{
1076 if (area->shortcut_configured == mode)
1077 return 0;
1078
1079 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001080 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001081 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001082
paul68980082003-03-25 05:07:42 +00001083 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001084
1085 return 1;
1086}
1087
1088int
paul68980082003-03-25 05:07:42 +00001089ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001090{
1091 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001092 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001093 ospf_area_check_free (ospf, area->area_id);
1094 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001095
1096 return 1;
1097}
1098
paul4dadc292005-05-06 21:37:42 +00001099static int
paul718e3742002-12-13 20:15:29 +00001100ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1101{
1102 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001103 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001104 int count = 0;
1105
paul1eb8ef22005-04-07 07:30:20 +00001106 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1107 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1108 count++;
paul718e3742002-12-13 20:15:29 +00001109
1110 return count;
1111}
1112
1113int
1114ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1115{
1116 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001117 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001118
paul68980082003-03-25 05:07:42 +00001119 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001120 if (ospf_area_vlink_count (ospf, area))
1121 return 0;
1122
1123 if (area->external_routing != OSPF_AREA_STUB)
1124 ospf_area_type_set (area, OSPF_AREA_STUB);
1125
1126 return 1;
1127}
1128
1129int
1130ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1131{
1132 struct ospf_area *area;
1133
paul68980082003-03-25 05:07:42 +00001134 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001135 if (area == NULL)
1136 return 1;
1137
1138 if (area->external_routing == OSPF_AREA_STUB)
1139 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1140
paul68980082003-03-25 05:07:42 +00001141 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001142
1143 return 1;
1144}
1145
1146int
1147ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1148{
1149 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001150 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001151
paul68980082003-03-25 05:07:42 +00001152 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001153 area->no_summary = 1;
1154
1155 return 1;
1156}
1157
1158int
1159ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1160{
1161 struct ospf_area *area;
1162
paul68980082003-03-25 05:07:42 +00001163 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001164 if (area == NULL)
1165 return 0;
1166
1167 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001168 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001169
1170 return 1;
1171}
1172
1173int
1174ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1175{
1176 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001177 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001178
paul68980082003-03-25 05:07:42 +00001179 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001180 if (ospf_area_vlink_count (ospf, area))
1181 return 0;
1182
1183 if (area->external_routing != OSPF_AREA_NSSA)
1184 {
1185 ospf_area_type_set (area, OSPF_AREA_NSSA);
1186 ospf->anyNSSA++;
1187 }
1188
paul084c7842003-06-22 08:35:18 +00001189 /* set NSSA area defaults */
1190 area->no_summary = 0;
1191 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001192 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001193 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1194
paul718e3742002-12-13 20:15:29 +00001195 return 1;
1196}
1197
1198int
1199ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
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
1207 if (area->external_routing == OSPF_AREA_NSSA)
1208 {
1209 ospf->anyNSSA--;
1210 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1211 }
1212
paul68980082003-03-25 05:07:42 +00001213 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001214
1215 return 1;
1216}
1217
1218int
1219ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1220 int role)
1221{
1222 struct ospf_area *area;
1223
paul68980082003-03-25 05:07:42 +00001224 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001225 if (area == NULL)
1226 return 0;
1227
paul084c7842003-06-22 08:35:18 +00001228 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001229
1230 return 1;
1231}
1232
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001233#if 0
paul4dadc292005-05-06 21:37:42 +00001234/* XXX: unused? Leave for symmetry? */
1235static int
paul718e3742002-12-13 20:15:29 +00001236ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1237 struct in_addr area_id)
1238{
1239 struct ospf_area *area;
1240
paul68980082003-03-25 05:07:42 +00001241 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001242 if (area == NULL)
1243 return 0;
1244
paul084c7842003-06-22 08:35:18 +00001245 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001246
paul68980082003-03-25 05:07:42 +00001247 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001248
1249 return 1;
1250}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001251#endif
paul718e3742002-12-13 20:15:29 +00001252
1253int
paul68980082003-03-25 05:07:42 +00001254ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001255 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001256{
1257 struct access_list *list;
1258 list = access_list_lookup (AFI_IP, list_name);
1259
1260 EXPORT_LIST (area) = list;
1261
1262 if (EXPORT_NAME (area))
1263 free (EXPORT_NAME (area));
1264
1265 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001266 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001267
1268 return 1;
1269}
1270
1271int
paul68980082003-03-25 05:07:42 +00001272ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001273{
1274
1275 EXPORT_LIST (area) = 0;
1276
1277 if (EXPORT_NAME (area))
1278 free (EXPORT_NAME (area));
1279
1280 EXPORT_NAME (area) = NULL;
1281
paul68980082003-03-25 05:07:42 +00001282 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001283
paul68980082003-03-25 05:07:42 +00001284 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001285
1286 return 1;
1287}
1288
1289int
paul6c835672004-10-11 11:00:30 +00001290ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1291 const char *name)
paul718e3742002-12-13 20:15:29 +00001292{
1293 struct access_list *list;
1294 list = access_list_lookup (AFI_IP, name);
1295
1296 IMPORT_LIST (area) = list;
1297
1298 if (IMPORT_NAME (area))
1299 free (IMPORT_NAME (area));
1300
1301 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001302 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001303
1304 return 1;
1305}
1306
1307int
paul68980082003-03-25 05:07:42 +00001308ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001309{
1310 IMPORT_LIST (area) = 0;
1311
1312 if (IMPORT_NAME (area))
1313 free (IMPORT_NAME (area));
1314
1315 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001316 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001317
paul68980082003-03-25 05:07:42 +00001318 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001319
1320 return 1;
1321}
1322
1323int
paul718e3742002-12-13 20:15:29 +00001324ospf_timers_refresh_set (struct ospf *ospf, int interval)
1325{
1326 int time_left;
1327
1328 if (ospf->lsa_refresh_interval == interval)
1329 return 1;
1330
1331 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001332 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001333
1334 if (time_left > interval)
1335 {
1336 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1337 ospf->t_lsa_refresher =
1338 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1339 }
1340 ospf->lsa_refresh_interval = interval;
1341
1342 return 1;
1343}
1344
1345int
1346ospf_timers_refresh_unset (struct ospf *ospf)
1347{
1348 int time_left;
1349
1350 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001351 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001352
1353 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1354 {
1355 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1356 ospf->t_lsa_refresher =
1357 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1358 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1359 }
1360
1361 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1362
1363 return 1;
1364}
1365
David Lamparter6b0655a2014-06-04 06:53:35 +02001366
paul4dadc292005-05-06 21:37:42 +00001367static struct ospf_nbr_nbma *
1368ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001369{
1370 struct ospf_nbr_nbma *nbr_nbma;
1371
Stephen Hemminger393deb92008-08-18 14:13:29 -07001372 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001373 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001374
1375 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1376 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1377
1378 return nbr_nbma;
1379}
1380
paul4dadc292005-05-06 21:37:42 +00001381static void
paul718e3742002-12-13 20:15:29 +00001382ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1383{
1384 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1385}
1386
paul4dadc292005-05-06 21:37:42 +00001387static void
paul718e3742002-12-13 20:15:29 +00001388ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1389{
1390 struct route_node *rn;
1391 struct prefix_ipv4 p;
1392
1393 p.family = AF_INET;
1394 p.prefix = nbr_nbma->addr;
1395 p.prefixlen = IPV4_MAX_BITLEN;
1396
1397 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1398 if (rn)
1399 {
1400 ospf_nbr_nbma_free (rn->info);
1401 rn->info = NULL;
1402 route_unlock_node (rn);
1403 route_unlock_node (rn);
1404 }
1405}
1406
paul4dadc292005-05-06 21:37:42 +00001407static void
paul718e3742002-12-13 20:15:29 +00001408ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1409{
1410 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1411
1412 if (nbr_nbma->nbr)
1413 {
1414 nbr_nbma->nbr->nbr_nbma = NULL;
1415 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1416 }
1417
1418 if (nbr_nbma->oi)
1419 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1420}
1421
paul4dadc292005-05-06 21:37:42 +00001422static void
paul718e3742002-12-13 20:15:29 +00001423ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1424 struct ospf_interface *oi)
1425{
1426 struct ospf_neighbor *nbr;
1427 struct route_node *rn;
1428 struct prefix p;
1429
1430 if (oi->type != OSPF_IFTYPE_NBMA)
1431 return;
1432
1433 if (nbr_nbma->nbr != NULL)
1434 return;
1435
1436 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1437 return;
1438
1439 nbr_nbma->oi = oi;
1440 listnode_add (oi->nbr_nbma, nbr_nbma);
1441
1442 /* Get neighbor information from table. */
1443 p.family = AF_INET;
1444 p.prefixlen = IPV4_MAX_BITLEN;
1445 p.u.prefix4 = nbr_nbma->addr;
1446
1447 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1448 if (rn->info)
1449 {
1450 nbr = rn->info;
1451 nbr->nbr_nbma = nbr_nbma;
1452 nbr_nbma->nbr = nbr;
1453
1454 route_unlock_node (rn);
1455 }
1456 else
1457 {
1458 nbr = rn->info = ospf_nbr_new (oi);
1459 nbr->state = NSM_Down;
1460 nbr->src = nbr_nbma->addr;
1461 nbr->nbr_nbma = nbr_nbma;
1462 nbr->priority = nbr_nbma->priority;
1463 nbr->address = p;
1464
1465 nbr_nbma->nbr = nbr;
1466
1467 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1468 }
1469}
1470
1471void
paul68980082003-03-25 05:07:42 +00001472ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001473{
1474 struct ospf_nbr_nbma *nbr_nbma;
1475 struct route_node *rn;
1476 struct prefix_ipv4 p;
1477
1478 if (oi->type != OSPF_IFTYPE_NBMA)
1479 return;
1480
paul68980082003-03-25 05:07:42 +00001481 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001482 if ((nbr_nbma = rn->info))
1483 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1484 {
1485 p.family = AF_INET;
1486 p.prefix = nbr_nbma->addr;
1487 p.prefixlen = IPV4_MAX_BITLEN;
1488
1489 if (prefix_match (oi->address, (struct prefix *)&p))
1490 ospf_nbr_nbma_add (nbr_nbma, oi);
1491 }
1492}
1493
1494struct ospf_nbr_nbma *
1495ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1496{
1497 struct route_node *rn;
1498 struct prefix_ipv4 p;
1499
1500 p.family = AF_INET;
1501 p.prefix = nbr_addr;
1502 p.prefixlen = IPV4_MAX_BITLEN;
1503
1504 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1505 if (rn)
1506 {
1507 route_unlock_node (rn);
1508 return rn->info;
1509 }
1510 return NULL;
1511}
1512
1513struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001514ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001515{
1516#if 0
1517 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001518 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001519#endif
1520
paul68980082003-03-25 05:07:42 +00001521 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001522 return NULL;
1523
1524#if 0
paul1eb8ef22005-04-07 07:30:20 +00001525 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001526 {
paul718e3742002-12-13 20:15:29 +00001527 if (first)
1528 {
1529 *addr = nbr_nbma->addr;
1530 return nbr_nbma;
1531 }
1532 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1533 {
1534 *addr = nbr_nbma->addr;
1535 return nbr_nbma;
1536 }
1537 }
1538#endif
1539 return NULL;
1540}
1541
1542int
1543ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1544{
1545 struct ospf_nbr_nbma *nbr_nbma;
1546 struct ospf_interface *oi;
1547 struct prefix_ipv4 p;
1548 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001549 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001550
1551 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1552 if (nbr_nbma)
1553 return 0;
1554
1555 nbr_nbma = ospf_nbr_nbma_new ();
1556 nbr_nbma->addr = nbr_addr;
1557
1558 p.family = AF_INET;
1559 p.prefix = nbr_addr;
1560 p.prefixlen = IPV4_MAX_BITLEN;
1561
1562 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
Joakim Tjernlund4de398e2010-03-08 13:58:14 +01001563 if (rn->info)
1564 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001565 rn->info = nbr_nbma;
1566
paul1eb8ef22005-04-07 07:30:20 +00001567 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001568 {
paul718e3742002-12-13 20:15:29 +00001569 if (oi->type == OSPF_IFTYPE_NBMA)
1570 if (prefix_match (oi->address, (struct prefix *)&p))
1571 {
1572 ospf_nbr_nbma_add (nbr_nbma, oi);
1573 break;
1574 }
1575 }
1576
1577 return 1;
1578}
1579
1580int
1581ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1582{
1583 struct ospf_nbr_nbma *nbr_nbma;
1584
1585 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1586 if (nbr_nbma == NULL)
1587 return 0;
1588
1589 ospf_nbr_nbma_down (nbr_nbma);
1590 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1591
1592 return 1;
1593}
1594
1595int
1596ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1597 u_char priority)
1598{
1599 struct ospf_nbr_nbma *nbr_nbma;
1600
1601 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1602 if (nbr_nbma == NULL)
1603 return 0;
1604
1605 if (nbr_nbma->priority != priority)
1606 nbr_nbma->priority = priority;
1607
1608 return 1;
1609}
1610
1611int
1612ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1613{
1614 struct ospf_nbr_nbma *nbr_nbma;
1615
1616 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1617 if (nbr_nbma == NULL)
1618 return 0;
1619
1620 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1621 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1622
1623 return 1;
1624}
1625
1626int
1627ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001628 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001629{
1630 struct ospf_nbr_nbma *nbr_nbma;
1631
1632 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1633 if (nbr_nbma == NULL)
1634 return 0;
1635
1636 if (nbr_nbma->v_poll != interval)
1637 {
1638 nbr_nbma->v_poll = interval;
1639 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1640 {
1641 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1642 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1643 nbr_nbma->v_poll);
1644 }
1645 }
1646
1647 return 1;
1648}
1649
1650int
1651ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1652{
1653 struct ospf_nbr_nbma *nbr_nbma;
1654
1655 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1656 if (nbr_nbma == NULL)
1657 return 0;
1658
1659 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1660 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1661
1662 return 1;
1663}
1664
paul718e3742002-12-13 20:15:29 +00001665void
paul020709f2003-04-04 02:44:16 +00001666ospf_master_init ()
1667{
1668 memset (&ospf_master, 0, sizeof (struct ospf_master));
1669
1670 om = &ospf_master;
1671 om->ospf = list_new ();
1672 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001673 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001674}