blob: c55bdaebffd89aa9b6d05093fafabe3052e778bd [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))
115 /* Update self-neighbor's router_id. */
116 oi->nbr_self->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000117
118 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000119 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000120 {
121 int type;
122 /* Originate each redistributed external route. */
123 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000124 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000125 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000126 ospf, type);
paul718e3742002-12-13 20:15:29 +0000127 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000128 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
Paul Jakma4021b602006-05-12 22:55:41 +0000129 thread_add_event (master, ospf_default_originate_timer, ospf, 0);
paul718e3742002-12-13 20:15:29 +0000130
paul68980082003-03-25 05:07:42 +0000131 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000132 }
133
Paul Jakmac363d382010-01-24 22:42:13 +0000134 /* update router-lsa's for each area */
135 ospf_router_lsa_update (ospf);
paulb29800a2005-11-20 14:50:45 +0000136
137 /* update ospf_interface's */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100138 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
139 ospf_if_update (ospf, ifp);
paul718e3742002-12-13 20:15:29 +0000140 }
141}
David Lamparter6b0655a2014-06-04 06:53:35 +0200142
paul718e3742002-12-13 20:15:29 +0000143/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000144static int
paul718e3742002-12-13 20:15:29 +0000145ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
146{
147 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
148 return 1;
149 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
150 return -1;
151 return 0;
152}
153
154/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000155static struct ospf *
156ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000157{
158 int i;
159
160 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
161
162 new->router_id.s_addr = htonl (0);
163 new->router_id_static.s_addr = htonl (0);
164
pauld57834f2005-07-12 20:04:22 +0000165 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000166 new->oiflist = list_new ();
167 new->vlinks = list_new ();
168 new->areas = list_new ();
169 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
170 new->networks = route_table_init ();
171 new->nbr_nbma = route_table_init ();
172
173 new->lsdb = ospf_lsdb_new ();
174
175 new->default_originate = DEFAULT_ORIGINATE_NONE;
176
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000177 new->passive_interface_default = OSPF_IF_ACTIVE;
178
paul718e3742002-12-13 20:15:29 +0000179 new->new_external_route = route_table_init ();
180 new->old_external_route = route_table_init ();
181 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000182
183 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000184 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800185 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
186
paul718e3742002-12-13 20:15:29 +0000187 /* Distribute parameter init. */
188 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
189 {
190 new->dmetric[i].type = -1;
191 new->dmetric[i].value = -1;
192 }
193 new->default_metric = -1;
194 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
195
196 /* SPF timer value init. */
197 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
198 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000199 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
200 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000201
202 /* MaxAge init. */
Dinesh Dutt2449fcd2013-08-24 07:54:17 +0000203 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800204 new->maxage_lsa = route_table_init();
paul718e3742002-12-13 20:15:29 +0000205 new->t_maxage_walker =
206 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000207 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000208
209 /* Distance table init. */
210 new->distance_table = route_table_init ();
211
212 new->lsa_refresh_queue.index = 0;
213 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
214 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
215 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000216 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000217
ajs5c333492005-02-23 15:43:01 +0000218 if ((new->fd = ospf_sock_init()) < 0)
219 {
220 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
221 "a socket");
222 exit(1);
223 }
Denis Ovsienkof102e752007-09-18 09:01:13 +0000224 new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
225 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
Andrew Certain0798cee2012-12-04 13:43:42 -0800226 zlog_debug ("%s: starting with OSPF send buffer size %u",
Denis Ovsienkof102e752007-09-18 09:01:13 +0000227 __func__, new->maxsndbuflen);
ajs5c333492005-02-23 15:43:01 +0000228 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
229 {
230 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
231 OSPF_MAX_PACKET_SIZE+1);
232 exit(1);
233 }
234 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000235 new->oi_write_q = list_new ();
236
237 return new;
238}
239
240struct ospf *
paul020709f2003-04-04 02:44:16 +0000241ospf_lookup ()
242{
243 if (listcount (om->ospf) == 0)
244 return NULL;
245
paul1eb8ef22005-04-07 07:30:20 +0000246 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000247}
248
paul4dadc292005-05-06 21:37:42 +0000249static void
paul020709f2003-04-04 02:44:16 +0000250ospf_add (struct ospf *ospf)
251{
252 listnode_add (om->ospf, ospf);
253}
254
paul4dadc292005-05-06 21:37:42 +0000255static void
paul020709f2003-04-04 02:44:16 +0000256ospf_delete (struct ospf *ospf)
257{
258 listnode_delete (om->ospf, ospf);
259}
260
261struct ospf *
paul718e3742002-12-13 20:15:29 +0000262ospf_get ()
263{
paul020709f2003-04-04 02:44:16 +0000264 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000265
paul020709f2003-04-04 02:44:16 +0000266 ospf = ospf_lookup ();
267 if (ospf == NULL)
268 {
269 ospf = ospf_new ();
270 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000271
paul020709f2003-04-04 02:44:16 +0000272 if (ospf->router_id_static.s_addr == 0)
273 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000274
275#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000276 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000277#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000278 }
paul68980082003-03-25 05:07:42 +0000279
280 return ospf;
paul718e3742002-12-13 20:15:29 +0000281}
David Lamparter6b0655a2014-06-04 06:53:35 +0200282
paulc9c93d52005-11-26 13:31:11 +0000283/* Handle the second half of deferred shutdown. This is called either
284 * from the deferred-shutdown timer thread, or directly through
285 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000286 *
287 * Function is to cleanup G-R state, if required then call ospf_finish_final
288 * to complete shutdown of this ospf instance. Possibly exit if the
289 * whole process is being shutdown and this was the last OSPF instance.
290 */
291static void
paulc9c93d52005-11-26 13:31:11 +0000292ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000293{
294 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000295 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000296
297 ospf_finish_final (ospf);
298
299 /* *ospf is now invalid */
300
301 /* ospfd being shut-down? If so, was this the last ospf instance? */
302 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
303 && (listcount (om->ospf) == 0))
304 exit (0);
305
306 return;
307}
308
309/* Timer thread for G-R */
310static int
paulc9c93d52005-11-26 13:31:11 +0000311ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000312{
313 struct ospf *ospf = THREAD_ARG(t);
314
paulc9c93d52005-11-26 13:31:11 +0000315 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000316
317 return 0;
318}
319
paulc9c93d52005-11-26 13:31:11 +0000320/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000321 * down directly into second-half of instance shutdown.
322 */
323static void
paulc9c93d52005-11-26 13:31:11 +0000324ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000325{
326 unsigned long timeout;
327 struct listnode *ln;
328 struct ospf_area *area;
329
paulc9c93d52005-11-26 13:31:11 +0000330 /* deferred shutdown already running? */
331 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000332 return;
333
334 /* Should we try push out max-metric LSAs? */
335 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
336 {
337 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
338 {
339 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
340
341 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
Paul Jakmac363d382010-01-24 22:42:13 +0000342 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000343 }
344 timeout = ospf->stub_router_shutdown_time;
345 }
346 else
paulc9c93d52005-11-26 13:31:11 +0000347 {
348 /* No timer needed */
349 ospf_deferred_shutdown_finish (ospf);
350 return;
351 }
paul88d6cf32005-10-29 12:50:09 +0000352
paulc9c93d52005-11-26 13:31:11 +0000353 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000354 timeout);
355 return;
356}
David Lamparter6b0655a2014-06-04 06:53:35 +0200357
paul88d6cf32005-10-29 12:50:09 +0000358/* Shut down the entire process */
359void
360ospf_terminate (void)
361{
362 struct ospf *ospf;
363 struct listnode *node, *nnode;
364
365 /* shutdown already in progress */
366 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
367 return;
368
369 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
370
Andrew J. Schorr4056a542007-02-27 13:55:46 +0000371 /* exit immediately if OSPF not actually running */
372 if (listcount(om->ospf) == 0)
373 exit(0);
374
paul88d6cf32005-10-29 12:50:09 +0000375 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
376 ospf_finish (ospf);
377
378 /* Deliberately go back up, hopefully to thread scheduler, as
379 * One or more ospf_finish()'s may have deferred shutdown to a timer
380 * thread
381 */
382}
paul718e3742002-12-13 20:15:29 +0000383
384void
385ospf_finish (struct ospf *ospf)
386{
paulc9c93d52005-11-26 13:31:11 +0000387 /* let deferred shutdown decide */
388 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000389
paulc9c93d52005-11-26 13:31:11 +0000390 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000391 * deferred to expiry of G-S timer thread. Return back up, hopefully
392 * to thread scheduler.
393 */
paulc9c93d52005-11-26 13:31:11 +0000394 return;
paul88d6cf32005-10-29 12:50:09 +0000395}
396
397/* Final cleanup of ospf instance */
398static void
399ospf_finish_final (struct ospf *ospf)
400{
paul718e3742002-12-13 20:15:29 +0000401 struct route_node *rn;
402 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000403 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000404 struct ospf_interface *oi;
405 struct ospf_area *area;
406 struct ospf_vl_data *vl_data;
407 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000408 int i;
409
410#ifdef HAVE_OPAQUE_LSA
411 ospf_opaque_type11_lsa_term (ospf);
412#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000413
414 /* be nice if this worked, but it doesn't */
415 /*ospf_flush_self_originated_lsas_now (ospf);*/
416
417 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000418 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000419 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000420 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000421
paul1eb8ef22005-04-07 07:30:20 +0000422 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
423 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000424
paul1eb8ef22005-04-07 07:30:20 +0000425 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
426 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000427
428 list_delete (ospf->vlinks);
429
430 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
432 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000433
434 /* Clear static neighbors */
435 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
436 if ((nbr_nbma = rn->info))
437 {
438 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
439
440 if (nbr_nbma->nbr)
441 {
442 nbr_nbma->nbr->nbr_nbma = NULL;
443 nbr_nbma->nbr = NULL;
444 }
445
446 if (nbr_nbma->oi)
447 {
448 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
449 nbr_nbma->oi = NULL;
450 }
451
452 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
453 }
454
455 route_table_finish (ospf->nbr_nbma);
456
457 /* Clear networks and Areas. */
458 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
459 {
460 struct ospf_network *network;
461
462 if ((network = rn->info) != NULL)
463 {
paul68980082003-03-25 05:07:42 +0000464 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000465 rn->info = NULL;
466 route_unlock_node (rn);
467 }
468 }
469
paul1eb8ef22005-04-07 07:30:20 +0000470 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000471 {
paul718e3742002-12-13 20:15:29 +0000472 listnode_delete (ospf->areas, area);
473 ospf_area_free (area);
474 }
475
476 /* Cancel all timers. */
477 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000478 OSPF_TIMER_OFF (ospf->t_spf_calc);
479 OSPF_TIMER_OFF (ospf->t_ase_calc);
480 OSPF_TIMER_OFF (ospf->t_maxage);
481 OSPF_TIMER_OFF (ospf->t_maxage_walker);
482 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000483 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000484 OSPF_TIMER_OFF (ospf->t_distribute_update);
485 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
486 OSPF_TIMER_OFF (ospf->t_read);
487 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000488#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000489 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000490#endif
paul718e3742002-12-13 20:15:29 +0000491
492 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000493 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000494
495#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000496 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
497 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000498#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000499 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
500 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
501
paul718e3742002-12-13 20:15:29 +0000502 ospf_lsdb_delete_all (ospf->lsdb);
503 ospf_lsdb_free (ospf->lsdb);
504
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800505 for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
506 {
507 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000508
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800509 if ((lsa = rn->info) != NULL)
510 {
511 ospf_lsa_unlock (&lsa);
512 rn->info = NULL;
513 }
514 route_unlock_node (rn);
515 }
516 route_table_finish (ospf->maxage_lsa);
paul718e3742002-12-13 20:15:29 +0000517
518 if (ospf->old_table)
519 ospf_route_table_free (ospf->old_table);
520 if (ospf->new_table)
521 {
522 ospf_route_delete (ospf->new_table);
523 ospf_route_table_free (ospf->new_table);
524 }
525 if (ospf->old_rtrs)
526 ospf_rtrs_free (ospf->old_rtrs);
527 if (ospf->new_rtrs)
528 ospf_rtrs_free (ospf->new_rtrs);
529 if (ospf->new_external_route)
530 {
531 ospf_route_delete (ospf->new_external_route);
532 ospf_route_table_free (ospf->new_external_route);
533 }
534 if (ospf->old_external_route)
535 {
536 ospf_route_delete (ospf->old_external_route);
537 ospf_route_table_free (ospf->old_external_route);
538 }
539 if (ospf->external_lsas)
540 {
541 ospf_ase_external_lsas_finish (ospf->external_lsas);
542 }
543
544 list_delete (ospf->areas);
545
546 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
547 if (EXTERNAL_INFO (i) != NULL)
548 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
549 {
550 if (rn->info == NULL)
551 continue;
552
553 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
554 rn->info = NULL;
555 route_unlock_node (rn);
556 }
557
paul68980082003-03-25 05:07:42 +0000558 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000559 route_table_finish (ospf->distance_table);
560
paul020709f2003-04-04 02:44:16 +0000561 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000562
paul020709f2003-04-04 02:44:16 +0000563 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000564}
565
David Lamparter6b0655a2014-06-04 06:53:35 +0200566
paul718e3742002-12-13 20:15:29 +0000567/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000568static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000569ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000570{
571 struct ospf_area *new;
572
573 /* Allocate new config_network. */
574 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
575
paul68980082003-03-25 05:07:42 +0000576 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000577
578 new->area_id = area_id;
579
580 new->external_routing = OSPF_AREA_DEFAULT;
581 new->default_cost = 1;
582 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000583
paul718e3742002-12-13 20:15:29 +0000584 /* New LSDB init. */
585 new->lsdb = ospf_lsdb_new ();
586
587 /* Self-originated LSAs initialize. */
588 new->router_lsa_self = NULL;
589
590#ifdef HAVE_OPAQUE_LSA
591 ospf_opaque_type10_lsa_init (new);
592#endif /* HAVE_OPAQUE_LSA */
593
594 new->oiflist = list_new ();
595 new->ranges = route_table_init ();
596
597 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000598 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000599
600 return new;
601}
602
Stephen Hemminger917e2992009-12-03 19:07:00 +0300603static void
paul718e3742002-12-13 20:15:29 +0000604ospf_area_free (struct ospf_area *area)
605{
paul68980082003-03-25 05:07:42 +0000606 struct route_node *rn;
607 struct ospf_lsa *lsa;
608
paul718e3742002-12-13 20:15:29 +0000609 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000610 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
611 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
612 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
613 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
614 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
615 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
616 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
617 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000618
paul68980082003-03-25 05:07:42 +0000619 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
620 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000621#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000622 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
623 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
624 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
625 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000626#endif /* HAVE_OPAQUE_LSA */
627
628 ospf_lsdb_delete_all (area->lsdb);
629 ospf_lsdb_free (area->lsdb);
630
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000631 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000632
633 route_table_finish (area->ranges);
634 list_delete (area->oiflist);
635
636 if (EXPORT_NAME (area))
637 free (EXPORT_NAME (area));
638
639 if (IMPORT_NAME (area))
640 free (IMPORT_NAME (area));
641
642 /* Cancel timer. */
paul88d6cf32005-10-29 12:50:09 +0000643 OSPF_TIMER_OFF (area->t_stub_router);
644#ifdef HAVE_OPAQUE_LSA
645 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
646#endif /* HAVE_OPAQUE_LSA */
647
paul718e3742002-12-13 20:15:29 +0000648 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000649 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000650
651 XFREE (MTYPE_OSPF_AREA, area);
652}
653
654void
paul68980082003-03-25 05:07:42 +0000655ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000656{
657 struct ospf_area *area;
658
paul68980082003-03-25 05:07:42 +0000659 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000660 if (area &&
661 listcount (area->oiflist) == 0 &&
662 area->ranges->top == NULL &&
663 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
664 area->external_routing == OSPF_AREA_DEFAULT &&
665 area->no_summary == 0 &&
666 area->default_cost == 1 &&
667 EXPORT_NAME (area) == NULL &&
668 IMPORT_NAME (area) == NULL &&
669 area->auth_type == OSPF_AUTH_NULL)
670 {
paul68980082003-03-25 05:07:42 +0000671 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000672 ospf_area_free (area);
673 }
674}
675
676struct ospf_area *
paul68980082003-03-25 05:07:42 +0000677ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000678{
679 struct ospf_area *area;
680
paul68980082003-03-25 05:07:42 +0000681 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000682 if (!area)
683 {
paul68980082003-03-25 05:07:42 +0000684 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000685 area->format = format;
paul68980082003-03-25 05:07:42 +0000686 listnode_add_sort (ospf->areas, area);
687 ospf_check_abr_status (ospf);
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800688 if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
689 {
690 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
691 }
paul718e3742002-12-13 20:15:29 +0000692 }
693
694 return area;
695}
696
697struct ospf_area *
paul68980082003-03-25 05:07:42 +0000698ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000699{
700 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000701 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000702
paul1eb8ef22005-04-07 07:30:20 +0000703 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
704 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
705 return area;
paul718e3742002-12-13 20:15:29 +0000706
707 return NULL;
708}
709
710void
711ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
712{
713 listnode_add (area->oiflist, oi);
714}
715
716void
717ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
718{
719 listnode_delete (area->oiflist, oi);
720}
721
David Lamparter6b0655a2014-06-04 06:53:35 +0200722
paul718e3742002-12-13 20:15:29 +0000723/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000724static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000725ospf_network_new (struct in_addr area_id, int format)
726{
727 struct ospf_network *new;
728 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
729
730 new->area_id = area_id;
731 new->format = format;
732
733 return new;
734}
735
Stephen Hemminger917e2992009-12-03 19:07:00 +0300736static void
paul68980082003-03-25 05:07:42 +0000737ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000738{
paul68980082003-03-25 05:07:42 +0000739 ospf_area_check_free (ospf, network->area_id);
740 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000741 XFREE (MTYPE_OSPF_NETWORK, network);
742}
743
744int
745ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
746 struct in_addr area_id)
747{
748 struct ospf_network *network;
749 struct ospf_area *area;
750 struct route_node *rn;
751 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000752 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000753
754 rn = route_node_get (ospf->networks, (struct prefix *)p);
755 if (rn->info)
756 {
757 /* There is already same network statement. */
758 route_unlock_node (rn);
759 return 0;
760 }
761
762 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000763 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000764
765 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100766 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000767
768 /* Update connected redistribute. */
769 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
770 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
771 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
772 rn; rn = route_next (rn))
773 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000774 if (ospf_external_info_find_lsa (ospf, &ei->p))
775 if (!ospf_distribute_check_connected (ospf, ei))
776 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000777 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000778
paul68980082003-03-25 05:07:42 +0000779 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000780
781 return 1;
782}
783
784int
785ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
786 struct in_addr area_id)
787{
788 struct route_node *rn;
789 struct ospf_network *network;
790 struct external_info *ei;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100791 struct listnode *node, *nnode;
792 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000793
794 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
795 if (rn == NULL)
796 return 0;
797
798 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700799 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000800 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
801 return 0;
802
paul68980082003-03-25 05:07:42 +0000803 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000804 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700805 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000806
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100807 /* Find interfaces that not configured already. */
808 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
809 {
810 int found = 0;
811 struct connected *co = oi->connected;
812
813 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
814 continue;
815
816 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
817 {
818 if (rn->info == NULL)
819 continue;
820
821 if (ospf_network_match_iface(co,&rn->p))
822 {
823 found = 1;
824 route_unlock_node (rn);
825 break;
826 }
827 }
828
829 if (found == 0)
Joakim Tjernlund6b274d92010-03-09 06:42:30 +0000830 {
831 ospf_if_free (oi);
832 ospf_area_check_free (ospf, area_id);
833 }
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100834 }
paul718e3742002-12-13 20:15:29 +0000835
836 /* Update connected redistribute. */
837 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
838 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
839 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
840 rn; rn = route_next (rn))
841 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000842 if (!ospf_external_info_find_lsa (ospf, &ei->p))
843 if (ospf_distribute_check_connected (ospf, ei))
844 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000845
846 return 1;
847}
848
paul570f7592003-01-25 06:47:41 +0000849/* Check whether interface matches given network
850 * returns: 1, true. 0, false
851 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300852static int
853ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000854{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000855 /* new approach: more elegant and conceptually clean */
856 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000857}
858
Stephen Hemminger917e2992009-12-03 19:07:00 +0300859static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100860ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
861 struct interface *ifp)
862{
863 struct listnode *cnode;
864 struct connected *co;
865
866 if (memcmp (ifp->name, "VLINK", 5) == 0)
867 return;
868
869 /* if interface prefix is match specified prefix,
870 then create socket and join multicast group. */
871 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
872 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200873
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100874 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
875 continue;
876
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100877 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200878 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100879 && ospf_network_match_iface(co,p))
880 {
881 struct ospf_interface *oi;
882
883 oi = ospf_if_new (area->ospf, ifp, co->address);
884 oi->connected = co;
885
886 oi->area = area;
887
888 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
889 oi->output_cost = ospf_if_get_output_cost (oi);
890
891 /* Add pseudo neighbor. */
892 ospf_nbr_add_self (oi);
893
894 /* Relate ospf interface to ospf instance. */
895 oi->ospf = area->ospf;
896
897 /* update network type as interface flag */
898 /* If network type is specified previously,
899 skip network type setting. */
900 oi->type = IF_DEF_PARAMS (ifp)->type;
901
902 ospf_area_add_if (oi->area, oi);
903
904 /* if router_id is not configured, dont bring up
905 * interfaces.
906 * ospf_router_id_update() will call ospf_if_update
907 * whenever r-id is configured instead.
908 */
909 if ((area->ospf->router_id.s_addr != 0)
910 && if_is_operative (ifp))
911 ospf_if_up (oi);
912 }
913 }
914}
915
Stephen Hemminger917e2992009-12-03 19:07:00 +0300916static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100917ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000918{
919 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000920 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000921
922 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100923 if (area->ospf->router_id.s_addr == 0)
924 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000925
paul718e3742002-12-13 20:15:29 +0000926 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000927 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100928 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000929}
930
931void
932ospf_ls_upd_queue_empty (struct ospf_interface *oi)
933{
934 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000935 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000936 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000937 struct ospf_lsa *lsa;
938
939 /* empty ls update queue */
940 for (rn = route_top (oi->ls_upd_queue); rn;
941 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000942 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000943 {
paul1eb8ef22005-04-07 07:30:20 +0000944 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000945 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000946 list_free (lst);
947 rn->info = NULL;
948 }
949
950 /* remove update event */
951 if (oi->t_ls_upd_event)
952 {
953 thread_cancel (oi->t_ls_upd_event);
954 oi->t_ls_upd_event = NULL;
955 }
956}
957
958void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100959ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000960{
961 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000962 struct ospf_network *network;
963 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100964
965 if (!ospf)
966 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000967
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100968 /* OSPF must be on and Router-ID must be configured. */
969 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100970 return;
971
972 /* Run each netowrk for this interface. */
973 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
974 if (rn->info != NULL)
975 {
976 network = (struct ospf_network *) rn->info;
977 area = ospf_area_get (ospf, network->area_id, network->format);
978 ospf_network_run_interface (&rn->p, area, ifp);
979 }
paul718e3742002-12-13 20:15:29 +0000980}
981
982void
paul68980082003-03-25 05:07:42 +0000983ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000984{
paul1eb8ef22005-04-07 07:30:20 +0000985 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000986 struct ospf_vl_data *vl_data;
987
paul1eb8ef22005-04-07 07:30:20 +0000988 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
989 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
990 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000991}
992
David Lamparter6b0655a2014-06-04 06:53:35 +0200993
Stephen Hemminger7ba82f72009-05-15 10:47:45 -0700994static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +0000995{
996 { OSPF_AREA_DEFAULT, "Default" },
997 { OSPF_AREA_STUB, "Stub" },
998 { OSPF_AREA_NSSA, "NSSA" },
999};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001000static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +00001001
paul4dadc292005-05-06 21:37:42 +00001002static void
paul718e3742002-12-13 20:15:29 +00001003ospf_area_type_set (struct ospf_area *area, int type)
1004{
hasso52dc7ee2004-09-23 19:18:23 +00001005 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001006 struct ospf_interface *oi;
1007
1008 if (area->external_routing == type)
1009 {
1010 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001011 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001012 inet_ntoa (area->area_id));
1013 return;
1014 }
1015
1016 area->external_routing = type;
1017
1018 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001019 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001020 LOOKUP (ospf_area_type_msg, type));
1021
1022 switch (area->external_routing)
1023 {
1024 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001025 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1026 if (oi->nbr_self != NULL)
1027 {
1028 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1029 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1030 }
paul718e3742002-12-13 20:15:29 +00001031 break;
1032 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001033 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1034 if (oi->nbr_self != NULL)
1035 {
1036 if (IS_DEBUG_OSPF_EVENT)
1037 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1038 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1039 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1040 if (IS_DEBUG_OSPF_EVENT)
1041 zlog_debug ("options set on %s: %x",
1042 IF_NAME (oi), OPTIONS (oi));
1043 }
paul718e3742002-12-13 20:15:29 +00001044 break;
1045 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001046 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1047 if (oi->nbr_self != NULL)
1048 {
1049 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1050 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1051 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1052 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1053 }
paul718e3742002-12-13 20:15:29 +00001054 break;
1055 default:
1056 break;
1057 }
1058
Paul Jakmac363d382010-01-24 22:42:13 +00001059 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001060 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001061}
1062
1063int
paul68980082003-03-25 05:07:42 +00001064ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001065{
1066 if (area->shortcut_configured == mode)
1067 return 0;
1068
1069 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001070 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001071 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001072
paul68980082003-03-25 05:07:42 +00001073 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001074
1075 return 1;
1076}
1077
1078int
paul68980082003-03-25 05:07:42 +00001079ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001080{
1081 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001082 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001083 ospf_area_check_free (ospf, area->area_id);
1084 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001085
1086 return 1;
1087}
1088
paul4dadc292005-05-06 21:37:42 +00001089static int
paul718e3742002-12-13 20:15:29 +00001090ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1091{
1092 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001093 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001094 int count = 0;
1095
paul1eb8ef22005-04-07 07:30:20 +00001096 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1097 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1098 count++;
paul718e3742002-12-13 20:15:29 +00001099
1100 return count;
1101}
1102
1103int
1104ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1105{
1106 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001107 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001108
paul68980082003-03-25 05:07:42 +00001109 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001110 if (ospf_area_vlink_count (ospf, area))
1111 return 0;
1112
1113 if (area->external_routing != OSPF_AREA_STUB)
1114 ospf_area_type_set (area, OSPF_AREA_STUB);
1115
1116 return 1;
1117}
1118
1119int
1120ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1121{
1122 struct ospf_area *area;
1123
paul68980082003-03-25 05:07:42 +00001124 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001125 if (area == NULL)
1126 return 1;
1127
1128 if (area->external_routing == OSPF_AREA_STUB)
1129 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1130
paul68980082003-03-25 05:07:42 +00001131 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001132
1133 return 1;
1134}
1135
1136int
1137ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1138{
1139 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001140 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001141
paul68980082003-03-25 05:07:42 +00001142 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001143 area->no_summary = 1;
1144
1145 return 1;
1146}
1147
1148int
1149ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1150{
1151 struct ospf_area *area;
1152
paul68980082003-03-25 05:07:42 +00001153 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001154 if (area == NULL)
1155 return 0;
1156
1157 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001158 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001159
1160 return 1;
1161}
1162
1163int
1164ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1165{
1166 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001167 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001168
paul68980082003-03-25 05:07:42 +00001169 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001170 if (ospf_area_vlink_count (ospf, area))
1171 return 0;
1172
1173 if (area->external_routing != OSPF_AREA_NSSA)
1174 {
1175 ospf_area_type_set (area, OSPF_AREA_NSSA);
1176 ospf->anyNSSA++;
1177 }
1178
paul084c7842003-06-22 08:35:18 +00001179 /* set NSSA area defaults */
1180 area->no_summary = 0;
1181 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001182 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001183 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1184
paul718e3742002-12-13 20:15:29 +00001185 return 1;
1186}
1187
1188int
1189ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1190{
1191 struct ospf_area *area;
1192
paul68980082003-03-25 05:07:42 +00001193 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001194 if (area == NULL)
1195 return 0;
1196
1197 if (area->external_routing == OSPF_AREA_NSSA)
1198 {
1199 ospf->anyNSSA--;
1200 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1201 }
1202
paul68980082003-03-25 05:07:42 +00001203 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001204
1205 return 1;
1206}
1207
1208int
1209ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1210 int role)
1211{
1212 struct ospf_area *area;
1213
paul68980082003-03-25 05:07:42 +00001214 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001215 if (area == NULL)
1216 return 0;
1217
paul084c7842003-06-22 08:35:18 +00001218 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001219
1220 return 1;
1221}
1222
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001223#if 0
paul4dadc292005-05-06 21:37:42 +00001224/* XXX: unused? Leave for symmetry? */
1225static int
paul718e3742002-12-13 20:15:29 +00001226ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1227 struct in_addr area_id)
1228{
1229 struct ospf_area *area;
1230
paul68980082003-03-25 05:07:42 +00001231 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001232 if (area == NULL)
1233 return 0;
1234
paul084c7842003-06-22 08:35:18 +00001235 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001236
paul68980082003-03-25 05:07:42 +00001237 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001238
1239 return 1;
1240}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001241#endif
paul718e3742002-12-13 20:15:29 +00001242
1243int
paul68980082003-03-25 05:07:42 +00001244ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001245 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001246{
1247 struct access_list *list;
1248 list = access_list_lookup (AFI_IP, list_name);
1249
1250 EXPORT_LIST (area) = list;
1251
1252 if (EXPORT_NAME (area))
1253 free (EXPORT_NAME (area));
1254
1255 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001256 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001257
1258 return 1;
1259}
1260
1261int
paul68980082003-03-25 05:07:42 +00001262ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001263{
1264
1265 EXPORT_LIST (area) = 0;
1266
1267 if (EXPORT_NAME (area))
1268 free (EXPORT_NAME (area));
1269
1270 EXPORT_NAME (area) = NULL;
1271
paul68980082003-03-25 05:07:42 +00001272 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001273
paul68980082003-03-25 05:07:42 +00001274 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001275
1276 return 1;
1277}
1278
1279int
paul6c835672004-10-11 11:00:30 +00001280ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1281 const char *name)
paul718e3742002-12-13 20:15:29 +00001282{
1283 struct access_list *list;
1284 list = access_list_lookup (AFI_IP, name);
1285
1286 IMPORT_LIST (area) = list;
1287
1288 if (IMPORT_NAME (area))
1289 free (IMPORT_NAME (area));
1290
1291 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001292 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001293
1294 return 1;
1295}
1296
1297int
paul68980082003-03-25 05:07:42 +00001298ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001299{
1300 IMPORT_LIST (area) = 0;
1301
1302 if (IMPORT_NAME (area))
1303 free (IMPORT_NAME (area));
1304
1305 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001306 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001307
paul68980082003-03-25 05:07:42 +00001308 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001309
1310 return 1;
1311}
1312
1313int
paul718e3742002-12-13 20:15:29 +00001314ospf_timers_refresh_set (struct ospf *ospf, int interval)
1315{
1316 int time_left;
1317
1318 if (ospf->lsa_refresh_interval == interval)
1319 return 1;
1320
1321 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001322 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001323
1324 if (time_left > interval)
1325 {
1326 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1327 ospf->t_lsa_refresher =
1328 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1329 }
1330 ospf->lsa_refresh_interval = interval;
1331
1332 return 1;
1333}
1334
1335int
1336ospf_timers_refresh_unset (struct ospf *ospf)
1337{
1338 int time_left;
1339
1340 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001341 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001342
1343 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1344 {
1345 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1346 ospf->t_lsa_refresher =
1347 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1348 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1349 }
1350
1351 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1352
1353 return 1;
1354}
1355
David Lamparter6b0655a2014-06-04 06:53:35 +02001356
paul4dadc292005-05-06 21:37:42 +00001357static struct ospf_nbr_nbma *
1358ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001359{
1360 struct ospf_nbr_nbma *nbr_nbma;
1361
Stephen Hemminger393deb92008-08-18 14:13:29 -07001362 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001363 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001364
1365 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1366 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1367
1368 return nbr_nbma;
1369}
1370
paul4dadc292005-05-06 21:37:42 +00001371static void
paul718e3742002-12-13 20:15:29 +00001372ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1373{
1374 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1375}
1376
paul4dadc292005-05-06 21:37:42 +00001377static void
paul718e3742002-12-13 20:15:29 +00001378ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1379{
1380 struct route_node *rn;
1381 struct prefix_ipv4 p;
1382
1383 p.family = AF_INET;
1384 p.prefix = nbr_nbma->addr;
1385 p.prefixlen = IPV4_MAX_BITLEN;
1386
1387 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1388 if (rn)
1389 {
1390 ospf_nbr_nbma_free (rn->info);
1391 rn->info = NULL;
1392 route_unlock_node (rn);
1393 route_unlock_node (rn);
1394 }
1395}
1396
paul4dadc292005-05-06 21:37:42 +00001397static void
paul718e3742002-12-13 20:15:29 +00001398ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1399{
1400 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1401
1402 if (nbr_nbma->nbr)
1403 {
1404 nbr_nbma->nbr->nbr_nbma = NULL;
1405 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1406 }
1407
1408 if (nbr_nbma->oi)
1409 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1410}
1411
paul4dadc292005-05-06 21:37:42 +00001412static void
paul718e3742002-12-13 20:15:29 +00001413ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1414 struct ospf_interface *oi)
1415{
1416 struct ospf_neighbor *nbr;
1417 struct route_node *rn;
1418 struct prefix p;
1419
1420 if (oi->type != OSPF_IFTYPE_NBMA)
1421 return;
1422
1423 if (nbr_nbma->nbr != NULL)
1424 return;
1425
1426 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1427 return;
1428
1429 nbr_nbma->oi = oi;
1430 listnode_add (oi->nbr_nbma, nbr_nbma);
1431
1432 /* Get neighbor information from table. */
1433 p.family = AF_INET;
1434 p.prefixlen = IPV4_MAX_BITLEN;
1435 p.u.prefix4 = nbr_nbma->addr;
1436
1437 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1438 if (rn->info)
1439 {
1440 nbr = rn->info;
1441 nbr->nbr_nbma = nbr_nbma;
1442 nbr_nbma->nbr = nbr;
1443
1444 route_unlock_node (rn);
1445 }
1446 else
1447 {
1448 nbr = rn->info = ospf_nbr_new (oi);
1449 nbr->state = NSM_Down;
1450 nbr->src = nbr_nbma->addr;
1451 nbr->nbr_nbma = nbr_nbma;
1452 nbr->priority = nbr_nbma->priority;
1453 nbr->address = p;
1454
1455 nbr_nbma->nbr = nbr;
1456
1457 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1458 }
1459}
1460
1461void
paul68980082003-03-25 05:07:42 +00001462ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001463{
1464 struct ospf_nbr_nbma *nbr_nbma;
1465 struct route_node *rn;
1466 struct prefix_ipv4 p;
1467
1468 if (oi->type != OSPF_IFTYPE_NBMA)
1469 return;
1470
paul68980082003-03-25 05:07:42 +00001471 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001472 if ((nbr_nbma = rn->info))
1473 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1474 {
1475 p.family = AF_INET;
1476 p.prefix = nbr_nbma->addr;
1477 p.prefixlen = IPV4_MAX_BITLEN;
1478
1479 if (prefix_match (oi->address, (struct prefix *)&p))
1480 ospf_nbr_nbma_add (nbr_nbma, oi);
1481 }
1482}
1483
1484struct ospf_nbr_nbma *
1485ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1486{
1487 struct route_node *rn;
1488 struct prefix_ipv4 p;
1489
1490 p.family = AF_INET;
1491 p.prefix = nbr_addr;
1492 p.prefixlen = IPV4_MAX_BITLEN;
1493
1494 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1495 if (rn)
1496 {
1497 route_unlock_node (rn);
1498 return rn->info;
1499 }
1500 return NULL;
1501}
1502
1503struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001504ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001505{
1506#if 0
1507 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001508 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001509#endif
1510
paul68980082003-03-25 05:07:42 +00001511 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001512 return NULL;
1513
1514#if 0
paul1eb8ef22005-04-07 07:30:20 +00001515 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001516 {
paul718e3742002-12-13 20:15:29 +00001517 if (first)
1518 {
1519 *addr = nbr_nbma->addr;
1520 return nbr_nbma;
1521 }
1522 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1523 {
1524 *addr = nbr_nbma->addr;
1525 return nbr_nbma;
1526 }
1527 }
1528#endif
1529 return NULL;
1530}
1531
1532int
1533ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1534{
1535 struct ospf_nbr_nbma *nbr_nbma;
1536 struct ospf_interface *oi;
1537 struct prefix_ipv4 p;
1538 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001539 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001540
1541 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1542 if (nbr_nbma)
1543 return 0;
1544
1545 nbr_nbma = ospf_nbr_nbma_new ();
1546 nbr_nbma->addr = nbr_addr;
1547
1548 p.family = AF_INET;
1549 p.prefix = nbr_addr;
1550 p.prefixlen = IPV4_MAX_BITLEN;
1551
1552 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1553 rn->info = nbr_nbma;
1554
paul1eb8ef22005-04-07 07:30:20 +00001555 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001556 {
paul718e3742002-12-13 20:15:29 +00001557 if (oi->type == OSPF_IFTYPE_NBMA)
1558 if (prefix_match (oi->address, (struct prefix *)&p))
1559 {
1560 ospf_nbr_nbma_add (nbr_nbma, oi);
1561 break;
1562 }
1563 }
1564
1565 return 1;
1566}
1567
1568int
1569ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1570{
1571 struct ospf_nbr_nbma *nbr_nbma;
1572
1573 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1574 if (nbr_nbma == NULL)
1575 return 0;
1576
1577 ospf_nbr_nbma_down (nbr_nbma);
1578 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1579
1580 return 1;
1581}
1582
1583int
1584ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1585 u_char priority)
1586{
1587 struct ospf_nbr_nbma *nbr_nbma;
1588
1589 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1590 if (nbr_nbma == NULL)
1591 return 0;
1592
1593 if (nbr_nbma->priority != priority)
1594 nbr_nbma->priority = priority;
1595
1596 return 1;
1597}
1598
1599int
1600ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1601{
1602 struct ospf_nbr_nbma *nbr_nbma;
1603
1604 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1605 if (nbr_nbma == NULL)
1606 return 0;
1607
1608 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1609 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1610
1611 return 1;
1612}
1613
1614int
1615ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001616 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001617{
1618 struct ospf_nbr_nbma *nbr_nbma;
1619
1620 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1621 if (nbr_nbma == NULL)
1622 return 0;
1623
1624 if (nbr_nbma->v_poll != interval)
1625 {
1626 nbr_nbma->v_poll = interval;
1627 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1628 {
1629 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1630 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1631 nbr_nbma->v_poll);
1632 }
1633 }
1634
1635 return 1;
1636}
1637
1638int
1639ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1640{
1641 struct ospf_nbr_nbma *nbr_nbma;
1642
1643 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1644 if (nbr_nbma == NULL)
1645 return 0;
1646
1647 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1648 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1649
1650 return 1;
1651}
1652
paul718e3742002-12-13 20:15:29 +00001653void
paul020709f2003-04-04 02:44:16 +00001654ospf_master_init ()
1655{
1656 memset (&ospf_master, 0, sizeof (struct ospf_master));
1657
1658 om = &ospf_master;
1659 om->ospf = list_new ();
1660 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001661 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001662}