blob: 019a22b70fb022d9968709df196e4d3421f3ca78 [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 */
121 ospf_nbr_delete(oi->nbr_self);
122 ospf_nbr_add_self(oi);
123 }
paul718e3742002-12-13 20:15:29 +0000124
125 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000126 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000127 {
128 int type;
129 /* Originate each redistributed external route. */
130 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000131 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000132 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000133 ospf, type);
paul718e3742002-12-13 20:15:29 +0000134 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000135 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
Paul Jakma4021b602006-05-12 22:55:41 +0000136 thread_add_event (master, ospf_default_originate_timer, ospf, 0);
paul718e3742002-12-13 20:15:29 +0000137
paul68980082003-03-25 05:07:42 +0000138 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000139 }
140
Paul Jakmac363d382010-01-24 22:42:13 +0000141 /* update router-lsa's for each area */
142 ospf_router_lsa_update (ospf);
paulb29800a2005-11-20 14:50:45 +0000143
144 /* update ospf_interface's */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100145 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
146 ospf_if_update (ospf, ifp);
paul718e3742002-12-13 20:15:29 +0000147 }
148}
David Lamparter6b0655a2014-06-04 06:53:35 +0200149
paul718e3742002-12-13 20:15:29 +0000150/* For OSPF area sort by area id. */
paul4dadc292005-05-06 21:37:42 +0000151static int
paul718e3742002-12-13 20:15:29 +0000152ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
153{
154 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
155 return 1;
156 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
157 return -1;
158 return 0;
159}
160
161/* Allocate new ospf structure. */
paul4dadc292005-05-06 21:37:42 +0000162static struct ospf *
163ospf_new (void)
paul718e3742002-12-13 20:15:29 +0000164{
165 int i;
166
167 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
168
169 new->router_id.s_addr = htonl (0);
170 new->router_id_static.s_addr = htonl (0);
171
pauld57834f2005-07-12 20:04:22 +0000172 new->abr_type = OSPF_ABR_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000173 new->oiflist = list_new ();
174 new->vlinks = list_new ();
175 new->areas = list_new ();
176 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
177 new->networks = route_table_init ();
178 new->nbr_nbma = route_table_init ();
179
180 new->lsdb = ospf_lsdb_new ();
181
182 new->default_originate = DEFAULT_ORIGINATE_NONE;
183
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000184 new->passive_interface_default = OSPF_IF_ACTIVE;
185
paul718e3742002-12-13 20:15:29 +0000186 new->new_external_route = route_table_init ();
187 new->old_external_route = route_table_init ();
188 new->external_lsas = route_table_init ();
paul88d6cf32005-10-29 12:50:09 +0000189
190 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paul31a59762005-11-14 11:11:11 +0000191 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800192 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
193
paul718e3742002-12-13 20:15:29 +0000194 /* Distribute parameter init. */
195 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
196 {
197 new->dmetric[i].type = -1;
198 new->dmetric[i].value = -1;
199 }
200 new->default_metric = -1;
201 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
202
203 /* SPF timer value init. */
204 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
205 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
pauld24f6e22005-10-21 09:23:12 +0000206 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
207 new->spf_hold_multiplier = 1;
paul718e3742002-12-13 20:15:29 +0000208
209 /* MaxAge init. */
Dinesh Dutt2449fcd2013-08-24 07:54:17 +0000210 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800211 new->maxage_lsa = route_table_init();
paul718e3742002-12-13 20:15:29 +0000212 new->t_maxage_walker =
213 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000214 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000215
216 /* Distance table init. */
217 new->distance_table = route_table_init ();
218
219 new->lsa_refresh_queue.index = 0;
220 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
221 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
222 new, new->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +0000223 new->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +0000224
ajs5c333492005-02-23 15:43:01 +0000225 if ((new->fd = ospf_sock_init()) < 0)
226 {
227 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
228 "a socket");
229 exit(1);
230 }
Denis Ovsienkof102e752007-09-18 09:01:13 +0000231 new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
232 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
Andrew Certain0798cee2012-12-04 13:43:42 -0800233 zlog_debug ("%s: starting with OSPF send buffer size %u",
Denis Ovsienkof102e752007-09-18 09:01:13 +0000234 __func__, new->maxsndbuflen);
ajs5c333492005-02-23 15:43:01 +0000235 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
236 {
237 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
238 OSPF_MAX_PACKET_SIZE+1);
239 exit(1);
240 }
241 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
paul718e3742002-12-13 20:15:29 +0000242 new->oi_write_q = list_new ();
243
244 return new;
245}
246
247struct ospf *
paul020709f2003-04-04 02:44:16 +0000248ospf_lookup ()
249{
250 if (listcount (om->ospf) == 0)
251 return NULL;
252
paul1eb8ef22005-04-07 07:30:20 +0000253 return listgetdata (listhead (om->ospf));
paul020709f2003-04-04 02:44:16 +0000254}
255
paul4dadc292005-05-06 21:37:42 +0000256static void
paul020709f2003-04-04 02:44:16 +0000257ospf_add (struct ospf *ospf)
258{
259 listnode_add (om->ospf, ospf);
260}
261
paul4dadc292005-05-06 21:37:42 +0000262static void
paul020709f2003-04-04 02:44:16 +0000263ospf_delete (struct ospf *ospf)
264{
265 listnode_delete (om->ospf, ospf);
266}
267
268struct ospf *
paul718e3742002-12-13 20:15:29 +0000269ospf_get ()
270{
paul020709f2003-04-04 02:44:16 +0000271 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000272
paul020709f2003-04-04 02:44:16 +0000273 ospf = ospf_lookup ();
274 if (ospf == NULL)
275 {
276 ospf = ospf_new ();
277 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000278
paul020709f2003-04-04 02:44:16 +0000279 if (ospf->router_id_static.s_addr == 0)
280 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000281
282#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000283 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000284#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000285 }
paul68980082003-03-25 05:07:42 +0000286
287 return ospf;
paul718e3742002-12-13 20:15:29 +0000288}
David Lamparter6b0655a2014-06-04 06:53:35 +0200289
paulc9c93d52005-11-26 13:31:11 +0000290/* Handle the second half of deferred shutdown. This is called either
291 * from the deferred-shutdown timer thread, or directly through
292 * ospf_deferred_shutdown_check.
paul88d6cf32005-10-29 12:50:09 +0000293 *
294 * Function is to cleanup G-R state, if required then call ospf_finish_final
295 * to complete shutdown of this ospf instance. Possibly exit if the
296 * whole process is being shutdown and this was the last OSPF instance.
297 */
298static void
paulc9c93d52005-11-26 13:31:11 +0000299ospf_deferred_shutdown_finish (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000300{
301 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
paulc9c93d52005-11-26 13:31:11 +0000302 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
paul88d6cf32005-10-29 12:50:09 +0000303
304 ospf_finish_final (ospf);
305
306 /* *ospf is now invalid */
307
308 /* ospfd being shut-down? If so, was this the last ospf instance? */
309 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
310 && (listcount (om->ospf) == 0))
311 exit (0);
312
313 return;
314}
315
316/* Timer thread for G-R */
317static int
paulc9c93d52005-11-26 13:31:11 +0000318ospf_deferred_shutdown_timer (struct thread *t)
paul88d6cf32005-10-29 12:50:09 +0000319{
320 struct ospf *ospf = THREAD_ARG(t);
321
paulc9c93d52005-11-26 13:31:11 +0000322 ospf_deferred_shutdown_finish (ospf);
paul88d6cf32005-10-29 12:50:09 +0000323
324 return 0;
325}
326
paulc9c93d52005-11-26 13:31:11 +0000327/* Check whether deferred-shutdown must be scheduled, otherwise call
paul88d6cf32005-10-29 12:50:09 +0000328 * down directly into second-half of instance shutdown.
329 */
330static void
paulc9c93d52005-11-26 13:31:11 +0000331ospf_deferred_shutdown_check (struct ospf *ospf)
paul88d6cf32005-10-29 12:50:09 +0000332{
333 unsigned long timeout;
334 struct listnode *ln;
335 struct ospf_area *area;
336
paulc9c93d52005-11-26 13:31:11 +0000337 /* deferred shutdown already running? */
338 if (ospf->t_deferred_shutdown)
paul88d6cf32005-10-29 12:50:09 +0000339 return;
340
341 /* Should we try push out max-metric LSAs? */
342 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
343 {
344 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
345 {
346 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
347
348 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
Paul Jakmac363d382010-01-24 22:42:13 +0000349 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000350 }
351 timeout = ospf->stub_router_shutdown_time;
352 }
353 else
paulc9c93d52005-11-26 13:31:11 +0000354 {
355 /* No timer needed */
356 ospf_deferred_shutdown_finish (ospf);
357 return;
358 }
paul88d6cf32005-10-29 12:50:09 +0000359
paulc9c93d52005-11-26 13:31:11 +0000360 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
paul88d6cf32005-10-29 12:50:09 +0000361 timeout);
362 return;
363}
David Lamparter6b0655a2014-06-04 06:53:35 +0200364
paul88d6cf32005-10-29 12:50:09 +0000365/* Shut down the entire process */
366void
367ospf_terminate (void)
368{
369 struct ospf *ospf;
370 struct listnode *node, *nnode;
371
372 /* shutdown already in progress */
373 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
374 return;
375
376 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
377
Andrew J. Schorr4056a542007-02-27 13:55:46 +0000378 /* exit immediately if OSPF not actually running */
379 if (listcount(om->ospf) == 0)
380 exit(0);
381
paul88d6cf32005-10-29 12:50:09 +0000382 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
383 ospf_finish (ospf);
384
385 /* Deliberately go back up, hopefully to thread scheduler, as
386 * One or more ospf_finish()'s may have deferred shutdown to a timer
387 * thread
388 */
389}
paul718e3742002-12-13 20:15:29 +0000390
391void
392ospf_finish (struct ospf *ospf)
393{
paulc9c93d52005-11-26 13:31:11 +0000394 /* let deferred shutdown decide */
395 ospf_deferred_shutdown_check (ospf);
paul88d6cf32005-10-29 12:50:09 +0000396
paulc9c93d52005-11-26 13:31:11 +0000397 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
paul88d6cf32005-10-29 12:50:09 +0000398 * deferred to expiry of G-S timer thread. Return back up, hopefully
399 * to thread scheduler.
400 */
paulc9c93d52005-11-26 13:31:11 +0000401 return;
paul88d6cf32005-10-29 12:50:09 +0000402}
403
404/* Final cleanup of ospf instance */
405static void
406ospf_finish_final (struct ospf *ospf)
407{
paul718e3742002-12-13 20:15:29 +0000408 struct route_node *rn;
409 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000410 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +0000411 struct ospf_interface *oi;
412 struct ospf_area *area;
413 struct ospf_vl_data *vl_data;
414 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000415 int i;
416
417#ifdef HAVE_OPAQUE_LSA
418 ospf_opaque_type11_lsa_term (ospf);
419#endif /* HAVE_OPAQUE_LSA */
paul88d6cf32005-10-29 12:50:09 +0000420
421 /* be nice if this worked, but it doesn't */
422 /*ospf_flush_self_originated_lsas_now (ospf);*/
423
424 /* Unregister redistribution */
paul718e3742002-12-13 20:15:29 +0000425 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000426 ospf_redistribute_unset (ospf, i);
Paul Jakma29b5a042006-08-27 08:01:20 +0000427 ospf_redistribute_default_unset (ospf);
paul718e3742002-12-13 20:15:29 +0000428
paul1eb8ef22005-04-07 07:30:20 +0000429 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
430 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000431
paul1eb8ef22005-04-07 07:30:20 +0000432 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
433 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000434
435 list_delete (ospf->vlinks);
436
437 /* Reset interface. */
paul1eb8ef22005-04-07 07:30:20 +0000438 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
439 ospf_if_free (oi);
paul718e3742002-12-13 20:15:29 +0000440
441 /* Clear static neighbors */
442 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
443 if ((nbr_nbma = rn->info))
444 {
445 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
446
447 if (nbr_nbma->nbr)
448 {
449 nbr_nbma->nbr->nbr_nbma = NULL;
450 nbr_nbma->nbr = NULL;
451 }
452
453 if (nbr_nbma->oi)
454 {
455 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
456 nbr_nbma->oi = NULL;
457 }
458
459 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
460 }
461
462 route_table_finish (ospf->nbr_nbma);
463
464 /* Clear networks and Areas. */
465 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
466 {
467 struct ospf_network *network;
468
469 if ((network = rn->info) != NULL)
470 {
paul68980082003-03-25 05:07:42 +0000471 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000472 rn->info = NULL;
473 route_unlock_node (rn);
474 }
475 }
476
paul1eb8ef22005-04-07 07:30:20 +0000477 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000478 {
paul718e3742002-12-13 20:15:29 +0000479 listnode_delete (ospf->areas, area);
480 ospf_area_free (area);
481 }
482
483 /* Cancel all timers. */
484 OSPF_TIMER_OFF (ospf->t_external_lsa);
paul718e3742002-12-13 20:15:29 +0000485 OSPF_TIMER_OFF (ospf->t_spf_calc);
486 OSPF_TIMER_OFF (ospf->t_ase_calc);
487 OSPF_TIMER_OFF (ospf->t_maxage);
488 OSPF_TIMER_OFF (ospf->t_maxage_walker);
489 OSPF_TIMER_OFF (ospf->t_abr_task);
paul88d6cf32005-10-29 12:50:09 +0000490 OSPF_TIMER_OFF (ospf->t_asbr_check);
paul718e3742002-12-13 20:15:29 +0000491 OSPF_TIMER_OFF (ospf->t_distribute_update);
492 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
493 OSPF_TIMER_OFF (ospf->t_read);
494 OSPF_TIMER_OFF (ospf->t_write);
paul31a59762005-11-14 11:11:11 +0000495#ifdef HAVE_OPAQUE_LSA
paul88d6cf32005-10-29 12:50:09 +0000496 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
paul31a59762005-11-14 11:11:11 +0000497#endif
paul718e3742002-12-13 20:15:29 +0000498
499 close (ospf->fd);
ajs5c333492005-02-23 15:43:01 +0000500 stream_free(ospf->ibuf);
paul718e3742002-12-13 20:15:29 +0000501
502#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000503 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
504 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000505#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000506 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
507 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
508
paul718e3742002-12-13 20:15:29 +0000509 ospf_lsdb_delete_all (ospf->lsdb);
510 ospf_lsdb_free (ospf->lsdb);
511
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800512 for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
513 {
514 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000515
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -0800516 if ((lsa = rn->info) != NULL)
517 {
518 ospf_lsa_unlock (&lsa);
519 rn->info = NULL;
520 }
521 route_unlock_node (rn);
522 }
523 route_table_finish (ospf->maxage_lsa);
paul718e3742002-12-13 20:15:29 +0000524
525 if (ospf->old_table)
526 ospf_route_table_free (ospf->old_table);
527 if (ospf->new_table)
528 {
529 ospf_route_delete (ospf->new_table);
530 ospf_route_table_free (ospf->new_table);
531 }
532 if (ospf->old_rtrs)
533 ospf_rtrs_free (ospf->old_rtrs);
534 if (ospf->new_rtrs)
535 ospf_rtrs_free (ospf->new_rtrs);
536 if (ospf->new_external_route)
537 {
538 ospf_route_delete (ospf->new_external_route);
539 ospf_route_table_free (ospf->new_external_route);
540 }
541 if (ospf->old_external_route)
542 {
543 ospf_route_delete (ospf->old_external_route);
544 ospf_route_table_free (ospf->old_external_route);
545 }
546 if (ospf->external_lsas)
547 {
548 ospf_ase_external_lsas_finish (ospf->external_lsas);
549 }
550
551 list_delete (ospf->areas);
552
553 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
554 if (EXTERNAL_INFO (i) != NULL)
555 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
556 {
557 if (rn->info == NULL)
558 continue;
559
560 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
561 rn->info = NULL;
562 route_unlock_node (rn);
563 }
564
paul68980082003-03-25 05:07:42 +0000565 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000566 route_table_finish (ospf->distance_table);
567
paul020709f2003-04-04 02:44:16 +0000568 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000569
paul020709f2003-04-04 02:44:16 +0000570 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000571}
572
David Lamparter6b0655a2014-06-04 06:53:35 +0200573
paul718e3742002-12-13 20:15:29 +0000574/* allocate new OSPF Area object */
paul4dadc292005-05-06 21:37:42 +0000575static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000576ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000577{
578 struct ospf_area *new;
579
580 /* Allocate new config_network. */
581 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
582
paul68980082003-03-25 05:07:42 +0000583 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000584
585 new->area_id = area_id;
586
587 new->external_routing = OSPF_AREA_DEFAULT;
588 new->default_cost = 1;
589 new->auth_type = OSPF_AUTH_NULL;
paul88d6cf32005-10-29 12:50:09 +0000590
paul718e3742002-12-13 20:15:29 +0000591 /* New LSDB init. */
592 new->lsdb = ospf_lsdb_new ();
593
594 /* Self-originated LSAs initialize. */
595 new->router_lsa_self = NULL;
596
597#ifdef HAVE_OPAQUE_LSA
598 ospf_opaque_type10_lsa_init (new);
599#endif /* HAVE_OPAQUE_LSA */
600
601 new->oiflist = list_new ();
602 new->ranges = route_table_init ();
603
604 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000605 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000606
607 return new;
608}
609
Stephen Hemminger917e2992009-12-03 19:07:00 +0300610static void
paul718e3742002-12-13 20:15:29 +0000611ospf_area_free (struct ospf_area *area)
612{
paul68980082003-03-25 05:07:42 +0000613 struct route_node *rn;
614 struct ospf_lsa *lsa;
615
paul718e3742002-12-13 20:15:29 +0000616 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000617 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
618 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
619 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
620 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
621 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
622 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
623 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
624 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000625
paul68980082003-03-25 05:07:42 +0000626 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
627 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000628#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000629 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
630 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
631 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
632 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000633#endif /* HAVE_OPAQUE_LSA */
634
635 ospf_lsdb_delete_all (area->lsdb);
636 ospf_lsdb_free (area->lsdb);
637
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000638 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000639
640 route_table_finish (area->ranges);
641 list_delete (area->oiflist);
642
643 if (EXPORT_NAME (area))
644 free (EXPORT_NAME (area));
645
646 if (IMPORT_NAME (area))
647 free (IMPORT_NAME (area));
648
649 /* Cancel timer. */
paul88d6cf32005-10-29 12:50:09 +0000650 OSPF_TIMER_OFF (area->t_stub_router);
651#ifdef HAVE_OPAQUE_LSA
652 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
653#endif /* HAVE_OPAQUE_LSA */
654
paul718e3742002-12-13 20:15:29 +0000655 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000656 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000657
658 XFREE (MTYPE_OSPF_AREA, area);
659}
660
661void
paul68980082003-03-25 05:07:42 +0000662ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000663{
664 struct ospf_area *area;
665
paul68980082003-03-25 05:07:42 +0000666 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000667 if (area &&
668 listcount (area->oiflist) == 0 &&
669 area->ranges->top == NULL &&
670 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
671 area->external_routing == OSPF_AREA_DEFAULT &&
672 area->no_summary == 0 &&
673 area->default_cost == 1 &&
674 EXPORT_NAME (area) == NULL &&
675 IMPORT_NAME (area) == NULL &&
676 area->auth_type == OSPF_AUTH_NULL)
677 {
paul68980082003-03-25 05:07:42 +0000678 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000679 ospf_area_free (area);
680 }
681}
682
683struct ospf_area *
paul68980082003-03-25 05:07:42 +0000684ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000685{
686 struct ospf_area *area;
687
paul68980082003-03-25 05:07:42 +0000688 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000689 if (!area)
690 {
paul68980082003-03-25 05:07:42 +0000691 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000692 area->format = format;
paul68980082003-03-25 05:07:42 +0000693 listnode_add_sort (ospf->areas, area);
694 ospf_check_abr_status (ospf);
Ayan Banerjee4ba4fc82012-12-03 11:17:24 -0800695 if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
696 {
697 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
698 }
paul718e3742002-12-13 20:15:29 +0000699 }
700
701 return area;
702}
703
704struct ospf_area *
paul68980082003-03-25 05:07:42 +0000705ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000706{
707 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000708 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000709
paul1eb8ef22005-04-07 07:30:20 +0000710 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
711 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
712 return area;
paul718e3742002-12-13 20:15:29 +0000713
714 return NULL;
715}
716
717void
718ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
719{
720 listnode_add (area->oiflist, oi);
721}
722
723void
724ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
725{
726 listnode_delete (area->oiflist, oi);
727}
728
David Lamparter6b0655a2014-06-04 06:53:35 +0200729
paul718e3742002-12-13 20:15:29 +0000730/* Config network statement related functions. */
paul4dadc292005-05-06 21:37:42 +0000731static struct ospf_network *
paul718e3742002-12-13 20:15:29 +0000732ospf_network_new (struct in_addr area_id, int format)
733{
734 struct ospf_network *new;
735 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
736
737 new->area_id = area_id;
738 new->format = format;
739
740 return new;
741}
742
Stephen Hemminger917e2992009-12-03 19:07:00 +0300743static void
paul68980082003-03-25 05:07:42 +0000744ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000745{
paul68980082003-03-25 05:07:42 +0000746 ospf_area_check_free (ospf, network->area_id);
747 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000748 XFREE (MTYPE_OSPF_NETWORK, network);
749}
750
751int
752ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
753 struct in_addr area_id)
754{
755 struct ospf_network *network;
756 struct ospf_area *area;
757 struct route_node *rn;
758 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000759 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000760
761 rn = route_node_get (ospf->networks, (struct prefix *)p);
762 if (rn->info)
763 {
764 /* There is already same network statement. */
765 route_unlock_node (rn);
766 return 0;
767 }
768
769 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000770 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000771
772 /* Run network config now. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100773 ospf_network_run ((struct prefix *)p, area);
paul718e3742002-12-13 20:15:29 +0000774
775 /* Update connected redistribute. */
776 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
777 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
778 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
779 rn; rn = route_next (rn))
780 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000781 if (ospf_external_info_find_lsa (ospf, &ei->p))
782 if (!ospf_distribute_check_connected (ospf, ei))
783 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +0000784 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +0000785
paul68980082003-03-25 05:07:42 +0000786 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000787
788 return 1;
789}
790
791int
792ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
793 struct in_addr area_id)
794{
795 struct route_node *rn;
796 struct ospf_network *network;
797 struct external_info *ei;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100798 struct listnode *node, *nnode;
799 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000800
801 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
802 if (rn == NULL)
803 return 0;
804
805 network = rn->info;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700806 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000807 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
808 return 0;
809
paul68980082003-03-25 05:07:42 +0000810 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000811 rn->info = NULL;
Stephen Hemminger965f54f2009-06-03 16:44:21 -0700812 route_unlock_node (rn); /* initial reference */
paul718e3742002-12-13 20:15:29 +0000813
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100814 /* Find interfaces that not configured already. */
815 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
816 {
817 int found = 0;
818 struct connected *co = oi->connected;
819
820 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
821 continue;
822
823 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
824 {
825 if (rn->info == NULL)
826 continue;
827
828 if (ospf_network_match_iface(co,&rn->p))
829 {
830 found = 1;
831 route_unlock_node (rn);
832 break;
833 }
834 }
835
836 if (found == 0)
Joakim Tjernlund6b274d92010-03-09 06:42:30 +0000837 {
838 ospf_if_free (oi);
839 ospf_area_check_free (ospf, area_id);
840 }
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100841 }
paul718e3742002-12-13 20:15:29 +0000842
843 /* Update connected redistribute. */
844 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
845 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
846 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
847 rn; rn = route_next (rn))
848 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000849 if (!ospf_external_info_find_lsa (ospf, &ei->p))
850 if (ospf_distribute_check_connected (ospf, ei))
851 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000852
853 return 1;
854}
855
paul570f7592003-01-25 06:47:41 +0000856/* Check whether interface matches given network
857 * returns: 1, true. 0, false
858 */
Stephen Hemminger917e2992009-12-03 19:07:00 +0300859static int
860ospf_network_match_iface(const struct connected *co, const struct prefix *net)
paul570f7592003-01-25 06:47:41 +0000861{
Andrew J. Schorre4529632006-12-12 19:18:21 +0000862 /* new approach: more elegant and conceptually clean */
863 return prefix_match(net, CONNECTED_PREFIX(co));
paul570f7592003-01-25 06:47:41 +0000864}
865
Stephen Hemminger917e2992009-12-03 19:07:00 +0300866static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100867ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
868 struct interface *ifp)
869{
870 struct listnode *cnode;
871 struct connected *co;
872
873 if (memcmp (ifp->name, "VLINK", 5) == 0)
874 return;
875
876 /* if interface prefix is match specified prefix,
877 then create socket and join multicast group. */
878 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
879 {
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200880
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100881 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
882 continue;
883
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100884 if (p->family == co->address->family
Joakim Tjernlundf0f63842009-07-27 12:42:29 +0200885 && ! ospf_if_table_lookup(ifp, co->address)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100886 && ospf_network_match_iface(co,p))
887 {
888 struct ospf_interface *oi;
889
890 oi = ospf_if_new (area->ospf, ifp, co->address);
891 oi->connected = co;
892
893 oi->area = area;
894
895 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
896 oi->output_cost = ospf_if_get_output_cost (oi);
897
898 /* Add pseudo neighbor. */
899 ospf_nbr_add_self (oi);
900
901 /* Relate ospf interface to ospf instance. */
902 oi->ospf = area->ospf;
903
904 /* update network type as interface flag */
905 /* If network type is specified previously,
906 skip network type setting. */
907 oi->type = IF_DEF_PARAMS (ifp)->type;
908
909 ospf_area_add_if (oi->area, oi);
910
911 /* if router_id is not configured, dont bring up
912 * interfaces.
913 * ospf_router_id_update() will call ospf_if_update
914 * whenever r-id is configured instead.
915 */
916 if ((area->ospf->router_id.s_addr != 0)
917 && if_is_operative (ifp))
918 ospf_if_up (oi);
919 }
920 }
921}
922
Stephen Hemminger917e2992009-12-03 19:07:00 +0300923static void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100924ospf_network_run (struct prefix *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000925{
926 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000927 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000928
929 /* Schedule Router ID Update. */
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100930 if (area->ospf->router_id.s_addr == 0)
931 ospf_router_id_update (area->ospf);
paulb29800a2005-11-20 14:50:45 +0000932
paul718e3742002-12-13 20:15:29 +0000933 /* Get target interface. */
paul1eb8ef22005-04-07 07:30:20 +0000934 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100935 ospf_network_run_interface (p, area, ifp);
paul718e3742002-12-13 20:15:29 +0000936}
937
938void
939ospf_ls_upd_queue_empty (struct ospf_interface *oi)
940{
941 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +0000942 struct listnode *node, *nnode;
hasso52dc7ee2004-09-23 19:18:23 +0000943 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000944 struct ospf_lsa *lsa;
945
946 /* empty ls update queue */
947 for (rn = route_top (oi->ls_upd_queue); rn;
948 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000949 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000950 {
paul1eb8ef22005-04-07 07:30:20 +0000951 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000952 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +0000953 list_free (lst);
954 rn->info = NULL;
955 }
956
957 /* remove update event */
958 if (oi->t_ls_upd_event)
959 {
960 thread_cancel (oi->t_ls_upd_event);
961 oi->t_ls_upd_event = NULL;
962 }
963}
964
965void
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100966ospf_if_update (struct ospf *ospf, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000967{
968 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000969 struct ospf_network *network;
970 struct ospf_area *area;
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100971
972 if (!ospf)
973 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +0000974
Joakim Tjernlund6e687d72008-09-24 17:15:48 +0100975 /* OSPF must be on and Router-ID must be configured. */
976 if (!ospf || ospf->router_id.s_addr == 0)
Joakim Tjernlunda49eb302008-09-02 19:06:31 +0100977 return;
978
979 /* Run each netowrk for this interface. */
980 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
981 if (rn->info != NULL)
982 {
983 network = (struct ospf_network *) rn->info;
984 area = ospf_area_get (ospf, network->area_id, network->format);
985 ospf_network_run_interface (&rn->p, area, ifp);
986 }
paul718e3742002-12-13 20:15:29 +0000987}
988
989void
paul68980082003-03-25 05:07:42 +0000990ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000991{
paul1eb8ef22005-04-07 07:30:20 +0000992 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000993 struct ospf_vl_data *vl_data;
994
paul1eb8ef22005-04-07 07:30:20 +0000995 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
996 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
997 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000998}
999
David Lamparter6b0655a2014-06-04 06:53:35 +02001000
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001001static const struct message ospf_area_type_msg[] =
paul718e3742002-12-13 20:15:29 +00001002{
1003 { OSPF_AREA_DEFAULT, "Default" },
1004 { OSPF_AREA_STUB, "Stub" },
1005 { OSPF_AREA_NSSA, "NSSA" },
1006};
Stephen Hemminger7ba82f72009-05-15 10:47:45 -07001007static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
paul718e3742002-12-13 20:15:29 +00001008
paul4dadc292005-05-06 21:37:42 +00001009static void
paul718e3742002-12-13 20:15:29 +00001010ospf_area_type_set (struct ospf_area *area, int type)
1011{
hasso52dc7ee2004-09-23 19:18:23 +00001012 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001013 struct ospf_interface *oi;
1014
1015 if (area->external_routing == type)
1016 {
1017 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001018 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +00001019 inet_ntoa (area->area_id));
1020 return;
1021 }
1022
1023 area->external_routing = type;
1024
1025 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +00001026 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +00001027 LOOKUP (ospf_area_type_msg, type));
1028
1029 switch (area->external_routing)
1030 {
1031 case OSPF_AREA_DEFAULT:
paul1eb8ef22005-04-07 07:30:20 +00001032 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1033 if (oi->nbr_self != NULL)
1034 {
1035 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1036 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1037 }
paul718e3742002-12-13 20:15:29 +00001038 break;
1039 case OSPF_AREA_STUB:
paul1eb8ef22005-04-07 07:30:20 +00001040 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1041 if (oi->nbr_self != NULL)
1042 {
1043 if (IS_DEBUG_OSPF_EVENT)
1044 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1045 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1046 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1047 if (IS_DEBUG_OSPF_EVENT)
1048 zlog_debug ("options set on %s: %x",
1049 IF_NAME (oi), OPTIONS (oi));
1050 }
paul718e3742002-12-13 20:15:29 +00001051 break;
1052 case OSPF_AREA_NSSA:
paul1eb8ef22005-04-07 07:30:20 +00001053 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1054 if (oi->nbr_self != NULL)
1055 {
1056 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1057 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1058 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1059 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1060 }
paul718e3742002-12-13 20:15:29 +00001061 break;
1062 default:
1063 break;
1064 }
1065
Paul Jakmac363d382010-01-24 22:42:13 +00001066 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001067 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001068}
1069
1070int
paul68980082003-03-25 05:07:42 +00001071ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001072{
1073 if (area->shortcut_configured == mode)
1074 return 0;
1075
1076 area->shortcut_configured = mode;
Paul Jakmac363d382010-01-24 22:42:13 +00001077 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001078 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001079
paul68980082003-03-25 05:07:42 +00001080 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001081
1082 return 1;
1083}
1084
1085int
paul68980082003-03-25 05:07:42 +00001086ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001087{
1088 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
Paul Jakmac363d382010-01-24 22:42:13 +00001089 ospf_router_lsa_update_area (area);
paul68980082003-03-25 05:07:42 +00001090 ospf_area_check_free (ospf, area->area_id);
1091 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001092
1093 return 1;
1094}
1095
paul4dadc292005-05-06 21:37:42 +00001096static int
paul718e3742002-12-13 20:15:29 +00001097ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1098{
1099 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001100 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001101 int count = 0;
1102
paul1eb8ef22005-04-07 07:30:20 +00001103 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1104 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1105 count++;
paul718e3742002-12-13 20:15:29 +00001106
1107 return count;
1108}
1109
1110int
1111ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1112{
1113 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001114 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001115
paul68980082003-03-25 05:07:42 +00001116 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001117 if (ospf_area_vlink_count (ospf, area))
1118 return 0;
1119
1120 if (area->external_routing != OSPF_AREA_STUB)
1121 ospf_area_type_set (area, OSPF_AREA_STUB);
1122
1123 return 1;
1124}
1125
1126int
1127ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1128{
1129 struct ospf_area *area;
1130
paul68980082003-03-25 05:07:42 +00001131 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001132 if (area == NULL)
1133 return 1;
1134
1135 if (area->external_routing == OSPF_AREA_STUB)
1136 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1137
paul68980082003-03-25 05:07:42 +00001138 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001139
1140 return 1;
1141}
1142
1143int
1144ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1145{
1146 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001147 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001148
paul68980082003-03-25 05:07:42 +00001149 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001150 area->no_summary = 1;
1151
1152 return 1;
1153}
1154
1155int
1156ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1157{
1158 struct ospf_area *area;
1159
paul68980082003-03-25 05:07:42 +00001160 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001161 if (area == NULL)
1162 return 0;
1163
1164 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001165 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001166
1167 return 1;
1168}
1169
1170int
1171ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1172{
1173 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001174 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001175
paul68980082003-03-25 05:07:42 +00001176 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001177 if (ospf_area_vlink_count (ospf, area))
1178 return 0;
1179
1180 if (area->external_routing != OSPF_AREA_NSSA)
1181 {
1182 ospf_area_type_set (area, OSPF_AREA_NSSA);
1183 ospf->anyNSSA++;
1184 }
1185
paul084c7842003-06-22 08:35:18 +00001186 /* set NSSA area defaults */
1187 area->no_summary = 0;
1188 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001189 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001190 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1191
paul718e3742002-12-13 20:15:29 +00001192 return 1;
1193}
1194
1195int
1196ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1197{
1198 struct ospf_area *area;
1199
paul68980082003-03-25 05:07:42 +00001200 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001201 if (area == NULL)
1202 return 0;
1203
1204 if (area->external_routing == OSPF_AREA_NSSA)
1205 {
1206 ospf->anyNSSA--;
1207 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1208 }
1209
paul68980082003-03-25 05:07:42 +00001210 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001211
1212 return 1;
1213}
1214
1215int
1216ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1217 int role)
1218{
1219 struct ospf_area *area;
1220
paul68980082003-03-25 05:07:42 +00001221 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001222 if (area == NULL)
1223 return 0;
1224
paul084c7842003-06-22 08:35:18 +00001225 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001226
1227 return 1;
1228}
1229
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001230#if 0
paul4dadc292005-05-06 21:37:42 +00001231/* XXX: unused? Leave for symmetry? */
1232static int
paul718e3742002-12-13 20:15:29 +00001233ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1234 struct in_addr area_id)
1235{
1236 struct ospf_area *area;
1237
paul68980082003-03-25 05:07:42 +00001238 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001239 if (area == NULL)
1240 return 0;
1241
paul084c7842003-06-22 08:35:18 +00001242 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001243
paul68980082003-03-25 05:07:42 +00001244 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001245
1246 return 1;
1247}
Stephen Hemminger075e12f2011-12-06 23:54:17 +04001248#endif
paul718e3742002-12-13 20:15:29 +00001249
1250int
paul68980082003-03-25 05:07:42 +00001251ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001252 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001253{
1254 struct access_list *list;
1255 list = access_list_lookup (AFI_IP, list_name);
1256
1257 EXPORT_LIST (area) = list;
1258
1259 if (EXPORT_NAME (area))
1260 free (EXPORT_NAME (area));
1261
1262 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001263 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001264
1265 return 1;
1266}
1267
1268int
paul68980082003-03-25 05:07:42 +00001269ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001270{
1271
1272 EXPORT_LIST (area) = 0;
1273
1274 if (EXPORT_NAME (area))
1275 free (EXPORT_NAME (area));
1276
1277 EXPORT_NAME (area) = NULL;
1278
paul68980082003-03-25 05:07:42 +00001279 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001280
paul68980082003-03-25 05:07:42 +00001281 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001282
1283 return 1;
1284}
1285
1286int
paul6c835672004-10-11 11:00:30 +00001287ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1288 const char *name)
paul718e3742002-12-13 20:15:29 +00001289{
1290 struct access_list *list;
1291 list = access_list_lookup (AFI_IP, name);
1292
1293 IMPORT_LIST (area) = list;
1294
1295 if (IMPORT_NAME (area))
1296 free (IMPORT_NAME (area));
1297
1298 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001299 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001300
1301 return 1;
1302}
1303
1304int
paul68980082003-03-25 05:07:42 +00001305ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001306{
1307 IMPORT_LIST (area) = 0;
1308
1309 if (IMPORT_NAME (area))
1310 free (IMPORT_NAME (area));
1311
1312 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001313 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001314
paul68980082003-03-25 05:07:42 +00001315 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001316
1317 return 1;
1318}
1319
1320int
paul718e3742002-12-13 20:15:29 +00001321ospf_timers_refresh_set (struct ospf *ospf, int interval)
1322{
1323 int time_left;
1324
1325 if (ospf->lsa_refresh_interval == interval)
1326 return 1;
1327
1328 time_left = ospf->lsa_refresh_interval -
Paul Jakma2518efd2006-08-27 06:49:29 +00001329 (quagga_time (NULL) - ospf->lsa_refresher_started);
paul718e3742002-12-13 20:15:29 +00001330
1331 if (time_left > interval)
1332 {
1333 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1334 ospf->t_lsa_refresher =
1335 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1336 }
1337 ospf->lsa_refresh_interval = interval;
1338
1339 return 1;
1340}
1341
1342int
1343ospf_timers_refresh_unset (struct ospf *ospf)
1344{
1345 int time_left;
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 > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1351 {
1352 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1353 ospf->t_lsa_refresher =
1354 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1355 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1356 }
1357
1358 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1359
1360 return 1;
1361}
1362
David Lamparter6b0655a2014-06-04 06:53:35 +02001363
paul4dadc292005-05-06 21:37:42 +00001364static struct ospf_nbr_nbma *
1365ospf_nbr_nbma_new (void)
paul718e3742002-12-13 20:15:29 +00001366{
1367 struct ospf_nbr_nbma *nbr_nbma;
1368
Stephen Hemminger393deb92008-08-18 14:13:29 -07001369 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
paul718e3742002-12-13 20:15:29 +00001370 sizeof (struct ospf_nbr_nbma));
paul718e3742002-12-13 20:15:29 +00001371
1372 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1373 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1374
1375 return nbr_nbma;
1376}
1377
paul4dadc292005-05-06 21:37:42 +00001378static void
paul718e3742002-12-13 20:15:29 +00001379ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1380{
1381 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1382}
1383
paul4dadc292005-05-06 21:37:42 +00001384static void
paul718e3742002-12-13 20:15:29 +00001385ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1386{
1387 struct route_node *rn;
1388 struct prefix_ipv4 p;
1389
1390 p.family = AF_INET;
1391 p.prefix = nbr_nbma->addr;
1392 p.prefixlen = IPV4_MAX_BITLEN;
1393
1394 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1395 if (rn)
1396 {
1397 ospf_nbr_nbma_free (rn->info);
1398 rn->info = NULL;
1399 route_unlock_node (rn);
1400 route_unlock_node (rn);
1401 }
1402}
1403
paul4dadc292005-05-06 21:37:42 +00001404static void
paul718e3742002-12-13 20:15:29 +00001405ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1406{
1407 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1408
1409 if (nbr_nbma->nbr)
1410 {
1411 nbr_nbma->nbr->nbr_nbma = NULL;
1412 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1413 }
1414
1415 if (nbr_nbma->oi)
1416 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1417}
1418
paul4dadc292005-05-06 21:37:42 +00001419static void
paul718e3742002-12-13 20:15:29 +00001420ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1421 struct ospf_interface *oi)
1422{
1423 struct ospf_neighbor *nbr;
1424 struct route_node *rn;
1425 struct prefix p;
1426
1427 if (oi->type != OSPF_IFTYPE_NBMA)
1428 return;
1429
1430 if (nbr_nbma->nbr != NULL)
1431 return;
1432
1433 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1434 return;
1435
1436 nbr_nbma->oi = oi;
1437 listnode_add (oi->nbr_nbma, nbr_nbma);
1438
1439 /* Get neighbor information from table. */
1440 p.family = AF_INET;
1441 p.prefixlen = IPV4_MAX_BITLEN;
1442 p.u.prefix4 = nbr_nbma->addr;
1443
1444 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1445 if (rn->info)
1446 {
1447 nbr = rn->info;
1448 nbr->nbr_nbma = nbr_nbma;
1449 nbr_nbma->nbr = nbr;
1450
1451 route_unlock_node (rn);
1452 }
1453 else
1454 {
1455 nbr = rn->info = ospf_nbr_new (oi);
1456 nbr->state = NSM_Down;
1457 nbr->src = nbr_nbma->addr;
1458 nbr->nbr_nbma = nbr_nbma;
1459 nbr->priority = nbr_nbma->priority;
1460 nbr->address = p;
1461
1462 nbr_nbma->nbr = nbr;
1463
1464 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1465 }
1466}
1467
1468void
paul68980082003-03-25 05:07:42 +00001469ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001470{
1471 struct ospf_nbr_nbma *nbr_nbma;
1472 struct route_node *rn;
1473 struct prefix_ipv4 p;
1474
1475 if (oi->type != OSPF_IFTYPE_NBMA)
1476 return;
1477
paul68980082003-03-25 05:07:42 +00001478 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001479 if ((nbr_nbma = rn->info))
1480 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1481 {
1482 p.family = AF_INET;
1483 p.prefix = nbr_nbma->addr;
1484 p.prefixlen = IPV4_MAX_BITLEN;
1485
1486 if (prefix_match (oi->address, (struct prefix *)&p))
1487 ospf_nbr_nbma_add (nbr_nbma, oi);
1488 }
1489}
1490
1491struct ospf_nbr_nbma *
1492ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1493{
1494 struct route_node *rn;
1495 struct prefix_ipv4 p;
1496
1497 p.family = AF_INET;
1498 p.prefix = nbr_addr;
1499 p.prefixlen = IPV4_MAX_BITLEN;
1500
1501 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1502 if (rn)
1503 {
1504 route_unlock_node (rn);
1505 return rn->info;
1506 }
1507 return NULL;
1508}
1509
1510struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001511ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001512{
1513#if 0
1514 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001515 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001516#endif
1517
paul68980082003-03-25 05:07:42 +00001518 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001519 return NULL;
1520
1521#if 0
paul1eb8ef22005-04-07 07:30:20 +00001522 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
paul718e3742002-12-13 20:15:29 +00001523 {
paul718e3742002-12-13 20:15:29 +00001524 if (first)
1525 {
1526 *addr = nbr_nbma->addr;
1527 return nbr_nbma;
1528 }
1529 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1530 {
1531 *addr = nbr_nbma->addr;
1532 return nbr_nbma;
1533 }
1534 }
1535#endif
1536 return NULL;
1537}
1538
1539int
1540ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1541{
1542 struct ospf_nbr_nbma *nbr_nbma;
1543 struct ospf_interface *oi;
1544 struct prefix_ipv4 p;
1545 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001546 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001547
1548 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1549 if (nbr_nbma)
1550 return 0;
1551
1552 nbr_nbma = ospf_nbr_nbma_new ();
1553 nbr_nbma->addr = nbr_addr;
1554
1555 p.family = AF_INET;
1556 p.prefix = nbr_addr;
1557 p.prefixlen = IPV4_MAX_BITLEN;
1558
1559 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
Joakim Tjernlund4de398e2010-03-08 13:58:14 +01001560 if (rn->info)
1561 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001562 rn->info = nbr_nbma;
1563
paul1eb8ef22005-04-07 07:30:20 +00001564 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001565 {
paul718e3742002-12-13 20:15:29 +00001566 if (oi->type == OSPF_IFTYPE_NBMA)
1567 if (prefix_match (oi->address, (struct prefix *)&p))
1568 {
1569 ospf_nbr_nbma_add (nbr_nbma, oi);
1570 break;
1571 }
1572 }
1573
1574 return 1;
1575}
1576
1577int
1578ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1579{
1580 struct ospf_nbr_nbma *nbr_nbma;
1581
1582 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1583 if (nbr_nbma == NULL)
1584 return 0;
1585
1586 ospf_nbr_nbma_down (nbr_nbma);
1587 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1588
1589 return 1;
1590}
1591
1592int
1593ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1594 u_char priority)
1595{
1596 struct ospf_nbr_nbma *nbr_nbma;
1597
1598 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1599 if (nbr_nbma == NULL)
1600 return 0;
1601
1602 if (nbr_nbma->priority != priority)
1603 nbr_nbma->priority = priority;
1604
1605 return 1;
1606}
1607
1608int
1609ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1610{
1611 struct ospf_nbr_nbma *nbr_nbma;
1612
1613 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1614 if (nbr_nbma == NULL)
1615 return 0;
1616
1617 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1618 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1619
1620 return 1;
1621}
1622
1623int
1624ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001625 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001626{
1627 struct ospf_nbr_nbma *nbr_nbma;
1628
1629 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1630 if (nbr_nbma == NULL)
1631 return 0;
1632
1633 if (nbr_nbma->v_poll != interval)
1634 {
1635 nbr_nbma->v_poll = interval;
1636 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1637 {
1638 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1639 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1640 nbr_nbma->v_poll);
1641 }
1642 }
1643
1644 return 1;
1645}
1646
1647int
1648ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1649{
1650 struct ospf_nbr_nbma *nbr_nbma;
1651
1652 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1653 if (nbr_nbma == NULL)
1654 return 0;
1655
1656 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1657 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1658
1659 return 1;
1660}
1661
paul718e3742002-12-13 20:15:29 +00001662void
paul020709f2003-04-04 02:44:16 +00001663ospf_master_init ()
1664{
1665 memset (&ospf_master, 0, sizeof (struct ospf_master));
1666
1667 om = &ospf_master;
1668 om->ospf = list_new ();
1669 om->master = thread_master_create ();
Paul Jakma2518efd2006-08-27 06:49:29 +00001670 om->start_time = quagga_time (NULL);
paul020709f2003-04-04 02:44:16 +00001671}