blob: d8646f07b445fc402b786bd21eb301cfb668db63 [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
56/* OSPF process wide configuration. */
57static struct ospf_master ospf_master;
58
59/* OSPF process wide configuration pointer to export. */
60struct ospf_master *om;
paul718e3742002-12-13 20:15:29 +000061
62extern struct zclient *zclient;
63
64
paul68980082003-03-25 05:07:42 +000065void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
66void ospf_network_free (struct ospf *, struct ospf_network *);
paul718e3742002-12-13 20:15:29 +000067void ospf_area_free (struct ospf_area *);
68void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
69
70/* Get Router ID from ospf interface list. */
71struct in_addr
72ospf_router_id_get (list if_list)
73{
74 listnode node;
75 struct in_addr router_id;
76
77 memset (&router_id, 0, sizeof (struct in_addr));
78
79 for (node = listhead (if_list); node; nextnode (node))
80 {
81 struct ospf_interface *oi = getdata (node);
82
83 if (!if_is_up (oi->ifp) ||
84 OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
85 continue;
86
87 /* Ignore virtual link interface. */
88 if (oi->type != OSPF_IFTYPE_VIRTUALLINK &&
89 oi->type != OSPF_IFTYPE_LOOPBACK)
90 if (IPV4_ADDR_CMP (&router_id, &oi->address->u.prefix4) < 0)
91 router_id = oi->address->u.prefix4;
92 }
93
94 return router_id;
95}
96
97#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
98
99void
paul68980082003-03-25 05:07:42 +0000100ospf_router_id_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000101{
paul718e3742002-12-13 20:15:29 +0000102 struct in_addr router_id, router_id_old;
paul68980082003-03-25 05:07:42 +0000103 listnode node;
paul718e3742002-12-13 20:15:29 +0000104
105 if (IS_DEBUG_OSPF_EVENT)
paul68980082003-03-25 05:07:42 +0000106 zlog_info ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000107
paul68980082003-03-25 05:07:42 +0000108 router_id_old = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000109
paul68980082003-03-25 05:07:42 +0000110 if (ospf->router_id_static.s_addr != 0)
111 router_id = ospf->router_id_static;
paul718e3742002-12-13 20:15:29 +0000112 else
paul68980082003-03-25 05:07:42 +0000113 router_id = ospf_router_id_get (ospf->oiflist);
paul718e3742002-12-13 20:15:29 +0000114
paul68980082003-03-25 05:07:42 +0000115 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000116
117 if (IS_DEBUG_OSPF_EVENT)
paul68980082003-03-25 05:07:42 +0000118 zlog_info ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000119
120 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
121 {
paul68980082003-03-25 05:07:42 +0000122 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000123 {
124 struct ospf_interface *oi = getdata (node);
125
126 /* Update self-neighbor's router_id. */
127 oi->nbr_self->router_id = router_id;
128 }
129
130 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000131 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000132 {
133 int type;
134 /* Originate each redistributed external route. */
135 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000136 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000137 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000138 ospf, type);
paul718e3742002-12-13 20:15:29 +0000139 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000140 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
paul718e3742002-12-13 20:15:29 +0000141 thread_add_event (master, ospf_default_originate_timer,
paul68980082003-03-25 05:07:42 +0000142 &ospf->default_originate, 0);
paul718e3742002-12-13 20:15:29 +0000143
paul68980082003-03-25 05:07:42 +0000144 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000145 }
146
paul68980082003-03-25 05:07:42 +0000147 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000148 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
149 }
150}
151
152int
153ospf_router_id_update_timer (struct thread *thread)
154{
paul020709f2003-04-04 02:44:16 +0000155 struct ospf *ospf = THREAD_ARG (thread);
paul68980082003-03-25 05:07:42 +0000156
paul718e3742002-12-13 20:15:29 +0000157 if (IS_DEBUG_OSPF_EVENT)
158 zlog_info ("Router-ID: Update timer fired!");
159
paul68980082003-03-25 05:07:42 +0000160 ospf->t_router_id_update = NULL;
161 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000162
163 return 0;
164}
165
166/* For OSPF area sort by area id. */
167int
168ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
169{
170 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
171 return 1;
172 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
173 return -1;
174 return 0;
175}
176
177/* Allocate new ospf structure. */
178struct ospf *
179ospf_new ()
180{
181 int i;
182
183 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
184
185 new->router_id.s_addr = htonl (0);
186 new->router_id_static.s_addr = htonl (0);
187
188 new->abr_type = OSPF_ABR_STAND;
paul718e3742002-12-13 20:15:29 +0000189 new->oiflist = list_new ();
190 new->vlinks = list_new ();
191 new->areas = list_new ();
192 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
193 new->networks = route_table_init ();
194 new->nbr_nbma = route_table_init ();
195
196 new->lsdb = ospf_lsdb_new ();
197
198 new->default_originate = DEFAULT_ORIGINATE_NONE;
199
200 new->new_external_route = route_table_init ();
201 new->old_external_route = route_table_init ();
202 new->external_lsas = route_table_init ();
203
204 /* Distribute parameter init. */
205 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
206 {
207 new->dmetric[i].type = -1;
208 new->dmetric[i].value = -1;
209 }
210 new->default_metric = -1;
211 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
212
213 /* SPF timer value init. */
214 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
215 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
216
217 /* MaxAge init. */
218 new->maxage_lsa = list_new ();
219 new->t_maxage_walker =
220 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000221 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000222
223 /* Distance table init. */
224 new->distance_table = route_table_init ();
225
226 new->lsa_refresh_queue.index = 0;
227 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
228 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
229 new, new->lsa_refresh_interval);
230 new->lsa_refresher_started = time (NULL);
231
232 new->fd = ospf_sock_init ();
233 if (new->fd >= 0)
234 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
235 new->oi_write_q = list_new ();
236
237 return new;
238}
239
240struct ospf *
paul020709f2003-04-04 02:44:16 +0000241ospf_lookup ()
242{
243 if (listcount (om->ospf) == 0)
244 return NULL;
245
246 return getdata (listhead (om->ospf));
247}
248
249void
250ospf_add (struct ospf *ospf)
251{
252 listnode_add (om->ospf, ospf);
253}
254
255void
256ospf_delete (struct ospf *ospf)
257{
258 listnode_delete (om->ospf, ospf);
259}
260
261struct ospf *
paul718e3742002-12-13 20:15:29 +0000262ospf_get ()
263{
paul020709f2003-04-04 02:44:16 +0000264 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000265
paul020709f2003-04-04 02:44:16 +0000266 ospf = ospf_lookup ();
267 if (ospf == NULL)
268 {
269 ospf = ospf_new ();
270 ospf_add (ospf);
paul718e3742002-12-13 20:15:29 +0000271
paul020709f2003-04-04 02:44:16 +0000272 if (ospf->router_id_static.s_addr == 0)
273 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000274
275#ifdef HAVE_OPAQUE_LSA
paul020709f2003-04-04 02:44:16 +0000276 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000277#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +0000278 }
paul68980082003-03-25 05:07:42 +0000279
280 return ospf;
paul718e3742002-12-13 20:15:29 +0000281}
282
283void
284ospf_finish (struct ospf *ospf)
285{
286 struct route_node *rn;
287 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000288 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000289 listnode node;
290 int i;
291
292#ifdef HAVE_OPAQUE_LSA
293 ospf_opaque_type11_lsa_term (ospf);
294#endif /* HAVE_OPAQUE_LSA */
295
296 /* Unredister redistribution */
297 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
paul020709f2003-04-04 02:44:16 +0000298 ospf_redistribute_unset (ospf, i);
paul718e3742002-12-13 20:15:29 +0000299
300 for (node = listhead (ospf->areas); node;)
301 {
302 struct ospf_area *area = getdata (node);
303 nextnode (node);
304
paul68980082003-03-25 05:07:42 +0000305 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000306 }
307
308 for (node = listhead (ospf->vlinks); node; )
309 {
310 struct ospf_vl_data *vl_data = node->data;
311 nextnode (node);
312
paul68980082003-03-25 05:07:42 +0000313 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000314 }
315
316 list_delete (ospf->vlinks);
317
318 /* Reset interface. */
319 for (node = listhead (ospf->oiflist); node;)
320 {
321 struct ospf_interface *oi = getdata (node);
322 nextnode (node);
323
324 if (oi)
325 ospf_if_free (oi);
326 }
327
328 /* Clear static neighbors */
329 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
330 if ((nbr_nbma = rn->info))
331 {
332 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
333
334 if (nbr_nbma->nbr)
335 {
336 nbr_nbma->nbr->nbr_nbma = NULL;
337 nbr_nbma->nbr = NULL;
338 }
339
340 if (nbr_nbma->oi)
341 {
342 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
343 nbr_nbma->oi = NULL;
344 }
345
346 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
347 }
348
349 route_table_finish (ospf->nbr_nbma);
350
351 /* Clear networks and Areas. */
352 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
353 {
354 struct ospf_network *network;
355
356 if ((network = rn->info) != NULL)
357 {
paul68980082003-03-25 05:07:42 +0000358 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000359 rn->info = NULL;
360 route_unlock_node (rn);
361 }
362 }
363
364 for (node = listhead (ospf->areas); node;)
365 {
366 struct ospf_area *area = getdata (node);
367 nextnode (node);
368
369 listnode_delete (ospf->areas, area);
370 ospf_area_free (area);
371 }
372
373 /* Cancel all timers. */
374 OSPF_TIMER_OFF (ospf->t_external_lsa);
375 OSPF_TIMER_OFF (ospf->t_router_id_update);
376 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
377 OSPF_TIMER_OFF (ospf->t_spf_calc);
378 OSPF_TIMER_OFF (ospf->t_ase_calc);
379 OSPF_TIMER_OFF (ospf->t_maxage);
380 OSPF_TIMER_OFF (ospf->t_maxage_walker);
381 OSPF_TIMER_OFF (ospf->t_abr_task);
382 OSPF_TIMER_OFF (ospf->t_distribute_update);
383 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
384 OSPF_TIMER_OFF (ospf->t_read);
385 OSPF_TIMER_OFF (ospf->t_write);
386
387 close (ospf->fd);
388
389#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000390 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
391 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000392#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000393 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
394 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
395
paul718e3742002-12-13 20:15:29 +0000396 ospf_lsdb_delete_all (ospf->lsdb);
397 ospf_lsdb_free (ospf->lsdb);
398
399 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
400 ospf_lsa_unlock (getdata (node));
401
402 list_delete (ospf->maxage_lsa);
403
404 if (ospf->old_table)
405 ospf_route_table_free (ospf->old_table);
406 if (ospf->new_table)
407 {
408 ospf_route_delete (ospf->new_table);
409 ospf_route_table_free (ospf->new_table);
410 }
411 if (ospf->old_rtrs)
412 ospf_rtrs_free (ospf->old_rtrs);
413 if (ospf->new_rtrs)
414 ospf_rtrs_free (ospf->new_rtrs);
415 if (ospf->new_external_route)
416 {
417 ospf_route_delete (ospf->new_external_route);
418 ospf_route_table_free (ospf->new_external_route);
419 }
420 if (ospf->old_external_route)
421 {
422 ospf_route_delete (ospf->old_external_route);
423 ospf_route_table_free (ospf->old_external_route);
424 }
425 if (ospf->external_lsas)
426 {
427 ospf_ase_external_lsas_finish (ospf->external_lsas);
428 }
429
430 list_delete (ospf->areas);
431
432 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
433 if (EXTERNAL_INFO (i) != NULL)
434 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
435 {
436 if (rn->info == NULL)
437 continue;
438
439 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
440 rn->info = NULL;
441 route_unlock_node (rn);
442 }
443
paul68980082003-03-25 05:07:42 +0000444 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000445 route_table_finish (ospf->distance_table);
446
paul020709f2003-04-04 02:44:16 +0000447 ospf_delete (ospf);
paul718e3742002-12-13 20:15:29 +0000448
paul020709f2003-04-04 02:44:16 +0000449 XFREE (MTYPE_OSPF_TOP, ospf);
paul718e3742002-12-13 20:15:29 +0000450}
451
452
453/* allocate new OSPF Area object */
454struct ospf_area *
paul68980082003-03-25 05:07:42 +0000455ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000456{
457 struct ospf_area *new;
458
459 /* Allocate new config_network. */
460 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
461
paul68980082003-03-25 05:07:42 +0000462 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000463
464 new->area_id = area_id;
465
466 new->external_routing = OSPF_AREA_DEFAULT;
467 new->default_cost = 1;
468 new->auth_type = OSPF_AUTH_NULL;
469
470 /* New LSDB init. */
471 new->lsdb = ospf_lsdb_new ();
472
473 /* Self-originated LSAs initialize. */
474 new->router_lsa_self = NULL;
475
476#ifdef HAVE_OPAQUE_LSA
477 ospf_opaque_type10_lsa_init (new);
478#endif /* HAVE_OPAQUE_LSA */
479
480 new->oiflist = list_new ();
481 new->ranges = route_table_init ();
482
483 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000484 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000485
486 return new;
487}
488
489void
490ospf_area_free (struct ospf_area *area)
491{
paul68980082003-03-25 05:07:42 +0000492 struct route_node *rn;
493 struct ospf_lsa *lsa;
494
paul718e3742002-12-13 20:15:29 +0000495 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000496 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
497 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
498 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
499 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
500 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
501 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
502 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
503 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000504
505#ifdef HAVE_NSSA
paul68980082003-03-25 05:07:42 +0000506 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
507 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000508#endif /* HAVE_NSSA */
509#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000510 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
511 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
512 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
513 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000514#endif /* HAVE_OPAQUE_LSA */
515
516 ospf_lsdb_delete_all (area->lsdb);
517 ospf_lsdb_free (area->lsdb);
518
paul718e3742002-12-13 20:15:29 +0000519 ospf_lsa_unlock (area->router_lsa_self);
520
521 route_table_finish (area->ranges);
522 list_delete (area->oiflist);
523
524 if (EXPORT_NAME (area))
525 free (EXPORT_NAME (area));
526
527 if (IMPORT_NAME (area))
528 free (IMPORT_NAME (area));
529
530 /* Cancel timer. */
531 OSPF_TIMER_OFF (area->t_router_lsa_self);
532
533 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000534 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000535
536 XFREE (MTYPE_OSPF_AREA, area);
537}
538
539void
paul68980082003-03-25 05:07:42 +0000540ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000541{
542 struct ospf_area *area;
543
paul68980082003-03-25 05:07:42 +0000544 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000545 if (area &&
546 listcount (area->oiflist) == 0 &&
547 area->ranges->top == NULL &&
548 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
549 area->external_routing == OSPF_AREA_DEFAULT &&
550 area->no_summary == 0 &&
551 area->default_cost == 1 &&
552 EXPORT_NAME (area) == NULL &&
553 IMPORT_NAME (area) == NULL &&
554 area->auth_type == OSPF_AUTH_NULL)
555 {
paul68980082003-03-25 05:07:42 +0000556 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000557 ospf_area_free (area);
558 }
559}
560
561struct ospf_area *
paul68980082003-03-25 05:07:42 +0000562ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000563{
564 struct ospf_area *area;
565
paul68980082003-03-25 05:07:42 +0000566 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000567 if (!area)
568 {
paul68980082003-03-25 05:07:42 +0000569 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000570 area->format = format;
paul68980082003-03-25 05:07:42 +0000571 listnode_add_sort (ospf->areas, area);
572 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000573 }
574
575 return area;
576}
577
578struct ospf_area *
paul68980082003-03-25 05:07:42 +0000579ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000580{
581 struct ospf_area *area;
582 listnode node;
583
paul68980082003-03-25 05:07:42 +0000584 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000585 {
586 area = getdata (node);
587
588 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
589 return area;
590 }
591
592 return NULL;
593}
594
595void
596ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
597{
598 listnode_add (area->oiflist, oi);
599}
600
601void
602ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
603{
604 listnode_delete (area->oiflist, oi);
605}
606
607
608/* Config network statement related functions. */
609struct ospf_network *
610ospf_network_new (struct in_addr area_id, int format)
611{
612 struct ospf_network *new;
613 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
614
615 new->area_id = area_id;
616 new->format = format;
617
618 return new;
619}
620
621void
paul68980082003-03-25 05:07:42 +0000622ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000623{
paul68980082003-03-25 05:07:42 +0000624 ospf_area_check_free (ospf, network->area_id);
625 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000626 XFREE (MTYPE_OSPF_NETWORK, network);
627}
628
629int
630ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
631 struct in_addr area_id)
632{
633 struct ospf_network *network;
634 struct ospf_area *area;
635 struct route_node *rn;
636 struct external_info *ei;
paul147193a2003-04-19 00:31:59 +0000637 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000638
639 rn = route_node_get (ospf->networks, (struct prefix *)p);
640 if (rn->info)
641 {
642 /* There is already same network statement. */
643 route_unlock_node (rn);
644 return 0;
645 }
646
647 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000648 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000649
650 /* Run network config now. */
651 ospf_network_run (ospf, (struct prefix *)p, area);
652
653 /* Update connected redistribute. */
654 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
655 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
656 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
657 rn; rn = route_next (rn))
658 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000659 if (ospf_external_info_find_lsa (ospf, &ei->p))
660 if (!ospf_distribute_check_connected (ospf, ei))
661 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
paul718e3742002-12-13 20:15:29 +0000662 ei->ifindex, ei->nexthop);
663
paul68980082003-03-25 05:07:42 +0000664 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000665
666 return 1;
667}
668
669int
670ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
671 struct in_addr area_id)
672{
673 struct route_node *rn;
674 struct ospf_network *network;
675 struct external_info *ei;
676
677 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
678 if (rn == NULL)
679 return 0;
680
681 network = rn->info;
682 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
683 return 0;
684
paul68980082003-03-25 05:07:42 +0000685 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000686 rn->info = NULL;
687 route_unlock_node (rn);
688
paul68980082003-03-25 05:07:42 +0000689 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000690
691 /* Update connected redistribute. */
692 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
693 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
694 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
695 rn; rn = route_next (rn))
696 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000697 if (!ospf_external_info_find_lsa (ospf, &ei->p))
698 if (ospf_distribute_check_connected (ospf, ei))
699 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000700
701 return 1;
702}
703
paul570f7592003-01-25 06:47:41 +0000704/* Check whether interface matches given network
705 * returns: 1, true. 0, false
706 */
707int
708ospf_network_match_iface(struct connected *co, struct prefix *net)
709{
710 /* Behaviour to match both Cisco where:
711 * iface address lies within network specified -> ospf
712 * and zebra 0.9[2ish-3]:
713 * PtP special case: network specified == iface peer addr -> ospf
714 */
715 return (
716 ((ifc_pointopoint (co) &&
717 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
718 || prefix_match (net, co->address))
719 ? 1 : 0
720 );
721}
722
paul718e3742002-12-13 20:15:29 +0000723void
724ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
725{
726 struct interface *ifp;
727 listnode node;
728
729 /* Schedule Router ID Update. */
730 if (ospf->router_id_static.s_addr == 0)
731 if (ospf->t_router_id_update == NULL)
732 {
paul020709f2003-04-04 02:44:16 +0000733 OSPF_TIMER_ON (ospf->t_router_id_update, ospf_router_id_update_timer,
734 OSPF_ROUTER_ID_UPDATE_DELAY);
paul718e3742002-12-13 20:15:29 +0000735 }
736
737 /* Get target interface. */
paul020709f2003-04-04 02:44:16 +0000738 for (node = listhead (om->iflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000739 {
740 listnode cn;
741
742 if ((ifp = getdata (node)) == NULL)
743 continue;
744
745 if (memcmp (ifp->name, "VLINK", 5) == 0)
746 continue;
747
748 /* if interface prefix is match specified prefix,
749 then create socket and join multicast group. */
750 for (cn = listhead (ifp->connected); cn; nextnode (cn))
751 {
752 struct connected *co = getdata (cn);
753 struct prefix *addr;
paul800dc102003-03-28 01:51:40 +0000754
paule7b050c2003-04-07 06:38:02 +0000755 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
756 continue;
paul718e3742002-12-13 20:15:29 +0000757
paul00df0c12002-12-13 21:07:36 +0000758 if (ifc_pointopoint (co))
paul718e3742002-12-13 20:15:29 +0000759 addr = co->destination;
760 else
761 addr = co->address;
762
paulcb3f37d2003-02-18 23:26:37 +0000763 if (p->family == co->address->family
paul68980082003-03-25 05:07:42 +0000764 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
paulcb3f37d2003-02-18 23:26:37 +0000765 && ospf_network_match_iface(co,p))
paul570f7592003-01-25 06:47:41 +0000766 {
paul487a5912003-02-19 02:54:57 +0000767 struct ospf_interface *oi;
768 assert(co);
paul718e3742002-12-13 20:15:29 +0000769
paul68980082003-03-25 05:07:42 +0000770 oi = ospf_if_new (ospf, ifp, co->address);
paul718e3742002-12-13 20:15:29 +0000771 oi->connected = co;
772
773 oi->nbr_self->address = *oi->address;
774
775 area->act_ints++;
776 oi->area = area;
777
778 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
779 oi->output_cost = ospf_if_get_output_cost (oi);
780
781 if (area->external_routing != OSPF_AREA_DEFAULT)
782 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
783 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
784
785 /* Add pseudo neighbor. */
786 ospf_nbr_add_self (oi);
787
788 /* Make sure pseudo neighbor's router_id. */
paul68980082003-03-25 05:07:42 +0000789 oi->nbr_self->router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000790 oi->nbr_self->src = oi->address->u.prefix4;
791
792 /* Relate ospf interface to ospf instance. */
paul68980082003-03-25 05:07:42 +0000793 oi->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000794
795 /* update network type as interface flag */
796 /* If network type is specified previously,
797 skip network type setting. */
798 oi->type = IF_DEF_PARAMS (ifp)->type;
799
800 /* Set area flag. */
801 switch (area->external_routing)
802 {
803 case OSPF_AREA_DEFAULT:
804 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
805 break;
806 case OSPF_AREA_STUB:
807 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
808 break;
809#ifdef HAVE_NSSA
810 case OSPF_AREA_NSSA:
811 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
812 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
813 break;
814#endif /* HAVE_NSSA */
815 }
816
817 ospf_area_add_if (oi->area, oi);
818
paul2e3b2e42002-12-13 21:03:13 +0000819 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000820 ospf_if_up (oi);
821
822 break;
823 }
824 }
825 }
826}
827
828void
829ospf_ls_upd_queue_empty (struct ospf_interface *oi)
830{
831 struct route_node *rn;
832 listnode node;
833 list lst;
834 struct ospf_lsa *lsa;
835
836 /* empty ls update queue */
837 for (rn = route_top (oi->ls_upd_queue); rn;
838 rn = route_next (rn))
839 if ((lst = (list) rn->info))
840 {
841 for (node = listhead (lst); node; nextnode (node))
842 if ((lsa = getdata (node)))
843 ospf_lsa_unlock (lsa);
844 list_free (lst);
845 rn->info = NULL;
846 }
847
848 /* remove update event */
849 if (oi->t_ls_upd_event)
850 {
851 thread_cancel (oi->t_ls_upd_event);
852 oi->t_ls_upd_event = NULL;
853 }
854}
855
856void
paul68980082003-03-25 05:07:42 +0000857ospf_if_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000858{
859 struct route_node *rn;
860 listnode node;
861 listnode next;
862 struct ospf_network *network;
863 struct ospf_area *area;
864
paul68980082003-03-25 05:07:42 +0000865 if (ospf != NULL)
paul718e3742002-12-13 20:15:29 +0000866 {
867 /* Update Router ID scheduled. */
paul68980082003-03-25 05:07:42 +0000868 if (ospf->router_id_static.s_addr == 0)
869 if (ospf->t_router_id_update == NULL)
paul718e3742002-12-13 20:15:29 +0000870 {
paul020709f2003-04-04 02:44:16 +0000871 OSPF_TIMER_ON (ospf->t_router_id_update,
872 ospf_router_id_update_timer,
873 OSPF_ROUTER_ID_UPDATE_DELAY);
paul718e3742002-12-13 20:15:29 +0000874 }
875
876 /* Find interfaces that not configured already. */
paul68980082003-03-25 05:07:42 +0000877 for (node = listhead (ospf->oiflist); node; node = next)
paul718e3742002-12-13 20:15:29 +0000878 {
879 int found = 0;
880 struct ospf_interface *oi = getdata (node);
881 struct connected *co = oi->connected;
882
883 next = nextnode (node);
884
885 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
886 continue;
887
paul68980082003-03-25 05:07:42 +0000888 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000889 {
890 if (rn->info == NULL)
891 continue;
892
paul570f7592003-01-25 06:47:41 +0000893 if (ospf_network_match_iface(co,&rn->p))
paul718e3742002-12-13 20:15:29 +0000894 {
895 found = 1;
896 route_unlock_node (rn);
897 break;
898 }
899 }
900
901 if (found == 0)
902 ospf_if_free (oi);
903 }
904
905 /* Run each interface. */
paul68980082003-03-25 05:07:42 +0000906 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000907 if (rn->info != NULL)
908 {
909 network = (struct ospf_network *) rn->info;
paul68980082003-03-25 05:07:42 +0000910 area = ospf_area_get (ospf, network->area_id, network->format);
911 ospf_network_run (ospf, &rn->p, area);
paul718e3742002-12-13 20:15:29 +0000912 }
913 }
914}
915
916void
paul68980082003-03-25 05:07:42 +0000917ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000918{
919 listnode node, next;
920 struct ospf_vl_data *vl_data;
921
paul68980082003-03-25 05:07:42 +0000922 for (node = listhead (ospf->vlinks); node; node = next)
paul718e3742002-12-13 20:15:29 +0000923 {
924 next = node->next;
925 if ((vl_data = getdata (node)) != NULL)
926 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
paul68980082003-03-25 05:07:42 +0000927 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000928 }
929}
930
931
932struct message ospf_area_type_msg[] =
933{
934 { OSPF_AREA_DEFAULT, "Default" },
935 { OSPF_AREA_STUB, "Stub" },
936 { OSPF_AREA_NSSA, "NSSA" },
937};
938int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
939
940void
941ospf_area_type_set (struct ospf_area *area, int type)
942{
943 listnode node;
944 struct ospf_interface *oi;
945
946 if (area->external_routing == type)
947 {
948 if (IS_DEBUG_OSPF_EVENT)
949 zlog_info ("Area[%s]: Types are the same, ignored.",
950 inet_ntoa (area->area_id));
951 return;
952 }
953
954 area->external_routing = type;
955
956 if (IS_DEBUG_OSPF_EVENT)
957 zlog_info ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
958 LOOKUP (ospf_area_type_msg, type));
959
960 switch (area->external_routing)
961 {
962 case OSPF_AREA_DEFAULT:
963 for (node = listhead (area->oiflist); node; nextnode (node))
964 if ((oi = getdata (node)) != NULL)
965 if (oi->nbr_self != NULL)
966 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
967 break;
968 case OSPF_AREA_STUB:
969 for (node = listhead (area->oiflist); node; nextnode (node))
970 if ((oi = getdata (node)) != NULL)
971 if (oi->nbr_self != NULL)
972 {
973 if (IS_DEBUG_OSPF_EVENT)
974 zlog_info ("setting options on %s accordingly", IF_NAME (oi));
975 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
976 if (IS_DEBUG_OSPF_EVENT)
977 zlog_info ("options set on %s: %x",
978 IF_NAME (oi), OPTIONS (oi));
979 }
980 break;
981 case OSPF_AREA_NSSA:
982#ifdef HAVE_NSSA
983 for (node = listhead (area->oiflist); node; nextnode (node))
984 if ((oi = getdata (node)) != NULL)
985 if (oi->nbr_self != NULL)
986 {
987 zlog_info ("setting nssa options on %s accordingly", IF_NAME (oi));
988 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
989 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
990 zlog_info ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
991 }
992#endif /* HAVE_NSSA */
993 break;
994 default:
995 break;
996 }
997
998 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +0000999 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +00001000}
1001
1002int
paul68980082003-03-25 05:07:42 +00001003ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +00001004{
1005 if (area->shortcut_configured == mode)
1006 return 0;
1007
1008 area->shortcut_configured = mode;
1009 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001010 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001011
paul68980082003-03-25 05:07:42 +00001012 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001013
1014 return 1;
1015}
1016
1017int
paul68980082003-03-25 05:07:42 +00001018ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001019{
1020 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
1021 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +00001022 ospf_area_check_free (ospf, area->area_id);
1023 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001024
1025 return 1;
1026}
1027
1028int
1029ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1030{
1031 struct ospf_vl_data *vl;
1032 listnode node;
1033 int count = 0;
1034
1035 for (node = listhead (ospf->vlinks); node; nextnode (node))
1036 {
1037 vl = getdata (node);
1038 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1039 count++;
1040 }
1041
1042 return count;
1043}
1044
1045int
1046ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1047{
1048 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001049 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001050
paul68980082003-03-25 05:07:42 +00001051 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001052 if (ospf_area_vlink_count (ospf, area))
1053 return 0;
1054
1055 if (area->external_routing != OSPF_AREA_STUB)
1056 ospf_area_type_set (area, OSPF_AREA_STUB);
1057
1058 return 1;
1059}
1060
1061int
1062ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1063{
1064 struct ospf_area *area;
1065
paul68980082003-03-25 05:07:42 +00001066 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001067 if (area == NULL)
1068 return 1;
1069
1070 if (area->external_routing == OSPF_AREA_STUB)
1071 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1072
paul68980082003-03-25 05:07:42 +00001073 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001074
1075 return 1;
1076}
1077
1078int
1079ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1080{
1081 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001082 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001083
paul68980082003-03-25 05:07:42 +00001084 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001085 area->no_summary = 1;
1086
1087 return 1;
1088}
1089
1090int
1091ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1092{
1093 struct ospf_area *area;
1094
paul68980082003-03-25 05:07:42 +00001095 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001096 if (area == NULL)
1097 return 0;
1098
1099 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001100 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001101
1102 return 1;
1103}
1104
1105int
1106ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1107{
1108 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001109 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +00001110
paul68980082003-03-25 05:07:42 +00001111 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001112 if (ospf_area_vlink_count (ospf, area))
1113 return 0;
1114
1115 if (area->external_routing != OSPF_AREA_NSSA)
1116 {
1117 ospf_area_type_set (area, OSPF_AREA_NSSA);
1118 ospf->anyNSSA++;
1119 }
1120
1121 return 1;
1122}
1123
1124int
1125ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1126{
1127 struct ospf_area *area;
1128
paul68980082003-03-25 05:07:42 +00001129 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001130 if (area == NULL)
1131 return 0;
1132
1133 if (area->external_routing == OSPF_AREA_NSSA)
1134 {
1135 ospf->anyNSSA--;
1136 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1137 }
1138
paul68980082003-03-25 05:07:42 +00001139 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001140
1141 return 1;
1142}
1143
1144int
1145ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1146 int role)
1147{
1148 struct ospf_area *area;
1149
paul68980082003-03-25 05:07:42 +00001150 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001151 if (area == NULL)
1152 return 0;
1153
1154 area->NSSATranslator = role;
1155
1156 return 1;
1157}
1158
1159int
1160ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1161 struct in_addr area_id)
1162{
1163 struct ospf_area *area;
1164
paul68980082003-03-25 05:07:42 +00001165 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001166 if (area == NULL)
1167 return 0;
1168
1169 area->NSSATranslator = OSPF_NSSA_ROLE_CANDIDATE;
1170
paul68980082003-03-25 05:07:42 +00001171 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001172
1173 return 1;
1174}
1175
1176int
paul68980082003-03-25 05:07:42 +00001177ospf_area_export_list_set (struct ospf *ospf,
1178 struct ospf_area *area, char *list_name)
paul718e3742002-12-13 20:15:29 +00001179{
1180 struct access_list *list;
1181 list = access_list_lookup (AFI_IP, list_name);
1182
1183 EXPORT_LIST (area) = list;
1184
1185 if (EXPORT_NAME (area))
1186 free (EXPORT_NAME (area));
1187
1188 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001189 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001190
1191 return 1;
1192}
1193
1194int
paul68980082003-03-25 05:07:42 +00001195ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001196{
1197
1198 EXPORT_LIST (area) = 0;
1199
1200 if (EXPORT_NAME (area))
1201 free (EXPORT_NAME (area));
1202
1203 EXPORT_NAME (area) = NULL;
1204
paul68980082003-03-25 05:07:42 +00001205 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001206
paul68980082003-03-25 05:07:42 +00001207 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001208
1209 return 1;
1210}
1211
1212int
paul68980082003-03-25 05:07:42 +00001213ospf_area_import_list_set (struct ospf *ospf,
1214 struct ospf_area *area, char *name)
paul718e3742002-12-13 20:15:29 +00001215{
1216 struct access_list *list;
1217 list = access_list_lookup (AFI_IP, name);
1218
1219 IMPORT_LIST (area) = list;
1220
1221 if (IMPORT_NAME (area))
1222 free (IMPORT_NAME (area));
1223
1224 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001225 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001226
1227 return 1;
1228}
1229
1230int
paul68980082003-03-25 05:07:42 +00001231ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001232{
1233 IMPORT_LIST (area) = 0;
1234
1235 if (IMPORT_NAME (area))
1236 free (IMPORT_NAME (area));
1237
1238 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001239 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001240
paul68980082003-03-25 05:07:42 +00001241 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001242
1243 return 1;
1244}
1245
1246int
1247ospf_timers_spf_set (struct ospf *ospf, u_int32_t delay, u_int32_t hold)
1248{
1249 ospf->spf_delay = delay;
1250 ospf->spf_holdtime = hold;
1251
1252 return 1;
1253}
1254
1255int
1256ospf_timers_spf_unset (struct ospf *ospf)
1257{
1258 ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT;
1259 ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
1260
1261 return 1;
1262}
1263
1264int
1265ospf_timers_refresh_set (struct ospf *ospf, int interval)
1266{
1267 int time_left;
1268
1269 if (ospf->lsa_refresh_interval == interval)
1270 return 1;
1271
1272 time_left = ospf->lsa_refresh_interval -
1273 (time (NULL) - ospf->lsa_refresher_started);
1274
1275 if (time_left > interval)
1276 {
1277 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1278 ospf->t_lsa_refresher =
1279 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1280 }
1281 ospf->lsa_refresh_interval = interval;
1282
1283 return 1;
1284}
1285
1286int
1287ospf_timers_refresh_unset (struct ospf *ospf)
1288{
1289 int time_left;
1290
1291 time_left = ospf->lsa_refresh_interval -
1292 (time (NULL) - ospf->lsa_refresher_started);
1293
1294 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1295 {
1296 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1297 ospf->t_lsa_refresher =
1298 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1299 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1300 }
1301
1302 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1303
1304 return 1;
1305}
1306
1307
1308struct ospf_nbr_nbma *
1309ospf_nbr_nbma_new ()
1310{
1311 struct ospf_nbr_nbma *nbr_nbma;
1312
1313 nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1314 sizeof (struct ospf_nbr_nbma));
1315 memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));
1316
1317 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1318 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1319
1320 return nbr_nbma;
1321}
1322
1323void
1324ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1325{
1326 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1327}
1328
1329void
1330ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1331{
1332 struct route_node *rn;
1333 struct prefix_ipv4 p;
1334
1335 p.family = AF_INET;
1336 p.prefix = nbr_nbma->addr;
1337 p.prefixlen = IPV4_MAX_BITLEN;
1338
1339 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1340 if (rn)
1341 {
1342 ospf_nbr_nbma_free (rn->info);
1343 rn->info = NULL;
1344 route_unlock_node (rn);
1345 route_unlock_node (rn);
1346 }
1347}
1348
1349void
1350ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1351{
1352 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1353
1354 if (nbr_nbma->nbr)
1355 {
1356 nbr_nbma->nbr->nbr_nbma = NULL;
1357 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1358 }
1359
1360 if (nbr_nbma->oi)
1361 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1362}
1363
1364void
1365ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1366 struct ospf_interface *oi)
1367{
1368 struct ospf_neighbor *nbr;
1369 struct route_node *rn;
1370 struct prefix p;
1371
1372 if (oi->type != OSPF_IFTYPE_NBMA)
1373 return;
1374
1375 if (nbr_nbma->nbr != NULL)
1376 return;
1377
1378 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1379 return;
1380
1381 nbr_nbma->oi = oi;
1382 listnode_add (oi->nbr_nbma, nbr_nbma);
1383
1384 /* Get neighbor information from table. */
1385 p.family = AF_INET;
1386 p.prefixlen = IPV4_MAX_BITLEN;
1387 p.u.prefix4 = nbr_nbma->addr;
1388
1389 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1390 if (rn->info)
1391 {
1392 nbr = rn->info;
1393 nbr->nbr_nbma = nbr_nbma;
1394 nbr_nbma->nbr = nbr;
1395
1396 route_unlock_node (rn);
1397 }
1398 else
1399 {
1400 nbr = rn->info = ospf_nbr_new (oi);
1401 nbr->state = NSM_Down;
1402 nbr->src = nbr_nbma->addr;
1403 nbr->nbr_nbma = nbr_nbma;
1404 nbr->priority = nbr_nbma->priority;
1405 nbr->address = p;
1406
1407 nbr_nbma->nbr = nbr;
1408
1409 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1410 }
1411}
1412
1413void
paul68980082003-03-25 05:07:42 +00001414ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001415{
1416 struct ospf_nbr_nbma *nbr_nbma;
1417 struct route_node *rn;
1418 struct prefix_ipv4 p;
1419
1420 if (oi->type != OSPF_IFTYPE_NBMA)
1421 return;
1422
paul68980082003-03-25 05:07:42 +00001423 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001424 if ((nbr_nbma = rn->info))
1425 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1426 {
1427 p.family = AF_INET;
1428 p.prefix = nbr_nbma->addr;
1429 p.prefixlen = IPV4_MAX_BITLEN;
1430
1431 if (prefix_match (oi->address, (struct prefix *)&p))
1432 ospf_nbr_nbma_add (nbr_nbma, oi);
1433 }
1434}
1435
1436struct ospf_nbr_nbma *
1437ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1438{
1439 struct route_node *rn;
1440 struct prefix_ipv4 p;
1441
1442 p.family = AF_INET;
1443 p.prefix = nbr_addr;
1444 p.prefixlen = IPV4_MAX_BITLEN;
1445
1446 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1447 if (rn)
1448 {
1449 route_unlock_node (rn);
1450 return rn->info;
1451 }
1452 return NULL;
1453}
1454
1455struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001456ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001457{
1458#if 0
1459 struct ospf_nbr_nbma *nbr_nbma;
1460 listnode node;
1461#endif
1462
paul68980082003-03-25 05:07:42 +00001463 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001464 return NULL;
1465
1466#if 0
paul68980082003-03-25 05:07:42 +00001467 for (node = listhead (ospf->nbr_nbma); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001468 {
1469 nbr_nbma = getdata (node);
1470
1471 if (first)
1472 {
1473 *addr = nbr_nbma->addr;
1474 return nbr_nbma;
1475 }
1476 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1477 {
1478 *addr = nbr_nbma->addr;
1479 return nbr_nbma;
1480 }
1481 }
1482#endif
1483 return NULL;
1484}
1485
1486int
1487ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1488{
1489 struct ospf_nbr_nbma *nbr_nbma;
1490 struct ospf_interface *oi;
1491 struct prefix_ipv4 p;
1492 struct route_node *rn;
1493 listnode node;
1494
1495 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1496 if (nbr_nbma)
1497 return 0;
1498
1499 nbr_nbma = ospf_nbr_nbma_new ();
1500 nbr_nbma->addr = nbr_addr;
1501
1502 p.family = AF_INET;
1503 p.prefix = nbr_addr;
1504 p.prefixlen = IPV4_MAX_BITLEN;
1505
1506 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1507 rn->info = nbr_nbma;
1508
1509 for (node = listhead (ospf->oiflist); node; nextnode (node))
1510 {
1511 oi = getdata (node);
1512 if (oi->type == OSPF_IFTYPE_NBMA)
1513 if (prefix_match (oi->address, (struct prefix *)&p))
1514 {
1515 ospf_nbr_nbma_add (nbr_nbma, oi);
1516 break;
1517 }
1518 }
1519
1520 return 1;
1521}
1522
1523int
1524ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1525{
1526 struct ospf_nbr_nbma *nbr_nbma;
1527
1528 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1529 if (nbr_nbma == NULL)
1530 return 0;
1531
1532 ospf_nbr_nbma_down (nbr_nbma);
1533 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1534
1535 return 1;
1536}
1537
1538int
1539ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1540 u_char priority)
1541{
1542 struct ospf_nbr_nbma *nbr_nbma;
1543
1544 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1545 if (nbr_nbma == NULL)
1546 return 0;
1547
1548 if (nbr_nbma->priority != priority)
1549 nbr_nbma->priority = priority;
1550
1551 return 1;
1552}
1553
1554int
1555ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1556{
1557 struct ospf_nbr_nbma *nbr_nbma;
1558
1559 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1560 if (nbr_nbma == NULL)
1561 return 0;
1562
1563 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1564 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1565
1566 return 1;
1567}
1568
1569int
1570ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
1571 int interval)
1572{
1573 struct ospf_nbr_nbma *nbr_nbma;
1574
1575 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1576 if (nbr_nbma == NULL)
1577 return 0;
1578
1579 if (nbr_nbma->v_poll != interval)
1580 {
1581 nbr_nbma->v_poll = interval;
1582 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1583 {
1584 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1585 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1586 nbr_nbma->v_poll);
1587 }
1588 }
1589
1590 return 1;
1591}
1592
1593int
1594ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1595{
1596 struct ospf_nbr_nbma *nbr_nbma;
1597
1598 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1599 if (nbr_nbma == NULL)
1600 return 0;
1601
1602 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1603 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1604
1605 return 1;
1606}
1607
1608
1609void
1610ospf_prefix_list_update (struct prefix_list *plist)
1611{
paul020709f2003-04-04 02:44:16 +00001612 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001613 struct ospf_area *area;
1614 listnode node;
1615 int abr_inv = 0;
1616
1617 /* If OSPF instatnce does not exist, return right now. */
paul020709f2003-04-04 02:44:16 +00001618 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001619 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001620 return;
1621
1622 /* Update Area prefix-list. */
paul68980082003-03-25 05:07:42 +00001623 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001624 {
1625 area = getdata (node);
1626
1627 /* Update filter-list in. */
1628 if (PREFIX_NAME_IN (area))
1629 if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
1630 {
1631 PREFIX_LIST_IN (area) =
1632 prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
1633 abr_inv++;
1634 }
1635
1636 /* Update filter-list out. */
1637 if (PREFIX_NAME_OUT (area))
1638 if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
1639 {
1640 PREFIX_LIST_IN (area) =
1641 prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
1642 abr_inv++;
1643 }
1644 }
1645
1646 /* Schedule ABR tasks. */
paul020709f2003-04-04 02:44:16 +00001647 if (IS_OSPF_ABR (ospf) && abr_inv)
paul68980082003-03-25 05:07:42 +00001648 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001649}
1650
1651void
paul020709f2003-04-04 02:44:16 +00001652ospf_master_init ()
1653{
1654 memset (&ospf_master, 0, sizeof (struct ospf_master));
1655
1656 om = &ospf_master;
1657 om->ospf = list_new ();
1658 om->master = thread_master_create ();
1659 om->start_time = time (NULL);
1660}
1661
1662void
paul718e3742002-12-13 20:15:29 +00001663ospf_init ()
1664{
paul718e3742002-12-13 20:15:29 +00001665 prefix_list_add_hook (ospf_prefix_list_update);
1666 prefix_list_delete_hook (ospf_prefix_list_update);
1667}