blob: c8ad25f249f136152bfd29034e69083246ea8c71 [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
Joakim Tjernlund7bd7f552009-08-07 13:48:15 +0200747add_ospf_interface (struct interface *ifp, struct ospf_area *area,
748 struct connected *co)
749{
750 struct ospf_interface *oi;
751
752 oi = ospf_if_new (area->ospf, ifp, co->address);
753 oi->connected = co;
754
755 oi->area = area;
756
757 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
758 oi->output_cost = ospf_if_get_output_cost (oi);
759
760 /* Add pseudo neighbor. */
761 ospf_nbr_add_self (oi);
762
763 /* Relate ospf interface to ospf instance. */
764 oi->ospf = area->ospf;
765
766 /* update network type as interface flag */
767 /* If network type is specified previously,
768 skip network type setting. */
769 oi->type = IF_DEF_PARAMS (ifp)->type;
770
771 ospf_area_add_if (oi->area, oi);
772
773 /* if router_id is not configured, dont bring up
774 * interfaces.
775 * ospf_router_id_update() will call ospf_if_update
776 * whenever r-id is configured instead.
777 */
778 if ((area->ospf->router_id.s_addr != 0)
779 && if_is_operative (ifp))
780 ospf_if_up (oi);
781}
782
783static void
784update_redistributed (struct ospf *ospf, int add_to_ospf)
785{
786 struct route_node *rn;
787 struct external_info *ei;
788
789 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
790 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
791 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
792 rn; rn = route_next (rn))
793 if ((ei = rn->info) != NULL)
794 {
795 if (add_to_ospf)
796 {
797 if (ospf_external_info_find_lsa (ospf, &ei->p))
798 if (!ospf_distribute_check_connected (ospf, ei))
799 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
800 ei->ifindex /*, ei->nexthop */);
801 }
802 else
803 {
804 if (!ospf_external_info_find_lsa (ospf, &ei->p))
805 if (ospf_distribute_check_connected (ospf, ei))
806 ospf_external_lsa_originate (ospf, ei);
807 }
808 }
809}
810
811static void
paul68980082003-03-25 05:07:42 +0000812ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000813{
paul68980082003-03-25 05:07:42 +0000814 ospf_area_check_free (ospf, network->area_id);
815 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000816 XFREE (MTYPE_OSPF_NETWORK, network);
817}
818
819int
820ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
821 struct in_addr area_id)
822{
823 struct ospf_network *network;
824 struct ospf_area *area;
825 struct route_node *rn;
paul147193a2003-04-19 00:31:59 +0000826 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000827
828 rn = route_node_get (ospf->networks, (struct prefix *)p);
829 if (rn->info)
830 {
831 /* There is already same network statement. */
832 route_unlock_node (rn);
833 return 0;
834 }
835
836 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000837 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000838
839 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100840 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000841
842 /* Update connected redistribute. */
Joakim Tjernlund7bd7f552009-08-07 13:48:15 +0200843 update_redistributed(ospf, 1); /* interfaces possibly added */
paul68980082003-03-25 05:07:42 +0000844 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000845
846 return 1;
847}
848
849int
850ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
851 struct in_addr area_id)
852{
853 struct route_node *rn;
854 struct ospf_network *network;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100855 struct listnode *node, *nnode;
856 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000857
858 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
859 if (rn == NULL)
860 return 0;
861
862 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700863 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000864 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
865 return 0;
866
paul68980082003-03-25 05:07:42 +0000867 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000868 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700869 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000870
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100871 /* Find interfaces that not configured already. */
872 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
873 {
874 int found = 0;
875 struct connected *co = oi->connected;
876
877 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
878 continue;
879
880 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
881 {
882 if (rn->info == NULL)
883 continue;
884
885 if (ospf_network_match_iface(co,&rn->p))
886 {
887 found = 1;
888 route_unlock_node (rn);
889 break;
890 }
891 }
892
893 if (found == 0)
Joakim Tjernlund6b274d92010-03-09 06:42:30 +0000894 {
895 ospf_if_free (oi);
896 ospf_area_check_free (ospf, area_id);
897 }
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100898 }
paul718e3742002-12-13 20:15:29 +0000899
900 /* Update connected redistribute. */
Joakim Tjernlund7bd7f552009-08-07 13:48:15 +0200901 update_redistributed(ospf, 0); /* interfaces possibly removed */
paul718e3742002-12-13 20:15:29 +0000902 return 1;
903}
904
paul570f7592003-01-25 06:47:41 +0000905/* Check whether interface matches given network
906 * returns: 1, true. 0, false
907 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300908static int
909ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000910{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000911 /* new approach: more elegant and conceptually clean */
912 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000913}
914
Stephen Hemminger917e2992009-12-03 19:07:00 +0300915static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100916ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
917 struct interface *ifp)
918{
919 struct listnode *cnode;
920 struct connected *co;
921
922 if (memcmp (ifp->name, "VLINK", 5) == 0)
923 return;
924
925 /* if interface prefix is match specified prefix,
926 then create socket and join multicast group. */
927 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
928 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200929
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100930 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
931 continue;
932
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100933 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200934 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100935 && ospf_network_match_iface(co,p))
Joakim Tjernlund7bd7f552009-08-07 13:48:15 +0200936 {
937 add_ospf_interface(ifp, area, co);
938 }
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100939 }
940}
941
Stephen Hemminger917e2992009-12-03 19:07:00 +0300942static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100943ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000944{
945 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000946 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000947
948 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100949 if (area->ospf->router_id.s_addr == 0)
950 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000951
paul718e3742002-12-13 20:15:29 +0000952 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000953 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100954 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000955}
956
957void
958ospf_ls_upd_queue_empty (struct ospf_interface *oi)
959{
960 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000961 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000962 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000963 struct ospf_lsa *lsa;
964
965 /* empty ls update queue */
966 for (rn = route_top (oi->ls_upd_queue); rn;
967 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000968 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000969 {
paul1eb8ef22005-04-07 07:30:20 +0000970 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000971 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000972 list_free (lst);
973 rn->info = NULL;
974 }
975
976 /* remove update event */
977 if (oi->t_ls_upd_event)
978 {
979 thread_cancel (oi->t_ls_upd_event);
980 oi->t_ls_upd_event = NULL;
981 }
982}
983
984void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100985ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000986{
987 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000988 struct ospf_network *network;
989 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100990
991 if (!ospf)
992 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000993
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100994 /* OSPF must be on and Router-ID must be configured. */
995 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100996 return;
Joakim Tjernlund7bd7f552009-08-07 13:48:15 +0200997
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100998 /* Run each netowrk for this interface. */
999 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
1000 if (rn->info != NULL)
1001 {
1002 network = (struct ospf_network *) rn->info;
1003 area = ospf_area_get (ospf, network->area_id, network->format);
1004 ospf_network_run_interface (&rn->p, area, ifp);
1005 }
paul718e3742002-12-13 20:15:29 +00001006}
1007
1008void
paul68980082003-03-25 05:07:42 +00001009ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001010{
paul1eb8ef22005-04-07 07:30:20 +00001011 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001012 struct ospf_vl_data *vl_data;
1013
paul1eb8ef22005-04-07 07:30:20 +00001014 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
1015 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
1016 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +00001017}
1018
David Lamparter6b0655a2014-06-04 06:53:35 +02001019
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001020static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +00001021{
1022 { OSPF_AREA_DEFAULT, "Default" },
1023 { OSPF_AREA_STUB, "Stub" },
1024 { OSPF_AREA_NSSA, "NSSA" },
1025};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001026static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +00001027
paul4dadc292005-05-06 21:37:42 +00001028static void
paul718e3742002-12-13 20:15:29 +00001029ospf_area_type_set (struct ospf_area *area, int type)
1030{
hasso52dc7ee2004-09-23 19:18:23 +00001031 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001032 struct ospf_interface *oi;
1033
1034 if (area->external_routing == type)
1035 {
1036 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001037 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001038 inet_ntoa (area->area_id));
1039 return;
1040 }
1041
1042 area->external_routing = type;
1043
1044 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001045 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001046 LOOKUP (ospf_area_type_msg, type));
1047
1048 switch (area->external_routing)
1049 {
1050 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001051 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1052 if (oi->nbr_self != NULL)
1053 {
1054 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1055 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1056 }
paul718e3742002-12-13 20:15:29 +00001057 break;
1058 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001059 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1060 if (oi->nbr_self != NULL)
1061 {
1062 if (IS_DEBUG_OSPF_EVENT)
1063 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1064 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1065 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1066 if (IS_DEBUG_OSPF_EVENT)
1067 zlog_debug ("options set on %s: %x",
1068 IF_NAME (oi), OPTIONS (oi));
1069 }
paul718e3742002-12-13 20:15:29 +00001070 break;
1071 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001072 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1073 if (oi->nbr_self != NULL)
1074 {
1075 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1076 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1077 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1078 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1079 }
paul718e3742002-12-13 20:15:29 +00001080 break;
1081 default:
1082 break;
1083 }
1084
Paul Jakmac363d382010-01-24 22:42:13 +00001085 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001086 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001087}
1088
1089int
paul68980082003-03-25 05:07:42 +00001090ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001091{
1092 if (area->shortcut_configured == mode)
1093 return 0;
1094
1095 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001096 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001097 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001098
paul68980082003-03-25 05:07:42 +00001099 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001100
1101 return 1;
1102}
1103
1104int
paul68980082003-03-25 05:07:42 +00001105ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001106{
1107 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001108 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001109 ospf_area_check_free (ospf, area->area_id);
1110 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001111
1112 return 1;
1113}
1114
paul4dadc292005-05-06 21:37:42 +00001115static int
paul718e3742002-12-13 20:15:29 +00001116ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1117{
1118 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001119 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001120 int count = 0;
1121
paul1eb8ef22005-04-07 07:30:20 +00001122 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1123 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1124 count++;
paul718e3742002-12-13 20:15:29 +00001125
1126 return count;
1127}
1128
1129int
1130ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1131{
1132 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001133 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001134
paul68980082003-03-25 05:07:42 +00001135 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001136 if (ospf_area_vlink_count (ospf, area))
1137 return 0;
1138
1139 if (area->external_routing != OSPF_AREA_STUB)
1140 ospf_area_type_set (area, OSPF_AREA_STUB);
1141
1142 return 1;
1143}
1144
1145int
1146ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1147{
1148 struct ospf_area *area;
1149
paul68980082003-03-25 05:07:42 +00001150 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001151 if (area == NULL)
1152 return 1;
1153
1154 if (area->external_routing == OSPF_AREA_STUB)
1155 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1156
paul68980082003-03-25 05:07:42 +00001157 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001158
1159 return 1;
1160}
1161
1162int
1163ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1164{
1165 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001166 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001167
paul68980082003-03-25 05:07:42 +00001168 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001169 area->no_summary = 1;
1170
1171 return 1;
1172}
1173
1174int
1175ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1176{
1177 struct ospf_area *area;
1178
paul68980082003-03-25 05:07:42 +00001179 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001180 if (area == NULL)
1181 return 0;
1182
1183 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001184 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001185
1186 return 1;
1187}
1188
1189int
1190ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1191{
1192 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001193 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001194
paul68980082003-03-25 05:07:42 +00001195 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001196 if (ospf_area_vlink_count (ospf, area))
1197 return 0;
1198
1199 if (area->external_routing != OSPF_AREA_NSSA)
1200 {
1201 ospf_area_type_set (area, OSPF_AREA_NSSA);
1202 ospf->anyNSSA++;
1203 }
1204
paul084c7842003-06-22 08:35:18 +00001205 /* set NSSA area defaults */
1206 area->no_summary = 0;
1207 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001208 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001209 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1210
paul718e3742002-12-13 20:15:29 +00001211 return 1;
1212}
1213
1214int
1215ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1216{
1217 struct ospf_area *area;
1218
paul68980082003-03-25 05:07:42 +00001219 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001220 if (area == NULL)
1221 return 0;
1222
1223 if (area->external_routing == OSPF_AREA_NSSA)
1224 {
1225 ospf->anyNSSA--;
1226 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1227 }
1228
paul68980082003-03-25 05:07:42 +00001229 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001230
1231 return 1;
1232}
1233
1234int
1235ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1236 int role)
1237{
1238 struct ospf_area *area;
1239
paul68980082003-03-25 05:07:42 +00001240 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001241 if (area == NULL)
1242 return 0;
1243
paul084c7842003-06-22 08:35:18 +00001244 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001245
1246 return 1;
1247}
1248
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001249#if 0
paul4dadc292005-05-06 21:37:42 +00001250/* XXX: unused? Leave for symmetry? */
1251static int
paul718e3742002-12-13 20:15:29 +00001252ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1253 struct in_addr area_id)
1254{
1255 struct ospf_area *area;
1256
paul68980082003-03-25 05:07:42 +00001257 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001258 if (area == NULL)
1259 return 0;
1260
paul084c7842003-06-22 08:35:18 +00001261 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001262
paul68980082003-03-25 05:07:42 +00001263 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001264
1265 return 1;
1266}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001267#endif
paul718e3742002-12-13 20:15:29 +00001268
1269int
paul68980082003-03-25 05:07:42 +00001270ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001271 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001272{
1273 struct access_list *list;
1274 list = access_list_lookup (AFI_IP, list_name);
1275
1276 EXPORT_LIST (area) = list;
1277
1278 if (EXPORT_NAME (area))
1279 free (EXPORT_NAME (area));
1280
1281 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001282 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001283
1284 return 1;
1285}
1286
1287int
paul68980082003-03-25 05:07:42 +00001288ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001289{
1290
1291 EXPORT_LIST (area) = 0;
1292
1293 if (EXPORT_NAME (area))
1294 free (EXPORT_NAME (area));
1295
1296 EXPORT_NAME (area) = NULL;
1297
paul68980082003-03-25 05:07:42 +00001298 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001299
paul68980082003-03-25 05:07:42 +00001300 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001301
1302 return 1;
1303}
1304
1305int
paul6c835672004-10-11 11:00:30 +00001306ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1307 const char *name)
paul718e3742002-12-13 20:15:29 +00001308{
1309 struct access_list *list;
1310 list = access_list_lookup (AFI_IP, name);
1311
1312 IMPORT_LIST (area) = list;
1313
1314 if (IMPORT_NAME (area))
1315 free (IMPORT_NAME (area));
1316
1317 IMPORT_NAME (area) = strdup (name);
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
paul68980082003-03-25 05:07:42 +00001324ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001325{
1326 IMPORT_LIST (area) = 0;
1327
1328 if (IMPORT_NAME (area))
1329 free (IMPORT_NAME (area));
1330
1331 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001332 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001333
paul68980082003-03-25 05:07:42 +00001334 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001335
1336 return 1;
1337}
1338
1339int
paul718e3742002-12-13 20:15:29 +00001340ospf_timers_refresh_set (struct ospf *ospf, int interval)
1341{
1342 int time_left;
1343
1344 if (ospf->lsa_refresh_interval == interval)
1345 return 1;
1346
1347 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001348 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001349
1350 if (time_left > interval)
1351 {
1352 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1353 ospf->t_lsa_refresher =
1354 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1355 }
1356 ospf->lsa_refresh_interval = interval;
1357
1358 return 1;
1359}
1360
1361int
1362ospf_timers_refresh_unset (struct ospf *ospf)
1363{
1364 int time_left;
1365
1366 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001367 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001368
1369 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1370 {
1371 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1372 ospf->t_lsa_refresher =
1373 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1374 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1375 }
1376
1377 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1378
1379 return 1;
1380}
1381
David Lamparter6b0655a2014-06-04 06:53:35 +02001382
paul4dadc292005-05-06 21:37:42 +00001383static struct ospf_nbr_nbma *
1384ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001385{
1386 struct ospf_nbr_nbma *nbr_nbma;
1387
Stephen Hemminger393deb92008-08-18 14:13:29 -07001388 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001389 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001390
1391 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1392 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1393
1394 return nbr_nbma;
1395}
1396
paul4dadc292005-05-06 21:37:42 +00001397static void
paul718e3742002-12-13 20:15:29 +00001398ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1399{
1400 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1401}
1402
paul4dadc292005-05-06 21:37:42 +00001403static void
paul718e3742002-12-13 20:15:29 +00001404ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1405{
1406 struct route_node *rn;
1407 struct prefix_ipv4 p;
1408
1409 p.family = AF_INET;
1410 p.prefix = nbr_nbma->addr;
1411 p.prefixlen = IPV4_MAX_BITLEN;
1412
1413 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1414 if (rn)
1415 {
1416 ospf_nbr_nbma_free (rn->info);
1417 rn->info = NULL;
1418 route_unlock_node (rn);
1419 route_unlock_node (rn);
1420 }
1421}
1422
paul4dadc292005-05-06 21:37:42 +00001423static void
paul718e3742002-12-13 20:15:29 +00001424ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1425{
1426 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1427
1428 if (nbr_nbma->nbr)
1429 {
1430 nbr_nbma->nbr->nbr_nbma = NULL;
1431 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1432 }
1433
1434 if (nbr_nbma->oi)
1435 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1436}
1437
paul4dadc292005-05-06 21:37:42 +00001438static void
paul718e3742002-12-13 20:15:29 +00001439ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1440 struct ospf_interface *oi)
1441{
1442 struct ospf_neighbor *nbr;
1443 struct route_node *rn;
1444 struct prefix p;
1445
1446 if (oi->type != OSPF_IFTYPE_NBMA)
1447 return;
1448
1449 if (nbr_nbma->nbr != NULL)
1450 return;
1451
1452 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1453 return;
1454
1455 nbr_nbma->oi = oi;
1456 listnode_add (oi->nbr_nbma, nbr_nbma);
1457
1458 /* Get neighbor information from table. */
1459 p.family = AF_INET;
1460 p.prefixlen = IPV4_MAX_BITLEN;
1461 p.u.prefix4 = nbr_nbma->addr;
1462
1463 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1464 if (rn->info)
1465 {
1466 nbr = rn->info;
1467 nbr->nbr_nbma = nbr_nbma;
1468 nbr_nbma->nbr = nbr;
1469
1470 route_unlock_node (rn);
1471 }
1472 else
1473 {
1474 nbr = rn->info = ospf_nbr_new (oi);
1475 nbr->state = NSM_Down;
1476 nbr->src = nbr_nbma->addr;
1477 nbr->nbr_nbma = nbr_nbma;
1478 nbr->priority = nbr_nbma->priority;
1479 nbr->address = p;
1480
1481 nbr_nbma->nbr = nbr;
1482
1483 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1484 }
1485}
1486
1487void
paul68980082003-03-25 05:07:42 +00001488ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001489{
1490 struct ospf_nbr_nbma *nbr_nbma;
1491 struct route_node *rn;
1492 struct prefix_ipv4 p;
1493
1494 if (oi->type != OSPF_IFTYPE_NBMA)
1495 return;
1496
paul68980082003-03-25 05:07:42 +00001497 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001498 if ((nbr_nbma = rn->info))
1499 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1500 {
1501 p.family = AF_INET;
1502 p.prefix = nbr_nbma->addr;
1503 p.prefixlen = IPV4_MAX_BITLEN;
1504
1505 if (prefix_match (oi->address, (struct prefix *)&p))
1506 ospf_nbr_nbma_add (nbr_nbma, oi);
1507 }
1508}
1509
1510struct ospf_nbr_nbma *
1511ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1512{
1513 struct route_node *rn;
1514 struct prefix_ipv4 p;
1515
1516 p.family = AF_INET;
1517 p.prefix = nbr_addr;
1518 p.prefixlen = IPV4_MAX_BITLEN;
1519
1520 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1521 if (rn)
1522 {
1523 route_unlock_node (rn);
1524 return rn->info;
1525 }
1526 return NULL;
1527}
1528
1529struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001530ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001531{
1532#if 0
1533 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001534 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001535#endif
1536
paul68980082003-03-25 05:07:42 +00001537 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001538 return NULL;
1539
1540#if 0
paul1eb8ef22005-04-07 07:30:20 +00001541 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001542 {
paul718e3742002-12-13 20:15:29 +00001543 if (first)
1544 {
1545 *addr = nbr_nbma->addr;
1546 return nbr_nbma;
1547 }
1548 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1549 {
1550 *addr = nbr_nbma->addr;
1551 return nbr_nbma;
1552 }
1553 }
1554#endif
1555 return NULL;
1556}
1557
1558int
1559ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1560{
1561 struct ospf_nbr_nbma *nbr_nbma;
1562 struct ospf_interface *oi;
1563 struct prefix_ipv4 p;
1564 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001565 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001566
1567 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1568 if (nbr_nbma)
1569 return 0;
1570
1571 nbr_nbma = ospf_nbr_nbma_new ();
1572 nbr_nbma->addr = nbr_addr;
1573
1574 p.family = AF_INET;
1575 p.prefix = nbr_addr;
1576 p.prefixlen = IPV4_MAX_BITLEN;
1577
1578 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
Joakim Tjernlund4de398e2010-03-08 13:58:14 +01001579 if (rn->info)
1580 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001581 rn->info = nbr_nbma;
1582
paul1eb8ef22005-04-07 07:30:20 +00001583 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001584 {
paul718e3742002-12-13 20:15:29 +00001585 if (oi->type == OSPF_IFTYPE_NBMA)
1586 if (prefix_match (oi->address, (struct prefix *)&p))
1587 {
1588 ospf_nbr_nbma_add (nbr_nbma, oi);
1589 break;
1590 }
1591 }
1592
1593 return 1;
1594}
1595
1596int
1597ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
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 ospf_nbr_nbma_down (nbr_nbma);
1606 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1607
1608 return 1;
1609}
1610
1611int
1612ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1613 u_char priority)
1614{
1615 struct ospf_nbr_nbma *nbr_nbma;
1616
1617 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1618 if (nbr_nbma == NULL)
1619 return 0;
1620
1621 if (nbr_nbma->priority != priority)
1622 nbr_nbma->priority = priority;
1623
1624 return 1;
1625}
1626
1627int
1628ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1629{
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 != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1637 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1638
1639 return 1;
1640}
1641
1642int
1643ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001644 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001645{
1646 struct ospf_nbr_nbma *nbr_nbma;
1647
1648 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1649 if (nbr_nbma == NULL)
1650 return 0;
1651
1652 if (nbr_nbma->v_poll != interval)
1653 {
1654 nbr_nbma->v_poll = interval;
1655 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1656 {
1657 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1658 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1659 nbr_nbma->v_poll);
1660 }
1661 }
1662
1663 return 1;
1664}
1665
1666int
1667ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1668{
1669 struct ospf_nbr_nbma *nbr_nbma;
1670
1671 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1672 if (nbr_nbma == NULL)
1673 return 0;
1674
1675 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1676 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1677
1678 return 1;
1679}
1680
paul718e3742002-12-13 20:15:29 +00001681void
paul020709f2003-04-04 02:44:16 +00001682ospf_master_init ()
1683{
1684 memset (&ospf_master, 0, sizeof (struct ospf_master));
1685
1686 om = &ospf_master;
1687 om->ospf = list_new ();
1688 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001689 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001690}