blob: 931ae49c59bae85ae65919b2dd9f9b92dfdf72ee [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"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_zebra.h"
50#include "ospfd/ospf_abr.h"
51#include "ospfd/ospf_flood.h"
52#include "ospfd/ospf_route.h"
53#include "ospfd/ospf_ase.h"
54
paul020709f2003-04-04 02:44:16 +000055
pauledd7c242003-06-04 13:59:38 +000056
paul020709f2003-04-04 02:44:16 +000057/* OSPF process wide configuration. */
58static struct ospf_master ospf_master;
59
60/* OSPF process wide configuration pointer to export. */
61struct ospf_master *om;
paul718e3742002-12-13 20:15:29 +000062
63extern struct zclient *zclient;
hasso18a6dce2004-10-03 18:18:34 +000064extern struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000065
66
paul68980082003-03-25 05:07:42 +000067void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
68void ospf_network_free (struct ospf *, struct ospf_network *);
paul718e3742002-12-13 20:15:29 +000069void ospf_area_free (struct ospf_area *);
70void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
71
paul718e3742002-12-13 20:15:29 +000072#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
73
74void
paul68980082003-03-25 05:07:42 +000075ospf_router_id_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +000076{
paul718e3742002-12-13 20:15:29 +000077 struct in_addr router_id, router_id_old;
hasso52dc7ee2004-09-23 19:18:23 +000078 struct listnode *node;
paul718e3742002-12-13 20:15:29 +000079
80 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +000081 zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +000082
paul68980082003-03-25 05:07:42 +000083 router_id_old = ospf->router_id;
paul718e3742002-12-13 20:15:29 +000084
paul68980082003-03-25 05:07:42 +000085 if (ospf->router_id_static.s_addr != 0)
86 router_id = ospf->router_id_static;
paul718e3742002-12-13 20:15:29 +000087 else
hasso18a6dce2004-10-03 18:18:34 +000088 router_id = router_id_zebra;
paul718e3742002-12-13 20:15:29 +000089
paul68980082003-03-25 05:07:42 +000090 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +000091
92 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +000093 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +000094
95 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
96 {
paul68980082003-03-25 05:07:42 +000097 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +000098 {
99 struct ospf_interface *oi = getdata (node);
100
101 /* Update self-neighbor's router_id. */
102 oi->nbr_self->router_id = router_id;
103 }
104
105 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000106 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000107 {
108 int type;
109 /* Originate each redistributed external route. */
110 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000111 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000112 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000113 ospf, type);
paul718e3742002-12-13 20:15:29 +0000114 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000115 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
paul718e3742002-12-13 20:15:29 +0000116 thread_add_event (master, ospf_default_originate_timer,
paul68980082003-03-25 05:07:42 +0000117 &ospf->default_originate, 0);
paul718e3742002-12-13 20:15:29 +0000118
paul68980082003-03-25 05:07:42 +0000119 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000120 }
121
paul68980082003-03-25 05:07:42 +0000122 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000123 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
124 }
125}
126
127int
128ospf_router_id_update_timer (struct thread *thread)
129{
paul020709f2003-04-04 02:44:16 +0000130 struct ospf *ospf = THREAD_ARG (thread);
paul68980082003-03-25 05:07:42 +0000131
paul718e3742002-12-13 20:15:29 +0000132 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000133 zlog_debug ("Router-ID: Update timer fired!");
paul718e3742002-12-13 20:15:29 +0000134
paul68980082003-03-25 05:07:42 +0000135 ospf->t_router_id_update = NULL;
136 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000137
138 return 0;
139}
140
141/* For OSPF area sort by area id. */
142int
143ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
144{
145 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
146 return 1;
147 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
148 return -1;
149 return 0;
150}
151
152/* Allocate new ospf structure. */
153struct ospf *
154ospf_new ()
155{
156 int i;
157
158 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
159
160 new->router_id.s_addr = htonl (0);
161 new->router_id_static.s_addr = htonl (0);
162
163 new->abr_type = OSPF_ABR_STAND;
paul718e3742002-12-13 20:15:29 +0000164 new->oiflist = list_new ();
165 new->vlinks = list_new ();
166 new->areas = list_new ();
167 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
168 new->networks = route_table_init ();
169 new->nbr_nbma = route_table_init ();
170
171 new->lsdb = ospf_lsdb_new ();
172
173 new->default_originate = DEFAULT_ORIGINATE_NONE;
174
175 new->new_external_route = route_table_init ();
176 new->old_external_route = route_table_init ();
177 new->external_lsas = route_table_init ();
178
179 /* Distribute parameter init. */
180 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
181 {
182 new->dmetric[i].type = -1;
183 new->dmetric[i].value = -1;
184 }
185 new->default_metric = -1;
186 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
187
188 /* SPF timer value init. */
189 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
190 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
191
192 /* MaxAge init. */
193 new->maxage_lsa = list_new ();
194 new->t_maxage_walker =
195 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000196 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000197
198 /* Distance table init. */
199 new->distance_table = route_table_init ();
200
201 new->lsa_refresh_queue.index = 0;
202 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
203 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
204 new, new->lsa_refresh_interval);
205 new->lsa_refresher_started = time (NULL);
206
207 new->fd = ospf_sock_init ();
208 if (new->fd >= 0)
209 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
210 new->oi_write_q = list_new ();
211
212 return new;
213}
214
215struct ospf *
paul020709f2003-04-04 02:44:16 +0000216ospf_lookup ()
217{
218 if (listcount (om->ospf) == 0)
219 return NULL;
220
221 return getdata (listhead (om->ospf));
222}
223
224void
225ospf_add (struct ospf *ospf)
226{
227 listnode_add (om->ospf, ospf);
228}
229
230void
231ospf_delete (struct ospf *ospf)
232{
233 listnode_delete (om->ospf, ospf);
234}
235
236struct ospf *
paul718e3742002-12-13 20:15:29 +0000237ospf_get ()
238{
paul020709f2003-04-04 02:44:16 +0000239 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000240
paul020709f2003-04-04 02:44:16 +0000241 ospf = ospf_lookup ();
242 if (ospf == NULL)
243 {
244 ospf = ospf_new ();
245 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000246
paul020709f2003-04-04 02:44:16 +0000247 if (ospf->router_id_static.s_addr == 0)
248 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000249
250#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000251 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000252#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000253 }
paul68980082003-03-25 05:07:42 +0000254
255 return ospf;
paul718e3742002-12-13 20:15:29 +0000256}
257
258void
259ospf_finish (struct ospf *ospf)
260{
261 struct route_node *rn;
262 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000263 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +0000264 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000265 int i;
266
267#ifdef HAVE_OPAQUE_LSA
268 ospf_opaque_type11_lsa_term (ospf);
269#endif /* HAVE_OPAQUE_LSA */
270
271 /* Unredister redistribution */
272 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000273 ospf_redistribute_unset (ospf, i);
paul718e3742002-12-13 20:15:29 +0000274
275 for (node = listhead (ospf->areas); node;)
276 {
277 struct ospf_area *area = getdata (node);
278 nextnode (node);
279
paul68980082003-03-25 05:07:42 +0000280 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000281 }
282
283 for (node = listhead (ospf->vlinks); node; )
284 {
285 struct ospf_vl_data *vl_data = node->data;
286 nextnode (node);
287
paul68980082003-03-25 05:07:42 +0000288 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000289 }
290
291 list_delete (ospf->vlinks);
292
293 /* Reset interface. */
294 for (node = listhead (ospf->oiflist); node;)
295 {
296 struct ospf_interface *oi = getdata (node);
297 nextnode (node);
298
299 if (oi)
300 ospf_if_free (oi);
301 }
302
303 /* Clear static neighbors */
304 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
305 if ((nbr_nbma = rn->info))
306 {
307 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
308
309 if (nbr_nbma->nbr)
310 {
311 nbr_nbma->nbr->nbr_nbma = NULL;
312 nbr_nbma->nbr = NULL;
313 }
314
315 if (nbr_nbma->oi)
316 {
317 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
318 nbr_nbma->oi = NULL;
319 }
320
321 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
322 }
323
324 route_table_finish (ospf->nbr_nbma);
325
326 /* Clear networks and Areas. */
327 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
328 {
329 struct ospf_network *network;
330
331 if ((network = rn->info) != NULL)
332 {
paul68980082003-03-25 05:07:42 +0000333 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000334 rn->info = NULL;
335 route_unlock_node (rn);
336 }
337 }
338
339 for (node = listhead (ospf->areas); node;)
340 {
341 struct ospf_area *area = getdata (node);
342 nextnode (node);
343
344 listnode_delete (ospf->areas, area);
345 ospf_area_free (area);
346 }
347
348 /* Cancel all timers. */
349 OSPF_TIMER_OFF (ospf->t_external_lsa);
350 OSPF_TIMER_OFF (ospf->t_router_id_update);
351 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
352 OSPF_TIMER_OFF (ospf->t_spf_calc);
353 OSPF_TIMER_OFF (ospf->t_ase_calc);
354 OSPF_TIMER_OFF (ospf->t_maxage);
355 OSPF_TIMER_OFF (ospf->t_maxage_walker);
356 OSPF_TIMER_OFF (ospf->t_abr_task);
357 OSPF_TIMER_OFF (ospf->t_distribute_update);
358 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
359 OSPF_TIMER_OFF (ospf->t_read);
360 OSPF_TIMER_OFF (ospf->t_write);
361
362 close (ospf->fd);
363
364#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000365 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
366 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000367#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000368 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
369 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
370
paul718e3742002-12-13 20:15:29 +0000371 ospf_lsdb_delete_all (ospf->lsdb);
372 ospf_lsdb_free (ospf->lsdb);
373
374 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
375 ospf_lsa_unlock (getdata (node));
376
377 list_delete (ospf->maxage_lsa);
378
379 if (ospf->old_table)
380 ospf_route_table_free (ospf->old_table);
381 if (ospf->new_table)
382 {
383 ospf_route_delete (ospf->new_table);
384 ospf_route_table_free (ospf->new_table);
385 }
386 if (ospf->old_rtrs)
387 ospf_rtrs_free (ospf->old_rtrs);
388 if (ospf->new_rtrs)
389 ospf_rtrs_free (ospf->new_rtrs);
390 if (ospf->new_external_route)
391 {
392 ospf_route_delete (ospf->new_external_route);
393 ospf_route_table_free (ospf->new_external_route);
394 }
395 if (ospf->old_external_route)
396 {
397 ospf_route_delete (ospf->old_external_route);
398 ospf_route_table_free (ospf->old_external_route);
399 }
400 if (ospf->external_lsas)
401 {
402 ospf_ase_external_lsas_finish (ospf->external_lsas);
403 }
404
405 list_delete (ospf->areas);
406
407 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
408 if (EXTERNAL_INFO (i) != NULL)
409 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
410 {
411 if (rn->info == NULL)
412 continue;
413
414 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
415 rn->info = NULL;
416 route_unlock_node (rn);
417 }
418
paul68980082003-03-25 05:07:42 +0000419 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000420 route_table_finish (ospf->distance_table);
421
paul020709f2003-04-04 02:44:16 +0000422 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000423
paul020709f2003-04-04 02:44:16 +0000424 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000425}
426
427
428/* allocate new OSPF Area object */
429struct ospf_area *
paul68980082003-03-25 05:07:42 +0000430ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000431{
432 struct ospf_area *new;
433
434 /* Allocate new config_network. */
435 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
436
paul68980082003-03-25 05:07:42 +0000437 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000438
439 new->area_id = area_id;
440
441 new->external_routing = OSPF_AREA_DEFAULT;
442 new->default_cost = 1;
443 new->auth_type = OSPF_AUTH_NULL;
444
445 /* New LSDB init. */
446 new->lsdb = ospf_lsdb_new ();
447
448 /* Self-originated LSAs initialize. */
449 new->router_lsa_self = NULL;
450
451#ifdef HAVE_OPAQUE_LSA
452 ospf_opaque_type10_lsa_init (new);
453#endif /* HAVE_OPAQUE_LSA */
454
455 new->oiflist = list_new ();
456 new->ranges = route_table_init ();
457
458 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000459 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000460
461 return new;
462}
463
464void
465ospf_area_free (struct ospf_area *area)
466{
paul68980082003-03-25 05:07:42 +0000467 struct route_node *rn;
468 struct ospf_lsa *lsa;
469
paul718e3742002-12-13 20:15:29 +0000470 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000471 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
472 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
473 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
474 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
475 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
476 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
477 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
478 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000479
paul68980082003-03-25 05:07:42 +0000480 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
481 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000482#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000483 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
484 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
485 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
486 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000487#endif /* HAVE_OPAQUE_LSA */
488
489 ospf_lsdb_delete_all (area->lsdb);
490 ospf_lsdb_free (area->lsdb);
491
paul718e3742002-12-13 20:15:29 +0000492 ospf_lsa_unlock (area->router_lsa_self);
493
494 route_table_finish (area->ranges);
495 list_delete (area->oiflist);
496
497 if (EXPORT_NAME (area))
498 free (EXPORT_NAME (area));
499
500 if (IMPORT_NAME (area))
501 free (IMPORT_NAME (area));
502
503 /* Cancel timer. */
504 OSPF_TIMER_OFF (area->t_router_lsa_self);
505
506 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000507 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000508
509 XFREE (MTYPE_OSPF_AREA, area);
510}
511
512void
paul68980082003-03-25 05:07:42 +0000513ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000514{
515 struct ospf_area *area;
516
paul68980082003-03-25 05:07:42 +0000517 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000518 if (area &&
519 listcount (area->oiflist) == 0 &&
520 area->ranges->top == NULL &&
521 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
522 area->external_routing == OSPF_AREA_DEFAULT &&
523 area->no_summary == 0 &&
524 area->default_cost == 1 &&
525 EXPORT_NAME (area) == NULL &&
526 IMPORT_NAME (area) == NULL &&
527 area->auth_type == OSPF_AUTH_NULL)
528 {
paul68980082003-03-25 05:07:42 +0000529 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000530 ospf_area_free (area);
531 }
532}
533
534struct ospf_area *
paul68980082003-03-25 05:07:42 +0000535ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000536{
537 struct ospf_area *area;
538
paul68980082003-03-25 05:07:42 +0000539 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000540 if (!area)
541 {
paul68980082003-03-25 05:07:42 +0000542 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000543 area->format = format;
paul68980082003-03-25 05:07:42 +0000544 listnode_add_sort (ospf->areas, area);
545 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000546 }
547
548 return area;
549}
550
551struct ospf_area *
paul68980082003-03-25 05:07:42 +0000552ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000553{
554 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000555 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000556
paul68980082003-03-25 05:07:42 +0000557 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000558 {
559 area = getdata (node);
560
561 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
562 return area;
563 }
564
565 return NULL;
566}
567
568void
569ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
570{
571 listnode_add (area->oiflist, oi);
572}
573
574void
575ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
576{
577 listnode_delete (area->oiflist, oi);
578}
579
580
581/* Config network statement related functions. */
582struct ospf_network *
583ospf_network_new (struct in_addr area_id, int format)
584{
585 struct ospf_network *new;
586 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
587
588 new->area_id = area_id;
589 new->format = format;
590
591 return new;
592}
593
594void
paul68980082003-03-25 05:07:42 +0000595ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000596{
paul68980082003-03-25 05:07:42 +0000597 ospf_area_check_free (ospf, network->area_id);
598 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000599 XFREE (MTYPE_OSPF_NETWORK, network);
600}
601
602int
603ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
604 struct in_addr area_id)
605{
606 struct ospf_network *network;
607 struct ospf_area *area;
608 struct route_node *rn;
609 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000610 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000611
612 rn = route_node_get (ospf->networks, (struct prefix *)p);
613 if (rn->info)
614 {
615 /* There is already same network statement. */
616 route_unlock_node (rn);
617 return 0;
618 }
619
620 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000621 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000622
623 /* Run network config now. */
624 ospf_network_run (ospf, (struct prefix *)p, area);
625
626 /* Update connected redistribute. */
627 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
628 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
629 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
630 rn; rn = route_next (rn))
631 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000632 if (ospf_external_info_find_lsa (ospf, &ei->p))
633 if (!ospf_distribute_check_connected (ospf, ei))
634 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
paul718e3742002-12-13 20:15:29 +0000635 ei->ifindex, ei->nexthop);
636
paul68980082003-03-25 05:07:42 +0000637 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000638
639 return 1;
640}
641
642int
643ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
644 struct in_addr area_id)
645{
646 struct route_node *rn;
647 struct ospf_network *network;
648 struct external_info *ei;
649
650 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
651 if (rn == NULL)
652 return 0;
653
654 network = rn->info;
655 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
656 return 0;
657
paul68980082003-03-25 05:07:42 +0000658 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000659 rn->info = NULL;
660 route_unlock_node (rn);
661
paul68980082003-03-25 05:07:42 +0000662 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000663
664 /* Update connected redistribute. */
665 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
666 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
667 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
668 rn; rn = route_next (rn))
669 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000670 if (!ospf_external_info_find_lsa (ospf, &ei->p))
671 if (ospf_distribute_check_connected (ospf, ei))
672 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000673
674 return 1;
675}
676
paul570f7592003-01-25 06:47:41 +0000677/* Check whether interface matches given network
678 * returns: 1, true. 0, false
679 */
680int
681ospf_network_match_iface(struct connected *co, struct prefix *net)
682{
683 /* Behaviour to match both Cisco where:
684 * iface address lies within network specified -> ospf
685 * and zebra 0.9[2ish-3]:
686 * PtP special case: network specified == iface peer addr -> ospf
687 */
gdt8f40e892003-12-05 14:01:43 +0000688
paulf3ae74c2004-11-04 20:35:31 +0000689 /* For PtP, match if peer address matches network address exactly.
690 * This can be addr/32 or addr/p for p < 32, but the addr must match
691 * exactly; this is not a test for falling within the prefix. This
gdt8f40e892003-12-05 14:01:43 +0000692 * test is solely for compatibility with zebra.
gdt8f40e892003-12-05 14:01:43 +0000693 */
paulf3ae74c2004-11-04 20:35:31 +0000694 if (if_is_pointopoint (co->ifp) && co->destination &&
695 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
696 return 1;
697
698#if 0
699 /* Decline to accept PtP if dst address does not match the
700 * prefix. (ifdefed out because this is a workaround, not the
701 * desired behavior.) */
702 if (if_is_pointopoint (co->ifp) &&
703 ! prefix_match (net, co->destination))
704 return 0;
705#endif
706
707 /* If the address is within the prefix, accept. Note that this
708 * applies to PtP as well as other types.
709 */
710 if (prefix_match (net, co->address))
711 return 1;
712
713 return 0; /* no match */
paul570f7592003-01-25 06:47:41 +0000714}
715
paul718e3742002-12-13 20:15:29 +0000716void
717ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
718{
719 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000720 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000721
722 /* Schedule Router ID Update. */
723 if (ospf->router_id_static.s_addr == 0)
724 if (ospf->t_router_id_update == NULL)
725 {
paul020709f2003-04-04 02:44:16 +0000726 OSPF_TIMER_ON (ospf->t_router_id_update, ospf_router_id_update_timer,
727 OSPF_ROUTER_ID_UPDATE_DELAY);
paul718e3742002-12-13 20:15:29 +0000728 }
729
730 /* Get target interface. */
paul020709f2003-04-04 02:44:16 +0000731 for (node = listhead (om->iflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000732 {
hasso52dc7ee2004-09-23 19:18:23 +0000733 struct listnode *cn;
paul718e3742002-12-13 20:15:29 +0000734
735 if ((ifp = getdata (node)) == NULL)
736 continue;
737
738 if (memcmp (ifp->name, "VLINK", 5) == 0)
739 continue;
740
741 /* if interface prefix is match specified prefix,
742 then create socket and join multicast group. */
743 for (cn = listhead (ifp->connected); cn; nextnode (cn))
744 {
745 struct connected *co = getdata (cn);
746 struct prefix *addr;
paul800dc102003-03-28 01:51:40 +0000747
paule7b050c2003-04-07 06:38:02 +0000748 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
749 continue;
paul718e3742002-12-13 20:15:29 +0000750
hasso3fb9cd62004-10-19 19:44:43 +0000751 if (CONNECTED_POINTOPOINT_HOST(co))
paul718e3742002-12-13 20:15:29 +0000752 addr = co->destination;
753 else
754 addr = co->address;
755
paulcb3f37d2003-02-18 23:26:37 +0000756 if (p->family == co->address->family
paul68980082003-03-25 05:07:42 +0000757 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
paulcb3f37d2003-02-18 23:26:37 +0000758 && ospf_network_match_iface(co,p))
paul570f7592003-01-25 06:47:41 +0000759 {
paul537d8ea2003-08-27 06:45:32 +0000760 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000761
paul68980082003-03-25 05:07:42 +0000762 oi = ospf_if_new (ospf, ifp, co->address);
paul718e3742002-12-13 20:15:29 +0000763 oi->connected = co;
764
765 oi->nbr_self->address = *oi->address;
766
paul718e3742002-12-13 20:15:29 +0000767 oi->area = area;
768
769 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
770 oi->output_cost = ospf_if_get_output_cost (oi);
771
772 if (area->external_routing != OSPF_AREA_DEFAULT)
773 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
774 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
775
776 /* Add pseudo neighbor. */
777 ospf_nbr_add_self (oi);
778
779 /* Make sure pseudo neighbor's router_id. */
paul68980082003-03-25 05:07:42 +0000780 oi->nbr_self->router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000781 oi->nbr_self->src = oi->address->u.prefix4;
782
783 /* Relate ospf interface to ospf instance. */
paul68980082003-03-25 05:07:42 +0000784 oi->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000785
786 /* update network type as interface flag */
787 /* If network type is specified previously,
788 skip network type setting. */
789 oi->type = IF_DEF_PARAMS (ifp)->type;
790
791 /* Set area flag. */
792 switch (area->external_routing)
793 {
794 case OSPF_AREA_DEFAULT:
795 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
796 break;
797 case OSPF_AREA_STUB:
798 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
799 break;
paul718e3742002-12-13 20:15:29 +0000800 case OSPF_AREA_NSSA:
801 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
802 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
803 break;
paul718e3742002-12-13 20:15:29 +0000804 }
805
806 ospf_area_add_if (oi->area, oi);
807
paul2e3b2e42002-12-13 21:03:13 +0000808 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000809 ospf_if_up (oi);
810
811 break;
812 }
813 }
814 }
815}
816
817void
818ospf_ls_upd_queue_empty (struct ospf_interface *oi)
819{
820 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +0000821 struct listnode *node;
822 struct list *lst;
paul718e3742002-12-13 20:15:29 +0000823 struct ospf_lsa *lsa;
824
825 /* empty ls update queue */
826 for (rn = route_top (oi->ls_upd_queue); rn;
827 rn = route_next (rn))
hasso52dc7ee2004-09-23 19:18:23 +0000828 if ((lst = (struct list *) rn->info))
paul718e3742002-12-13 20:15:29 +0000829 {
830 for (node = listhead (lst); node; nextnode (node))
831 if ((lsa = getdata (node)))
832 ospf_lsa_unlock (lsa);
833 list_free (lst);
834 rn->info = NULL;
835 }
836
837 /* remove update event */
838 if (oi->t_ls_upd_event)
839 {
840 thread_cancel (oi->t_ls_upd_event);
841 oi->t_ls_upd_event = NULL;
842 }
843}
844
845void
paul68980082003-03-25 05:07:42 +0000846ospf_if_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000847{
848 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +0000849 struct listnode *node;
850 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000851 struct ospf_network *network;
852 struct ospf_area *area;
853
paul68980082003-03-25 05:07:42 +0000854 if (ospf != NULL)
paul718e3742002-12-13 20:15:29 +0000855 {
856 /* Update Router ID scheduled. */
paul68980082003-03-25 05:07:42 +0000857 if (ospf->router_id_static.s_addr == 0)
858 if (ospf->t_router_id_update == NULL)
paul718e3742002-12-13 20:15:29 +0000859 {
paul020709f2003-04-04 02:44:16 +0000860 OSPF_TIMER_ON (ospf->t_router_id_update,
861 ospf_router_id_update_timer,
862 OSPF_ROUTER_ID_UPDATE_DELAY);
paul718e3742002-12-13 20:15:29 +0000863 }
864
865 /* Find interfaces that not configured already. */
paul68980082003-03-25 05:07:42 +0000866 for (node = listhead (ospf->oiflist); node; node = next)
paul718e3742002-12-13 20:15:29 +0000867 {
868 int found = 0;
869 struct ospf_interface *oi = getdata (node);
870 struct connected *co = oi->connected;
871
872 next = nextnode (node);
873
874 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
875 continue;
876
paul68980082003-03-25 05:07:42 +0000877 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000878 {
879 if (rn->info == NULL)
880 continue;
881
paul570f7592003-01-25 06:47:41 +0000882 if (ospf_network_match_iface(co,&rn->p))
paul718e3742002-12-13 20:15:29 +0000883 {
884 found = 1;
885 route_unlock_node (rn);
886 break;
887 }
888 }
889
890 if (found == 0)
891 ospf_if_free (oi);
892 }
893
894 /* Run each interface. */
paul68980082003-03-25 05:07:42 +0000895 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000896 if (rn->info != NULL)
897 {
898 network = (struct ospf_network *) rn->info;
paul68980082003-03-25 05:07:42 +0000899 area = ospf_area_get (ospf, network->area_id, network->format);
900 ospf_network_run (ospf, &rn->p, area);
paul718e3742002-12-13 20:15:29 +0000901 }
902 }
903}
904
905void
paul68980082003-03-25 05:07:42 +0000906ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000907{
hasso52dc7ee2004-09-23 19:18:23 +0000908 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +0000909 struct ospf_vl_data *vl_data;
910
paul68980082003-03-25 05:07:42 +0000911 for (node = listhead (ospf->vlinks); node; node = next)
paul718e3742002-12-13 20:15:29 +0000912 {
913 next = node->next;
914 if ((vl_data = getdata (node)) != NULL)
915 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
paul68980082003-03-25 05:07:42 +0000916 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000917 }
918}
919
920
921struct message ospf_area_type_msg[] =
922{
923 { OSPF_AREA_DEFAULT, "Default" },
924 { OSPF_AREA_STUB, "Stub" },
925 { OSPF_AREA_NSSA, "NSSA" },
926};
927int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
928
929void
930ospf_area_type_set (struct ospf_area *area, int type)
931{
hasso52dc7ee2004-09-23 19:18:23 +0000932 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000933 struct ospf_interface *oi;
934
935 if (area->external_routing == type)
936 {
937 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000938 zlog_debug ("Area[%s]: Types are the same, ignored.",
paul718e3742002-12-13 20:15:29 +0000939 inet_ntoa (area->area_id));
940 return;
941 }
942
943 area->external_routing = type;
944
945 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000946 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
paul718e3742002-12-13 20:15:29 +0000947 LOOKUP (ospf_area_type_msg, type));
948
949 switch (area->external_routing)
950 {
951 case OSPF_AREA_DEFAULT:
952 for (node = listhead (area->oiflist); node; nextnode (node))
953 if ((oi = getdata (node)) != NULL)
954 if (oi->nbr_self != NULL)
hasso8585d4e2004-04-20 17:25:12 +0000955 {
hasso8585d4e2004-04-20 17:25:12 +0000956 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
hasso8585d4e2004-04-20 17:25:12 +0000957 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
958 }
paul718e3742002-12-13 20:15:29 +0000959 break;
960 case OSPF_AREA_STUB:
961 for (node = listhead (area->oiflist); node; nextnode (node))
962 if ((oi = getdata (node)) != NULL)
963 if (oi->nbr_self != NULL)
964 {
965 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000966 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
hasso8585d4e2004-04-20 17:25:12 +0000967 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
paul718e3742002-12-13 20:15:29 +0000968 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
969 if (IS_DEBUG_OSPF_EVENT)
ajs9b0e25c2004-12-08 19:06:51 +0000970 zlog_debug ("options set on %s: %x",
paul718e3742002-12-13 20:15:29 +0000971 IF_NAME (oi), OPTIONS (oi));
972 }
973 break;
974 case OSPF_AREA_NSSA:
paul718e3742002-12-13 20:15:29 +0000975 for (node = listhead (area->oiflist); node; nextnode (node))
976 if ((oi = getdata (node)) != NULL)
977 if (oi->nbr_self != NULL)
978 {
ajs9b0e25c2004-12-08 19:06:51 +0000979 if (IS_DEBUG_OSPF_EVENT)
980 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +0000981 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
982 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
ajs9b0e25c2004-12-08 19:06:51 +0000983 if (IS_DEBUG_OSPF_EVENT)
984 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
paul718e3742002-12-13 20:15:29 +0000985 }
paul718e3742002-12-13 20:15:29 +0000986 break;
987 default:
988 break;
989 }
990
991 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +0000992 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +0000993}
994
995int
paul68980082003-03-25 05:07:42 +0000996ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +0000997{
998 if (area->shortcut_configured == mode)
999 return 0;
1000
1001 area->shortcut_configured = mode;
1002 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001003 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001004
paul68980082003-03-25 05:07:42 +00001005 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001006
1007 return 1;
1008}
1009
1010int
paul68980082003-03-25 05:07:42 +00001011ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001012{
1013 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1014 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001015 ospf_area_check_free (ospf, area->area_id);
1016 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001017
1018 return 1;
1019}
1020
1021int
1022ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1023{
1024 struct ospf_vl_data *vl;
hasso52dc7ee2004-09-23 19:18:23 +00001025 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001026 int count = 0;
1027
1028 for (node = listhead (ospf->vlinks); node; nextnode (node))
1029 {
1030 vl = getdata (node);
1031 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1032 count++;
1033 }
1034
1035 return count;
1036}
1037
1038int
1039ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1040{
1041 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001042 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001043
paul68980082003-03-25 05:07:42 +00001044 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001045 if (ospf_area_vlink_count (ospf, area))
1046 return 0;
1047
1048 if (area->external_routing != OSPF_AREA_STUB)
1049 ospf_area_type_set (area, OSPF_AREA_STUB);
1050
1051 return 1;
1052}
1053
1054int
1055ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1056{
1057 struct ospf_area *area;
1058
paul68980082003-03-25 05:07:42 +00001059 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001060 if (area == NULL)
1061 return 1;
1062
1063 if (area->external_routing == OSPF_AREA_STUB)
1064 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1065
paul68980082003-03-25 05:07:42 +00001066 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001067
1068 return 1;
1069}
1070
1071int
1072ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1073{
1074 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001075 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001076
paul68980082003-03-25 05:07:42 +00001077 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001078 area->no_summary = 1;
1079
1080 return 1;
1081}
1082
1083int
1084ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1085{
1086 struct ospf_area *area;
1087
paul68980082003-03-25 05:07:42 +00001088 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001089 if (area == NULL)
1090 return 0;
1091
1092 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001093 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001094
1095 return 1;
1096}
1097
1098int
1099ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1100{
1101 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001102 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001103
paul68980082003-03-25 05:07:42 +00001104 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001105 if (ospf_area_vlink_count (ospf, area))
1106 return 0;
1107
1108 if (area->external_routing != OSPF_AREA_NSSA)
1109 {
1110 ospf_area_type_set (area, OSPF_AREA_NSSA);
1111 ospf->anyNSSA++;
1112 }
1113
paul084c7842003-06-22 08:35:18 +00001114 /* set NSSA area defaults */
1115 area->no_summary = 0;
1116 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
pauld4a53d52003-07-12 21:30:57 +00001117 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paul084c7842003-06-22 08:35:18 +00001118 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1119
paul718e3742002-12-13 20:15:29 +00001120 return 1;
1121}
1122
1123int
1124ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1125{
1126 struct ospf_area *area;
1127
paul68980082003-03-25 05:07:42 +00001128 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001129 if (area == NULL)
1130 return 0;
1131
1132 if (area->external_routing == OSPF_AREA_NSSA)
1133 {
1134 ospf->anyNSSA--;
1135 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1136 }
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_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1145 int role)
1146{
1147 struct ospf_area *area;
1148
paul68980082003-03-25 05:07:42 +00001149 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001150 if (area == NULL)
1151 return 0;
1152
paul084c7842003-06-22 08:35:18 +00001153 area->NSSATranslatorRole = role;
paul718e3742002-12-13 20:15:29 +00001154
1155 return 1;
1156}
1157
1158int
1159ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1160 struct in_addr area_id)
1161{
1162 struct ospf_area *area;
1163
paul68980082003-03-25 05:07:42 +00001164 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001165 if (area == NULL)
1166 return 0;
1167
paul084c7842003-06-22 08:35:18 +00001168 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
paul718e3742002-12-13 20:15:29 +00001169
paul68980082003-03-25 05:07:42 +00001170 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001171
1172 return 1;
1173}
1174
1175int
paul68980082003-03-25 05:07:42 +00001176ospf_area_export_list_set (struct ospf *ospf,
paul6c835672004-10-11 11:00:30 +00001177 struct ospf_area *area, const char *list_name)
paul718e3742002-12-13 20:15:29 +00001178{
1179 struct access_list *list;
1180 list = access_list_lookup (AFI_IP, list_name);
1181
1182 EXPORT_LIST (area) = list;
1183
1184 if (EXPORT_NAME (area))
1185 free (EXPORT_NAME (area));
1186
1187 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001188 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001189
1190 return 1;
1191}
1192
1193int
paul68980082003-03-25 05:07:42 +00001194ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001195{
1196
1197 EXPORT_LIST (area) = 0;
1198
1199 if (EXPORT_NAME (area))
1200 free (EXPORT_NAME (area));
1201
1202 EXPORT_NAME (area) = NULL;
1203
paul68980082003-03-25 05:07:42 +00001204 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001205
paul68980082003-03-25 05:07:42 +00001206 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001207
1208 return 1;
1209}
1210
1211int
paul6c835672004-10-11 11:00:30 +00001212ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1213 const char *name)
paul718e3742002-12-13 20:15:29 +00001214{
1215 struct access_list *list;
1216 list = access_list_lookup (AFI_IP, name);
1217
1218 IMPORT_LIST (area) = list;
1219
1220 if (IMPORT_NAME (area))
1221 free (IMPORT_NAME (area));
1222
1223 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001224 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001225
1226 return 1;
1227}
1228
1229int
paul68980082003-03-25 05:07:42 +00001230ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001231{
1232 IMPORT_LIST (area) = 0;
1233
1234 if (IMPORT_NAME (area))
1235 free (IMPORT_NAME (area));
1236
1237 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001238 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001239
paul68980082003-03-25 05:07:42 +00001240 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001241
1242 return 1;
1243}
1244
1245int
1246ospf_timers_spf_set (struct ospf *ospf, u_int32_t delay, u_int32_t hold)
1247{
1248 ospf->spf_delay = delay;
1249 ospf->spf_holdtime = hold;
1250
1251 return 1;
1252}
1253
1254int
1255ospf_timers_spf_unset (struct ospf *ospf)
1256{
1257 ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT;
1258 ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
1259
1260 return 1;
1261}
1262
1263int
1264ospf_timers_refresh_set (struct ospf *ospf, int interval)
1265{
1266 int time_left;
1267
1268 if (ospf->lsa_refresh_interval == interval)
1269 return 1;
1270
1271 time_left = ospf->lsa_refresh_interval -
1272 (time (NULL) - ospf->lsa_refresher_started);
1273
1274 if (time_left > interval)
1275 {
1276 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1277 ospf->t_lsa_refresher =
1278 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1279 }
1280 ospf->lsa_refresh_interval = interval;
1281
1282 return 1;
1283}
1284
1285int
1286ospf_timers_refresh_unset (struct ospf *ospf)
1287{
1288 int time_left;
1289
1290 time_left = ospf->lsa_refresh_interval -
1291 (time (NULL) - ospf->lsa_refresher_started);
1292
1293 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1294 {
1295 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1296 ospf->t_lsa_refresher =
1297 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1298 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1299 }
1300
1301 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1302
1303 return 1;
1304}
1305
1306
1307struct ospf_nbr_nbma *
1308ospf_nbr_nbma_new ()
1309{
1310 struct ospf_nbr_nbma *nbr_nbma;
1311
1312 nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1313 sizeof (struct ospf_nbr_nbma));
1314 memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));
1315
1316 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1317 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1318
1319 return nbr_nbma;
1320}
1321
1322void
1323ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1324{
1325 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1326}
1327
1328void
1329ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1330{
1331 struct route_node *rn;
1332 struct prefix_ipv4 p;
1333
1334 p.family = AF_INET;
1335 p.prefix = nbr_nbma->addr;
1336 p.prefixlen = IPV4_MAX_BITLEN;
1337
1338 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1339 if (rn)
1340 {
1341 ospf_nbr_nbma_free (rn->info);
1342 rn->info = NULL;
1343 route_unlock_node (rn);
1344 route_unlock_node (rn);
1345 }
1346}
1347
1348void
1349ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1350{
1351 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1352
1353 if (nbr_nbma->nbr)
1354 {
1355 nbr_nbma->nbr->nbr_nbma = NULL;
1356 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1357 }
1358
1359 if (nbr_nbma->oi)
1360 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1361}
1362
1363void
1364ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1365 struct ospf_interface *oi)
1366{
1367 struct ospf_neighbor *nbr;
1368 struct route_node *rn;
1369 struct prefix p;
1370
1371 if (oi->type != OSPF_IFTYPE_NBMA)
1372 return;
1373
1374 if (nbr_nbma->nbr != NULL)
1375 return;
1376
1377 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1378 return;
1379
1380 nbr_nbma->oi = oi;
1381 listnode_add (oi->nbr_nbma, nbr_nbma);
1382
1383 /* Get neighbor information from table. */
1384 p.family = AF_INET;
1385 p.prefixlen = IPV4_MAX_BITLEN;
1386 p.u.prefix4 = nbr_nbma->addr;
1387
1388 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1389 if (rn->info)
1390 {
1391 nbr = rn->info;
1392 nbr->nbr_nbma = nbr_nbma;
1393 nbr_nbma->nbr = nbr;
1394
1395 route_unlock_node (rn);
1396 }
1397 else
1398 {
1399 nbr = rn->info = ospf_nbr_new (oi);
1400 nbr->state = NSM_Down;
1401 nbr->src = nbr_nbma->addr;
1402 nbr->nbr_nbma = nbr_nbma;
1403 nbr->priority = nbr_nbma->priority;
1404 nbr->address = p;
1405
1406 nbr_nbma->nbr = nbr;
1407
1408 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1409 }
1410}
1411
1412void
paul68980082003-03-25 05:07:42 +00001413ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001414{
1415 struct ospf_nbr_nbma *nbr_nbma;
1416 struct route_node *rn;
1417 struct prefix_ipv4 p;
1418
1419 if (oi->type != OSPF_IFTYPE_NBMA)
1420 return;
1421
paul68980082003-03-25 05:07:42 +00001422 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001423 if ((nbr_nbma = rn->info))
1424 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1425 {
1426 p.family = AF_INET;
1427 p.prefix = nbr_nbma->addr;
1428 p.prefixlen = IPV4_MAX_BITLEN;
1429
1430 if (prefix_match (oi->address, (struct prefix *)&p))
1431 ospf_nbr_nbma_add (nbr_nbma, oi);
1432 }
1433}
1434
1435struct ospf_nbr_nbma *
1436ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1437{
1438 struct route_node *rn;
1439 struct prefix_ipv4 p;
1440
1441 p.family = AF_INET;
1442 p.prefix = nbr_addr;
1443 p.prefixlen = IPV4_MAX_BITLEN;
1444
1445 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1446 if (rn)
1447 {
1448 route_unlock_node (rn);
1449 return rn->info;
1450 }
1451 return NULL;
1452}
1453
1454struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001455ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001456{
1457#if 0
1458 struct ospf_nbr_nbma *nbr_nbma;
hasso52dc7ee2004-09-23 19:18:23 +00001459 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001460#endif
1461
paul68980082003-03-25 05:07:42 +00001462 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001463 return NULL;
1464
1465#if 0
paul68980082003-03-25 05:07:42 +00001466 for (node = listhead (ospf->nbr_nbma); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001467 {
1468 nbr_nbma = getdata (node);
1469
1470 if (first)
1471 {
1472 *addr = nbr_nbma->addr;
1473 return nbr_nbma;
1474 }
1475 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1476 {
1477 *addr = nbr_nbma->addr;
1478 return nbr_nbma;
1479 }
1480 }
1481#endif
1482 return NULL;
1483}
1484
1485int
1486ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1487{
1488 struct ospf_nbr_nbma *nbr_nbma;
1489 struct ospf_interface *oi;
1490 struct prefix_ipv4 p;
1491 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00001492 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001493
1494 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1495 if (nbr_nbma)
1496 return 0;
1497
1498 nbr_nbma = ospf_nbr_nbma_new ();
1499 nbr_nbma->addr = nbr_addr;
1500
1501 p.family = AF_INET;
1502 p.prefix = nbr_addr;
1503 p.prefixlen = IPV4_MAX_BITLEN;
1504
1505 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1506 rn->info = nbr_nbma;
1507
1508 for (node = listhead (ospf->oiflist); node; nextnode (node))
1509 {
1510 oi = getdata (node);
1511 if (oi->type == OSPF_IFTYPE_NBMA)
1512 if (prefix_match (oi->address, (struct prefix *)&p))
1513 {
1514 ospf_nbr_nbma_add (nbr_nbma, oi);
1515 break;
1516 }
1517 }
1518
1519 return 1;
1520}
1521
1522int
1523ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1524{
1525 struct ospf_nbr_nbma *nbr_nbma;
1526
1527 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1528 if (nbr_nbma == NULL)
1529 return 0;
1530
1531 ospf_nbr_nbma_down (nbr_nbma);
1532 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1533
1534 return 1;
1535}
1536
1537int
1538ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1539 u_char priority)
1540{
1541 struct ospf_nbr_nbma *nbr_nbma;
1542
1543 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1544 if (nbr_nbma == NULL)
1545 return 0;
1546
1547 if (nbr_nbma->priority != priority)
1548 nbr_nbma->priority = priority;
1549
1550 return 1;
1551}
1552
1553int
1554ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1555{
1556 struct ospf_nbr_nbma *nbr_nbma;
1557
1558 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1559 if (nbr_nbma == NULL)
1560 return 0;
1561
1562 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1563 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1564
1565 return 1;
1566}
1567
1568int
1569ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
paul6c835672004-10-11 11:00:30 +00001570 unsigned int interval)
paul718e3742002-12-13 20:15:29 +00001571{
1572 struct ospf_nbr_nbma *nbr_nbma;
1573
1574 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1575 if (nbr_nbma == NULL)
1576 return 0;
1577
1578 if (nbr_nbma->v_poll != interval)
1579 {
1580 nbr_nbma->v_poll = interval;
1581 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1582 {
1583 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1584 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1585 nbr_nbma->v_poll);
1586 }
1587 }
1588
1589 return 1;
1590}
1591
1592int
1593ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1594{
1595 struct ospf_nbr_nbma *nbr_nbma;
1596
1597 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1598 if (nbr_nbma == NULL)
1599 return 0;
1600
1601 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1602 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1603
1604 return 1;
1605}
1606
paul718e3742002-12-13 20:15:29 +00001607void
paul020709f2003-04-04 02:44:16 +00001608ospf_master_init ()
1609{
1610 memset (&ospf_master, 0, sizeof (struct ospf_master));
1611
1612 om = &ospf_master;
1613 om->ospf = list_new ();
1614 om->master = thread_master_create ();
1615 om->start_time = time (NULL);
1616}