blob: 8d1b786821e1135bb41690e0f61a3aec300f53c4 [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
55/* OSPF instance top. */
56struct ospf *ospf_top;
57
58extern struct zclient *zclient;
59
60
paul68980082003-03-25 05:07:42 +000061void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
62void ospf_network_free (struct ospf *, struct ospf_network *);
paul718e3742002-12-13 20:15:29 +000063void ospf_area_free (struct ospf_area *);
64void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
65
66/* Get Router ID from ospf interface list. */
67struct in_addr
68ospf_router_id_get (list if_list)
69{
70 listnode node;
71 struct in_addr router_id;
72
73 memset (&router_id, 0, sizeof (struct in_addr));
74
75 for (node = listhead (if_list); node; nextnode (node))
76 {
77 struct ospf_interface *oi = getdata (node);
78
79 if (!if_is_up (oi->ifp) ||
80 OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
81 continue;
82
83 /* Ignore virtual link interface. */
84 if (oi->type != OSPF_IFTYPE_VIRTUALLINK &&
85 oi->type != OSPF_IFTYPE_LOOPBACK)
86 if (IPV4_ADDR_CMP (&router_id, &oi->address->u.prefix4) < 0)
87 router_id = oi->address->u.prefix4;
88 }
89
90 return router_id;
91}
92
93#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
94
95void
paul68980082003-03-25 05:07:42 +000096ospf_router_id_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +000097{
paul718e3742002-12-13 20:15:29 +000098 struct in_addr router_id, router_id_old;
paul68980082003-03-25 05:07:42 +000099 listnode node;
paul718e3742002-12-13 20:15:29 +0000100
101 if (IS_DEBUG_OSPF_EVENT)
paul68980082003-03-25 05:07:42 +0000102 zlog_info ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000103
paul68980082003-03-25 05:07:42 +0000104 router_id_old = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000105
paul68980082003-03-25 05:07:42 +0000106 if (ospf->router_id_static.s_addr != 0)
107 router_id = ospf->router_id_static;
paul718e3742002-12-13 20:15:29 +0000108 else
paul68980082003-03-25 05:07:42 +0000109 router_id = ospf_router_id_get (ospf->oiflist);
paul718e3742002-12-13 20:15:29 +0000110
paul68980082003-03-25 05:07:42 +0000111 ospf->router_id = router_id;
paul718e3742002-12-13 20:15:29 +0000112
113 if (IS_DEBUG_OSPF_EVENT)
paul68980082003-03-25 05:07:42 +0000114 zlog_info ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
paul718e3742002-12-13 20:15:29 +0000115
116 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
117 {
paul68980082003-03-25 05:07:42 +0000118 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000119 {
120 struct ospf_interface *oi = getdata (node);
121
122 /* Update self-neighbor's router_id. */
123 oi->nbr_self->router_id = router_id;
124 }
125
126 /* If AS-external-LSA is queued, then flush those LSAs. */
paul68980082003-03-25 05:07:42 +0000127 if (router_id_old.s_addr == 0 && ospf->external_origin)
paul718e3742002-12-13 20:15:29 +0000128 {
129 int type;
130 /* Originate each redistributed external route. */
131 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul68980082003-03-25 05:07:42 +0000132 if (ospf->external_origin & (1 << type))
paul718e3742002-12-13 20:15:29 +0000133 thread_add_event (master, ospf_external_lsa_originate_timer,
paul68980082003-03-25 05:07:42 +0000134 ospf, type);
paul718e3742002-12-13 20:15:29 +0000135 /* Originate Deafult. */
paul68980082003-03-25 05:07:42 +0000136 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
paul718e3742002-12-13 20:15:29 +0000137 thread_add_event (master, ospf_default_originate_timer,
paul68980082003-03-25 05:07:42 +0000138 &ospf->default_originate, 0);
paul718e3742002-12-13 20:15:29 +0000139
paul68980082003-03-25 05:07:42 +0000140 ospf->external_origin = 0;
paul718e3742002-12-13 20:15:29 +0000141 }
142
paul68980082003-03-25 05:07:42 +0000143 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000144 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
145 }
146}
147
148int
149ospf_router_id_update_timer (struct thread *thread)
150{
paul68980082003-03-25 05:07:42 +0000151 struct ospf *ospf = ospf_top;
152
paul718e3742002-12-13 20:15:29 +0000153 if (IS_DEBUG_OSPF_EVENT)
154 zlog_info ("Router-ID: Update timer fired!");
155
paul68980082003-03-25 05:07:42 +0000156 ospf->t_router_id_update = NULL;
157 ospf_router_id_update (ospf);
paul718e3742002-12-13 20:15:29 +0000158
159 return 0;
160}
161
162/* For OSPF area sort by area id. */
163int
164ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
165{
166 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
167 return 1;
168 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
169 return -1;
170 return 0;
171}
172
173/* Allocate new ospf structure. */
174struct ospf *
175ospf_new ()
176{
177 int i;
178
179 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
180
181 new->router_id.s_addr = htonl (0);
182 new->router_id_static.s_addr = htonl (0);
183
184 new->abr_type = OSPF_ABR_STAND;
185 new->iflist = iflist;
186 new->oiflist = list_new ();
187 new->vlinks = list_new ();
188 new->areas = list_new ();
189 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
190 new->networks = route_table_init ();
191 new->nbr_nbma = route_table_init ();
192
193 new->lsdb = ospf_lsdb_new ();
194
195 new->default_originate = DEFAULT_ORIGINATE_NONE;
196
197 new->new_external_route = route_table_init ();
198 new->old_external_route = route_table_init ();
199 new->external_lsas = route_table_init ();
200
201 /* Distribute parameter init. */
202 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
203 {
204 new->dmetric[i].type = -1;
205 new->dmetric[i].value = -1;
206 }
207 new->default_metric = -1;
208 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
209
210 /* SPF timer value init. */
211 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
212 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
213
214 /* MaxAge init. */
215 new->maxage_lsa = list_new ();
216 new->t_maxage_walker =
217 thread_add_timer (master, ospf_lsa_maxage_walker,
paul68980082003-03-25 05:07:42 +0000218 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +0000219
220 /* Distance table init. */
221 new->distance_table = route_table_init ();
222
223 new->lsa_refresh_queue.index = 0;
224 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
225 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
226 new, new->lsa_refresh_interval);
227 new->lsa_refresher_started = time (NULL);
228
229 new->fd = ospf_sock_init ();
230 if (new->fd >= 0)
231 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
232 new->oi_write_q = list_new ();
233
234 return new;
235}
236
237struct ospf *
238ospf_get ()
239{
paul68980082003-03-25 05:07:42 +0000240 struct ospf *ospf = ospf_top;
paul718e3742002-12-13 20:15:29 +0000241
paul68980082003-03-25 05:07:42 +0000242 if (ospf != NULL)
243 return ospf;
paul718e3742002-12-13 20:15:29 +0000244
paul68980082003-03-25 05:07:42 +0000245 ospf = ospf_new ();
246
247 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
paul68980082003-03-25 05:07:42 +0000251 ospf_opaque_type11_lsa_init (ospf);
paul718e3742002-12-13 20:15:29 +0000252#endif /* HAVE_OPAQUE_LSA */
253
paul68980082003-03-25 05:07:42 +0000254 ospf_top = ospf;
255
256 return ospf;
paul718e3742002-12-13 20:15:29 +0000257}
258
259void
260ospf_finish (struct ospf *ospf)
261{
262 struct route_node *rn;
263 struct ospf_nbr_nbma *nbr_nbma;
paul68980082003-03-25 05:07:42 +0000264 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000265 listnode node;
266 int i;
267
268#ifdef HAVE_OPAQUE_LSA
269 ospf_opaque_type11_lsa_term (ospf);
270#endif /* HAVE_OPAQUE_LSA */
271
272 /* Unredister redistribution */
273 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
274 ospf_redistribute_unset (i);
275
276 for (node = listhead (ospf->areas); node;)
277 {
278 struct ospf_area *area = getdata (node);
279 nextnode (node);
280
paul68980082003-03-25 05:07:42 +0000281 ospf_remove_vls_through_area (ospf, area);
paul718e3742002-12-13 20:15:29 +0000282 }
283
284 for (node = listhead (ospf->vlinks); node; )
285 {
286 struct ospf_vl_data *vl_data = node->data;
287 nextnode (node);
288
paul68980082003-03-25 05:07:42 +0000289 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000290 }
291
292 list_delete (ospf->vlinks);
293
294 /* Reset interface. */
295 for (node = listhead (ospf->oiflist); node;)
296 {
297 struct ospf_interface *oi = getdata (node);
298 nextnode (node);
299
300 if (oi)
301 ospf_if_free (oi);
302 }
303
304 /* Clear static neighbors */
305 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
306 if ((nbr_nbma = rn->info))
307 {
308 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
309
310 if (nbr_nbma->nbr)
311 {
312 nbr_nbma->nbr->nbr_nbma = NULL;
313 nbr_nbma->nbr = NULL;
314 }
315
316 if (nbr_nbma->oi)
317 {
318 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
319 nbr_nbma->oi = NULL;
320 }
321
322 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
323 }
324
325 route_table_finish (ospf->nbr_nbma);
326
327 /* Clear networks and Areas. */
328 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
329 {
330 struct ospf_network *network;
331
332 if ((network = rn->info) != NULL)
333 {
paul68980082003-03-25 05:07:42 +0000334 ospf_network_free (ospf, network);
paul718e3742002-12-13 20:15:29 +0000335 rn->info = NULL;
336 route_unlock_node (rn);
337 }
338 }
339
340 for (node = listhead (ospf->areas); node;)
341 {
342 struct ospf_area *area = getdata (node);
343 nextnode (node);
344
345 listnode_delete (ospf->areas, area);
346 ospf_area_free (area);
347 }
348
349 /* Cancel all timers. */
350 OSPF_TIMER_OFF (ospf->t_external_lsa);
351 OSPF_TIMER_OFF (ospf->t_router_id_update);
352 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
353 OSPF_TIMER_OFF (ospf->t_spf_calc);
354 OSPF_TIMER_OFF (ospf->t_ase_calc);
355 OSPF_TIMER_OFF (ospf->t_maxage);
356 OSPF_TIMER_OFF (ospf->t_maxage_walker);
357 OSPF_TIMER_OFF (ospf->t_abr_task);
358 OSPF_TIMER_OFF (ospf->t_distribute_update);
359 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
360 OSPF_TIMER_OFF (ospf->t_read);
361 OSPF_TIMER_OFF (ospf->t_write);
362
363 close (ospf->fd);
364
365#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000366 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
367 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000368#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +0000369 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
370 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
371
paul718e3742002-12-13 20:15:29 +0000372 ospf_lsdb_delete_all (ospf->lsdb);
373 ospf_lsdb_free (ospf->lsdb);
374
375 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
376 ospf_lsa_unlock (getdata (node));
377
378 list_delete (ospf->maxage_lsa);
379
380 if (ospf->old_table)
381 ospf_route_table_free (ospf->old_table);
382 if (ospf->new_table)
383 {
384 ospf_route_delete (ospf->new_table);
385 ospf_route_table_free (ospf->new_table);
386 }
387 if (ospf->old_rtrs)
388 ospf_rtrs_free (ospf->old_rtrs);
389 if (ospf->new_rtrs)
390 ospf_rtrs_free (ospf->new_rtrs);
391 if (ospf->new_external_route)
392 {
393 ospf_route_delete (ospf->new_external_route);
394 ospf_route_table_free (ospf->new_external_route);
395 }
396 if (ospf->old_external_route)
397 {
398 ospf_route_delete (ospf->old_external_route);
399 ospf_route_table_free (ospf->old_external_route);
400 }
401 if (ospf->external_lsas)
402 {
403 ospf_ase_external_lsas_finish (ospf->external_lsas);
404 }
405
406 list_delete (ospf->areas);
407
408 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
409 if (EXTERNAL_INFO (i) != NULL)
410 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
411 {
412 if (rn->info == NULL)
413 continue;
414
415 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
416 rn->info = NULL;
417 route_unlock_node (rn);
418 }
419
paul68980082003-03-25 05:07:42 +0000420 ospf_distance_reset (ospf);
paul718e3742002-12-13 20:15:29 +0000421 route_table_finish (ospf->distance_table);
422
423 XFREE (MTYPE_OSPF_TOP, ospf);
424
425 ospf_top = NULL;
426}
427
428
429/* allocate new OSPF Area object */
430struct ospf_area *
paul68980082003-03-25 05:07:42 +0000431ospf_area_new (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000432{
433 struct ospf_area *new;
434
435 /* Allocate new config_network. */
436 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
437
paul68980082003-03-25 05:07:42 +0000438 new->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000439
440 new->area_id = area_id;
441
442 new->external_routing = OSPF_AREA_DEFAULT;
443 new->default_cost = 1;
444 new->auth_type = OSPF_AUTH_NULL;
445
446 /* New LSDB init. */
447 new->lsdb = ospf_lsdb_new ();
448
449 /* Self-originated LSAs initialize. */
450 new->router_lsa_self = NULL;
451
452#ifdef HAVE_OPAQUE_LSA
453 ospf_opaque_type10_lsa_init (new);
454#endif /* HAVE_OPAQUE_LSA */
455
456 new->oiflist = list_new ();
457 new->ranges = route_table_init ();
458
459 if (area_id.s_addr == OSPF_AREA_BACKBONE)
paul68980082003-03-25 05:07:42 +0000460 ospf->backbone = new;
paul718e3742002-12-13 20:15:29 +0000461
462 return new;
463}
464
465void
466ospf_area_free (struct ospf_area *area)
467{
paul68980082003-03-25 05:07:42 +0000468 struct route_node *rn;
469 struct ospf_lsa *lsa;
470
paul718e3742002-12-13 20:15:29 +0000471 /* Free LSDBs. */
paul68980082003-03-25 05:07:42 +0000472 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
473 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
474 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
475 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
476 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
477 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
478 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
479 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000480
481#ifdef HAVE_NSSA
paul68980082003-03-25 05:07:42 +0000482 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
483 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000484#endif /* HAVE_NSSA */
485#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000486 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
487 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
488 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
489 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +0000490#endif /* HAVE_OPAQUE_LSA */
491
492 ospf_lsdb_delete_all (area->lsdb);
493 ospf_lsdb_free (area->lsdb);
494
paul718e3742002-12-13 20:15:29 +0000495 ospf_lsa_unlock (area->router_lsa_self);
496
497 route_table_finish (area->ranges);
498 list_delete (area->oiflist);
499
500 if (EXPORT_NAME (area))
501 free (EXPORT_NAME (area));
502
503 if (IMPORT_NAME (area))
504 free (IMPORT_NAME (area));
505
506 /* Cancel timer. */
507 OSPF_TIMER_OFF (area->t_router_lsa_self);
508
509 if (OSPF_IS_AREA_BACKBONE (area))
paul68980082003-03-25 05:07:42 +0000510 area->ospf->backbone = NULL;
paul718e3742002-12-13 20:15:29 +0000511
512 XFREE (MTYPE_OSPF_AREA, area);
513}
514
515void
paul68980082003-03-25 05:07:42 +0000516ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000517{
518 struct ospf_area *area;
519
paul68980082003-03-25 05:07:42 +0000520 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000521 if (area &&
522 listcount (area->oiflist) == 0 &&
523 area->ranges->top == NULL &&
524 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
525 area->external_routing == OSPF_AREA_DEFAULT &&
526 area->no_summary == 0 &&
527 area->default_cost == 1 &&
528 EXPORT_NAME (area) == NULL &&
529 IMPORT_NAME (area) == NULL &&
530 area->auth_type == OSPF_AUTH_NULL)
531 {
paul68980082003-03-25 05:07:42 +0000532 listnode_delete (ospf->areas, area);
paul718e3742002-12-13 20:15:29 +0000533 ospf_area_free (area);
534 }
535}
536
537struct ospf_area *
paul68980082003-03-25 05:07:42 +0000538ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
paul718e3742002-12-13 20:15:29 +0000539{
540 struct ospf_area *area;
541
paul68980082003-03-25 05:07:42 +0000542 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000543 if (!area)
544 {
paul68980082003-03-25 05:07:42 +0000545 area = ospf_area_new (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000546 area->format = format;
paul68980082003-03-25 05:07:42 +0000547 listnode_add_sort (ospf->areas, area);
548 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +0000549 }
550
551 return area;
552}
553
554struct ospf_area *
paul68980082003-03-25 05:07:42 +0000555ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
paul718e3742002-12-13 20:15:29 +0000556{
557 struct ospf_area *area;
558 listnode node;
559
paul68980082003-03-25 05:07:42 +0000560 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000561 {
562 area = getdata (node);
563
564 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
565 return area;
566 }
567
568 return NULL;
569}
570
571void
572ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
573{
574 listnode_add (area->oiflist, oi);
575}
576
577void
578ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
579{
580 listnode_delete (area->oiflist, oi);
581}
582
583
584/* Config network statement related functions. */
585struct ospf_network *
586ospf_network_new (struct in_addr area_id, int format)
587{
588 struct ospf_network *new;
589 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
590
591 new->area_id = area_id;
592 new->format = format;
593
594 return new;
595}
596
597void
paul68980082003-03-25 05:07:42 +0000598ospf_network_free (struct ospf *ospf, struct ospf_network *network)
paul718e3742002-12-13 20:15:29 +0000599{
paul68980082003-03-25 05:07:42 +0000600 ospf_area_check_free (ospf, network->area_id);
601 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000602 XFREE (MTYPE_OSPF_NETWORK, network);
603}
604
605int
606ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
607 struct in_addr area_id)
608{
609 struct ospf_network *network;
610 struct ospf_area *area;
611 struct route_node *rn;
612 struct external_info *ei;
613 int ret = OSPF_AREA_ID_FORMAT_DECIMAL;
614
615 rn = route_node_get (ospf->networks, (struct prefix *)p);
616 if (rn->info)
617 {
618 /* There is already same network statement. */
619 route_unlock_node (rn);
620 return 0;
621 }
622
623 rn->info = network = ospf_network_new (area_id, ret);
paul68980082003-03-25 05:07:42 +0000624 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000625
626 /* Run network config now. */
627 ospf_network_run (ospf, (struct prefix *)p, area);
628
629 /* Update connected redistribute. */
630 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
631 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
632 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
633 rn; rn = route_next (rn))
634 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000635 if (ospf_external_info_find_lsa (ospf, &ei->p))
636 if (!ospf_distribute_check_connected (ospf, ei))
637 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
paul718e3742002-12-13 20:15:29 +0000638 ei->ifindex, ei->nexthop);
639
paul68980082003-03-25 05:07:42 +0000640 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000641
642 return 1;
643}
644
645int
646ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
647 struct in_addr area_id)
648{
649 struct route_node *rn;
650 struct ospf_network *network;
651 struct external_info *ei;
652
653 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
654 if (rn == NULL)
655 return 0;
656
657 network = rn->info;
658 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
659 return 0;
660
paul68980082003-03-25 05:07:42 +0000661 ospf_network_free (ospf, rn->info);
paul718e3742002-12-13 20:15:29 +0000662 rn->info = NULL;
663 route_unlock_node (rn);
664
paul68980082003-03-25 05:07:42 +0000665 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000666
667 /* Update connected redistribute. */
668 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
669 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
670 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
671 rn; rn = route_next (rn))
672 if ((ei = rn->info) != NULL)
paul68980082003-03-25 05:07:42 +0000673 if (!ospf_external_info_find_lsa (ospf, &ei->p))
674 if (ospf_distribute_check_connected (ospf, ei))
675 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000676
677 return 1;
678}
679
paul570f7592003-01-25 06:47:41 +0000680/* Check whether interface matches given network
681 * returns: 1, true. 0, false
682 */
683int
684ospf_network_match_iface(struct connected *co, struct prefix *net)
685{
686 /* Behaviour to match both Cisco where:
687 * iface address lies within network specified -> ospf
688 * and zebra 0.9[2ish-3]:
689 * PtP special case: network specified == iface peer addr -> ospf
690 */
691 return (
692 ((ifc_pointopoint (co) &&
693 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
694 || prefix_match (net, co->address))
695 ? 1 : 0
696 );
697}
698
paul718e3742002-12-13 20:15:29 +0000699void
700ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
701{
702 struct interface *ifp;
703 listnode node;
704
705 /* Schedule Router ID Update. */
706 if (ospf->router_id_static.s_addr == 0)
707 if (ospf->t_router_id_update == NULL)
708 {
709 ospf->t_router_id_update =
710 thread_add_timer (master, ospf_router_id_update_timer, ospf,
711 OSPF_ROUTER_ID_UPDATE_DELAY);
712 }
713
714 /* Get target interface. */
715 for (node = listhead (ospf->iflist); node; nextnode (node))
716 {
717 listnode cn;
718
719 if ((ifp = getdata (node)) == NULL)
720 continue;
721
722 if (memcmp (ifp->name, "VLINK", 5) == 0)
723 continue;
724
725 /* if interface prefix is match specified prefix,
726 then create socket and join multicast group. */
727 for (cn = listhead (ifp->connected); cn; nextnode (cn))
728 {
729 struct connected *co = getdata (cn);
730 struct prefix *addr;
731
paul00df0c12002-12-13 21:07:36 +0000732 if (ifc_pointopoint (co))
paul718e3742002-12-13 20:15:29 +0000733 addr = co->destination;
734 else
735 addr = co->address;
736
paulcb3f37d2003-02-18 23:26:37 +0000737 if (p->family == co->address->family
paul68980082003-03-25 05:07:42 +0000738 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
paulcb3f37d2003-02-18 23:26:37 +0000739 && ospf_network_match_iface(co,p))
paul570f7592003-01-25 06:47:41 +0000740 {
paul487a5912003-02-19 02:54:57 +0000741 struct ospf_interface *oi;
742 assert(co);
paul718e3742002-12-13 20:15:29 +0000743
paul68980082003-03-25 05:07:42 +0000744 oi = ospf_if_new (ospf, ifp, co->address);
paul718e3742002-12-13 20:15:29 +0000745 oi->connected = co;
746
747 oi->nbr_self->address = *oi->address;
748
749 area->act_ints++;
750 oi->area = area;
751
752 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
753 oi->output_cost = ospf_if_get_output_cost (oi);
754
755 if (area->external_routing != OSPF_AREA_DEFAULT)
756 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
757 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
758
759 /* Add pseudo neighbor. */
760 ospf_nbr_add_self (oi);
761
762 /* Make sure pseudo neighbor's router_id. */
paul68980082003-03-25 05:07:42 +0000763 oi->nbr_self->router_id = ospf->router_id;
paul718e3742002-12-13 20:15:29 +0000764 oi->nbr_self->src = oi->address->u.prefix4;
765
766 /* Relate ospf interface to ospf instance. */
paul68980082003-03-25 05:07:42 +0000767 oi->ospf = ospf;
paul718e3742002-12-13 20:15:29 +0000768
769 /* update network type as interface flag */
770 /* If network type is specified previously,
771 skip network type setting. */
772 oi->type = IF_DEF_PARAMS (ifp)->type;
773
774 /* Set area flag. */
775 switch (area->external_routing)
776 {
777 case OSPF_AREA_DEFAULT:
778 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
779 break;
780 case OSPF_AREA_STUB:
781 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
782 break;
783#ifdef HAVE_NSSA
784 case OSPF_AREA_NSSA:
785 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
786 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
787 break;
788#endif /* HAVE_NSSA */
789 }
790
791 ospf_area_add_if (oi->area, oi);
792
paul2e3b2e42002-12-13 21:03:13 +0000793 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000794 ospf_if_up (oi);
795
796 break;
797 }
798 }
799 }
800}
801
802void
803ospf_ls_upd_queue_empty (struct ospf_interface *oi)
804{
805 struct route_node *rn;
806 listnode node;
807 list lst;
808 struct ospf_lsa *lsa;
809
810 /* empty ls update queue */
811 for (rn = route_top (oi->ls_upd_queue); rn;
812 rn = route_next (rn))
813 if ((lst = (list) rn->info))
814 {
815 for (node = listhead (lst); node; nextnode (node))
816 if ((lsa = getdata (node)))
817 ospf_lsa_unlock (lsa);
818 list_free (lst);
819 rn->info = NULL;
820 }
821
822 /* remove update event */
823 if (oi->t_ls_upd_event)
824 {
825 thread_cancel (oi->t_ls_upd_event);
826 oi->t_ls_upd_event = NULL;
827 }
828}
829
830void
paul68980082003-03-25 05:07:42 +0000831ospf_if_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000832{
833 struct route_node *rn;
834 listnode node;
835 listnode next;
836 struct ospf_network *network;
837 struct ospf_area *area;
838
paul68980082003-03-25 05:07:42 +0000839 if (ospf != NULL)
paul718e3742002-12-13 20:15:29 +0000840 {
841 /* Update Router ID scheduled. */
paul68980082003-03-25 05:07:42 +0000842 if (ospf->router_id_static.s_addr == 0)
843 if (ospf->t_router_id_update == NULL)
paul718e3742002-12-13 20:15:29 +0000844 {
paul68980082003-03-25 05:07:42 +0000845 ospf->t_router_id_update =
paul718e3742002-12-13 20:15:29 +0000846 thread_add_timer (master, ospf_router_id_update_timer, NULL,
847 OSPF_ROUTER_ID_UPDATE_DELAY);
848 }
849
850 /* Find interfaces that not configured already. */
paul68980082003-03-25 05:07:42 +0000851 for (node = listhead (ospf->oiflist); node; node = next)
paul718e3742002-12-13 20:15:29 +0000852 {
853 int found = 0;
854 struct ospf_interface *oi = getdata (node);
855 struct connected *co = oi->connected;
856
857 next = nextnode (node);
858
859 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
860 continue;
861
paul68980082003-03-25 05:07:42 +0000862 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000863 {
864 if (rn->info == NULL)
865 continue;
866
paul570f7592003-01-25 06:47:41 +0000867 if (ospf_network_match_iface(co,&rn->p))
paul718e3742002-12-13 20:15:29 +0000868 {
869 found = 1;
870 route_unlock_node (rn);
871 break;
872 }
873 }
874
875 if (found == 0)
876 ospf_if_free (oi);
877 }
878
879 /* Run each interface. */
paul68980082003-03-25 05:07:42 +0000880 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000881 if (rn->info != NULL)
882 {
883 network = (struct ospf_network *) rn->info;
paul68980082003-03-25 05:07:42 +0000884 area = ospf_area_get (ospf, network->area_id, network->format);
885 ospf_network_run (ospf, &rn->p, area);
paul718e3742002-12-13 20:15:29 +0000886 }
887 }
888}
889
890void
paul68980082003-03-25 05:07:42 +0000891ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000892{
893 listnode node, next;
894 struct ospf_vl_data *vl_data;
895
paul68980082003-03-25 05:07:42 +0000896 for (node = listhead (ospf->vlinks); node; node = next)
paul718e3742002-12-13 20:15:29 +0000897 {
898 next = node->next;
899 if ((vl_data = getdata (node)) != NULL)
900 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
paul68980082003-03-25 05:07:42 +0000901 ospf_vl_delete (ospf, vl_data);
paul718e3742002-12-13 20:15:29 +0000902 }
903}
904
905
906struct message ospf_area_type_msg[] =
907{
908 { OSPF_AREA_DEFAULT, "Default" },
909 { OSPF_AREA_STUB, "Stub" },
910 { OSPF_AREA_NSSA, "NSSA" },
911};
912int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
913
914void
915ospf_area_type_set (struct ospf_area *area, int type)
916{
917 listnode node;
918 struct ospf_interface *oi;
919
920 if (area->external_routing == type)
921 {
922 if (IS_DEBUG_OSPF_EVENT)
923 zlog_info ("Area[%s]: Types are the same, ignored.",
924 inet_ntoa (area->area_id));
925 return;
926 }
927
928 area->external_routing = type;
929
930 if (IS_DEBUG_OSPF_EVENT)
931 zlog_info ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
932 LOOKUP (ospf_area_type_msg, type));
933
934 switch (area->external_routing)
935 {
936 case OSPF_AREA_DEFAULT:
937 for (node = listhead (area->oiflist); node; nextnode (node))
938 if ((oi = getdata (node)) != NULL)
939 if (oi->nbr_self != NULL)
940 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
941 break;
942 case OSPF_AREA_STUB:
943 for (node = listhead (area->oiflist); node; nextnode (node))
944 if ((oi = getdata (node)) != NULL)
945 if (oi->nbr_self != NULL)
946 {
947 if (IS_DEBUG_OSPF_EVENT)
948 zlog_info ("setting options on %s accordingly", IF_NAME (oi));
949 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
950 if (IS_DEBUG_OSPF_EVENT)
951 zlog_info ("options set on %s: %x",
952 IF_NAME (oi), OPTIONS (oi));
953 }
954 break;
955 case OSPF_AREA_NSSA:
956#ifdef HAVE_NSSA
957 for (node = listhead (area->oiflist); node; nextnode (node))
958 if ((oi = getdata (node)) != NULL)
959 if (oi->nbr_self != NULL)
960 {
961 zlog_info ("setting nssa options on %s accordingly", IF_NAME (oi));
962 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
963 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
964 zlog_info ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
965 }
966#endif /* HAVE_NSSA */
967 break;
968 default:
969 break;
970 }
971
972 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +0000973 ospf_schedule_abr_task (area->ospf);
paul718e3742002-12-13 20:15:29 +0000974}
975
976int
paul68980082003-03-25 05:07:42 +0000977ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
paul718e3742002-12-13 20:15:29 +0000978{
979 if (area->shortcut_configured == mode)
980 return 0;
981
982 area->shortcut_configured = mode;
983 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +0000984 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000985
paul68980082003-03-25 05:07:42 +0000986 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +0000987
988 return 1;
989}
990
991int
paul68980082003-03-25 05:07:42 +0000992ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000993{
994 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
995 ospf_router_lsa_timer_add (area);
paul68980082003-03-25 05:07:42 +0000996 ospf_area_check_free (ospf, area->area_id);
997 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000998
999 return 1;
1000}
1001
1002int
1003ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1004{
1005 struct ospf_vl_data *vl;
1006 listnode node;
1007 int count = 0;
1008
1009 for (node = listhead (ospf->vlinks); node; nextnode (node))
1010 {
1011 vl = getdata (node);
1012 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1013 count++;
1014 }
1015
1016 return count;
1017}
1018
1019int
1020ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1021{
1022 struct ospf_area *area;
1023 int format = OSPF_AREA_ID_FORMAT_DECIMAL;
1024
paul68980082003-03-25 05:07:42 +00001025 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001026 if (ospf_area_vlink_count (ospf, area))
1027 return 0;
1028
1029 if (area->external_routing != OSPF_AREA_STUB)
1030 ospf_area_type_set (area, OSPF_AREA_STUB);
1031
1032 return 1;
1033}
1034
1035int
1036ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1037{
1038 struct ospf_area *area;
1039
paul68980082003-03-25 05:07:42 +00001040 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001041 if (area == NULL)
1042 return 1;
1043
1044 if (area->external_routing == OSPF_AREA_STUB)
1045 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1046
paul68980082003-03-25 05:07:42 +00001047 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001048
1049 return 1;
1050}
1051
1052int
1053ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1054{
1055 struct ospf_area *area;
1056 int format = OSPF_AREA_ID_FORMAT_DECIMAL;
1057
paul68980082003-03-25 05:07:42 +00001058 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001059 area->no_summary = 1;
1060
1061 return 1;
1062}
1063
1064int
1065ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1066{
1067 struct ospf_area *area;
1068
paul68980082003-03-25 05:07:42 +00001069 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001070 if (area == NULL)
1071 return 0;
1072
1073 area->no_summary = 0;
paul68980082003-03-25 05:07:42 +00001074 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001075
1076 return 1;
1077}
1078
1079int
1080ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1081{
1082 struct ospf_area *area;
1083 int format = OSPF_AREA_ID_FORMAT_DECIMAL;
1084
paul68980082003-03-25 05:07:42 +00001085 area = ospf_area_get (ospf, area_id, format);
paul718e3742002-12-13 20:15:29 +00001086 if (ospf_area_vlink_count (ospf, area))
1087 return 0;
1088
1089 if (area->external_routing != OSPF_AREA_NSSA)
1090 {
1091 ospf_area_type_set (area, OSPF_AREA_NSSA);
1092 ospf->anyNSSA++;
1093 }
1094
1095 return 1;
1096}
1097
1098int
1099ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1100{
1101 struct ospf_area *area;
1102
paul68980082003-03-25 05:07:42 +00001103 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001104 if (area == NULL)
1105 return 0;
1106
1107 if (area->external_routing == OSPF_AREA_NSSA)
1108 {
1109 ospf->anyNSSA--;
1110 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1111 }
1112
paul68980082003-03-25 05:07:42 +00001113 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001114
1115 return 1;
1116}
1117
1118int
1119ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1120 int role)
1121{
1122 struct ospf_area *area;
1123
paul68980082003-03-25 05:07:42 +00001124 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001125 if (area == NULL)
1126 return 0;
1127
1128 area->NSSATranslator = role;
1129
1130 return 1;
1131}
1132
1133int
1134ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1135 struct in_addr area_id)
1136{
1137 struct ospf_area *area;
1138
paul68980082003-03-25 05:07:42 +00001139 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001140 if (area == NULL)
1141 return 0;
1142
1143 area->NSSATranslator = OSPF_NSSA_ROLE_CANDIDATE;
1144
paul68980082003-03-25 05:07:42 +00001145 ospf_area_check_free (ospf, area_id);
paul718e3742002-12-13 20:15:29 +00001146
1147 return 1;
1148}
1149
1150int
paul68980082003-03-25 05:07:42 +00001151ospf_area_export_list_set (struct ospf *ospf,
1152 struct ospf_area *area, char *list_name)
paul718e3742002-12-13 20:15:29 +00001153{
1154 struct access_list *list;
1155 list = access_list_lookup (AFI_IP, list_name);
1156
1157 EXPORT_LIST (area) = list;
1158
1159 if (EXPORT_NAME (area))
1160 free (EXPORT_NAME (area));
1161
1162 EXPORT_NAME (area) = strdup (list_name);
paul68980082003-03-25 05:07:42 +00001163 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001164
1165 return 1;
1166}
1167
1168int
paul68980082003-03-25 05:07:42 +00001169ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001170{
1171
1172 EXPORT_LIST (area) = 0;
1173
1174 if (EXPORT_NAME (area))
1175 free (EXPORT_NAME (area));
1176
1177 EXPORT_NAME (area) = NULL;
1178
paul68980082003-03-25 05:07:42 +00001179 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001180
paul68980082003-03-25 05:07:42 +00001181 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001182
1183 return 1;
1184}
1185
1186int
paul68980082003-03-25 05:07:42 +00001187ospf_area_import_list_set (struct ospf *ospf,
1188 struct ospf_area *area, char *name)
paul718e3742002-12-13 20:15:29 +00001189{
1190 struct access_list *list;
1191 list = access_list_lookup (AFI_IP, name);
1192
1193 IMPORT_LIST (area) = list;
1194
1195 if (IMPORT_NAME (area))
1196 free (IMPORT_NAME (area));
1197
1198 IMPORT_NAME (area) = strdup (name);
paul68980082003-03-25 05:07:42 +00001199 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001200
1201 return 1;
1202}
1203
1204int
paul68980082003-03-25 05:07:42 +00001205ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
paul718e3742002-12-13 20:15:29 +00001206{
1207 IMPORT_LIST (area) = 0;
1208
1209 if (IMPORT_NAME (area))
1210 free (IMPORT_NAME (area));
1211
1212 IMPORT_NAME (area) = NULL;
paul68980082003-03-25 05:07:42 +00001213 ospf_area_check_free (ospf, area->area_id);
paul718e3742002-12-13 20:15:29 +00001214
paul68980082003-03-25 05:07:42 +00001215 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001216
1217 return 1;
1218}
1219
1220int
1221ospf_timers_spf_set (struct ospf *ospf, u_int32_t delay, u_int32_t hold)
1222{
1223 ospf->spf_delay = delay;
1224 ospf->spf_holdtime = hold;
1225
1226 return 1;
1227}
1228
1229int
1230ospf_timers_spf_unset (struct ospf *ospf)
1231{
1232 ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT;
1233 ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
1234
1235 return 1;
1236}
1237
1238int
1239ospf_timers_refresh_set (struct ospf *ospf, int interval)
1240{
1241 int time_left;
1242
1243 if (ospf->lsa_refresh_interval == interval)
1244 return 1;
1245
1246 time_left = ospf->lsa_refresh_interval -
1247 (time (NULL) - ospf->lsa_refresher_started);
1248
1249 if (time_left > interval)
1250 {
1251 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1252 ospf->t_lsa_refresher =
1253 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1254 }
1255 ospf->lsa_refresh_interval = interval;
1256
1257 return 1;
1258}
1259
1260int
1261ospf_timers_refresh_unset (struct ospf *ospf)
1262{
1263 int time_left;
1264
1265 time_left = ospf->lsa_refresh_interval -
1266 (time (NULL) - ospf->lsa_refresher_started);
1267
1268 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1269 {
1270 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1271 ospf->t_lsa_refresher =
1272 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1273 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1274 }
1275
1276 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1277
1278 return 1;
1279}
1280
1281
1282struct ospf_nbr_nbma *
1283ospf_nbr_nbma_new ()
1284{
1285 struct ospf_nbr_nbma *nbr_nbma;
1286
1287 nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1288 sizeof (struct ospf_nbr_nbma));
1289 memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));
1290
1291 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1292 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1293
1294 return nbr_nbma;
1295}
1296
1297void
1298ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1299{
1300 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1301}
1302
1303void
1304ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1305{
1306 struct route_node *rn;
1307 struct prefix_ipv4 p;
1308
1309 p.family = AF_INET;
1310 p.prefix = nbr_nbma->addr;
1311 p.prefixlen = IPV4_MAX_BITLEN;
1312
1313 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1314 if (rn)
1315 {
1316 ospf_nbr_nbma_free (rn->info);
1317 rn->info = NULL;
1318 route_unlock_node (rn);
1319 route_unlock_node (rn);
1320 }
1321}
1322
1323void
1324ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1325{
1326 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1327
1328 if (nbr_nbma->nbr)
1329 {
1330 nbr_nbma->nbr->nbr_nbma = NULL;
1331 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1332 }
1333
1334 if (nbr_nbma->oi)
1335 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1336}
1337
1338void
1339ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1340 struct ospf_interface *oi)
1341{
1342 struct ospf_neighbor *nbr;
1343 struct route_node *rn;
1344 struct prefix p;
1345
1346 if (oi->type != OSPF_IFTYPE_NBMA)
1347 return;
1348
1349 if (nbr_nbma->nbr != NULL)
1350 return;
1351
1352 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1353 return;
1354
1355 nbr_nbma->oi = oi;
1356 listnode_add (oi->nbr_nbma, nbr_nbma);
1357
1358 /* Get neighbor information from table. */
1359 p.family = AF_INET;
1360 p.prefixlen = IPV4_MAX_BITLEN;
1361 p.u.prefix4 = nbr_nbma->addr;
1362
1363 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1364 if (rn->info)
1365 {
1366 nbr = rn->info;
1367 nbr->nbr_nbma = nbr_nbma;
1368 nbr_nbma->nbr = nbr;
1369
1370 route_unlock_node (rn);
1371 }
1372 else
1373 {
1374 nbr = rn->info = ospf_nbr_new (oi);
1375 nbr->state = NSM_Down;
1376 nbr->src = nbr_nbma->addr;
1377 nbr->nbr_nbma = nbr_nbma;
1378 nbr->priority = nbr_nbma->priority;
1379 nbr->address = p;
1380
1381 nbr_nbma->nbr = nbr;
1382
1383 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1384 }
1385}
1386
1387void
paul68980082003-03-25 05:07:42 +00001388ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001389{
1390 struct ospf_nbr_nbma *nbr_nbma;
1391 struct route_node *rn;
1392 struct prefix_ipv4 p;
1393
1394 if (oi->type != OSPF_IFTYPE_NBMA)
1395 return;
1396
paul68980082003-03-25 05:07:42 +00001397 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001398 if ((nbr_nbma = rn->info))
1399 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1400 {
1401 p.family = AF_INET;
1402 p.prefix = nbr_nbma->addr;
1403 p.prefixlen = IPV4_MAX_BITLEN;
1404
1405 if (prefix_match (oi->address, (struct prefix *)&p))
1406 ospf_nbr_nbma_add (nbr_nbma, oi);
1407 }
1408}
1409
1410struct ospf_nbr_nbma *
1411ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1412{
1413 struct route_node *rn;
1414 struct prefix_ipv4 p;
1415
1416 p.family = AF_INET;
1417 p.prefix = nbr_addr;
1418 p.prefixlen = IPV4_MAX_BITLEN;
1419
1420 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1421 if (rn)
1422 {
1423 route_unlock_node (rn);
1424 return rn->info;
1425 }
1426 return NULL;
1427}
1428
1429struct ospf_nbr_nbma *
paul68980082003-03-25 05:07:42 +00001430ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
paul718e3742002-12-13 20:15:29 +00001431{
1432#if 0
1433 struct ospf_nbr_nbma *nbr_nbma;
1434 listnode node;
1435#endif
1436
paul68980082003-03-25 05:07:42 +00001437 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001438 return NULL;
1439
1440#if 0
paul68980082003-03-25 05:07:42 +00001441 for (node = listhead (ospf->nbr_nbma); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001442 {
1443 nbr_nbma = getdata (node);
1444
1445 if (first)
1446 {
1447 *addr = nbr_nbma->addr;
1448 return nbr_nbma;
1449 }
1450 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1451 {
1452 *addr = nbr_nbma->addr;
1453 return nbr_nbma;
1454 }
1455 }
1456#endif
1457 return NULL;
1458}
1459
1460int
1461ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1462{
1463 struct ospf_nbr_nbma *nbr_nbma;
1464 struct ospf_interface *oi;
1465 struct prefix_ipv4 p;
1466 struct route_node *rn;
1467 listnode node;
1468
1469 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1470 if (nbr_nbma)
1471 return 0;
1472
1473 nbr_nbma = ospf_nbr_nbma_new ();
1474 nbr_nbma->addr = nbr_addr;
1475
1476 p.family = AF_INET;
1477 p.prefix = nbr_addr;
1478 p.prefixlen = IPV4_MAX_BITLEN;
1479
1480 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1481 rn->info = nbr_nbma;
1482
1483 for (node = listhead (ospf->oiflist); node; nextnode (node))
1484 {
1485 oi = getdata (node);
1486 if (oi->type == OSPF_IFTYPE_NBMA)
1487 if (prefix_match (oi->address, (struct prefix *)&p))
1488 {
1489 ospf_nbr_nbma_add (nbr_nbma, oi);
1490 break;
1491 }
1492 }
1493
1494 return 1;
1495}
1496
1497int
1498ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1499{
1500 struct ospf_nbr_nbma *nbr_nbma;
1501
1502 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1503 if (nbr_nbma == NULL)
1504 return 0;
1505
1506 ospf_nbr_nbma_down (nbr_nbma);
1507 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1508
1509 return 1;
1510}
1511
1512int
1513ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1514 u_char priority)
1515{
1516 struct ospf_nbr_nbma *nbr_nbma;
1517
1518 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1519 if (nbr_nbma == NULL)
1520 return 0;
1521
1522 if (nbr_nbma->priority != priority)
1523 nbr_nbma->priority = priority;
1524
1525 return 1;
1526}
1527
1528int
1529ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1530{
1531 struct ospf_nbr_nbma *nbr_nbma;
1532
1533 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1534 if (nbr_nbma == NULL)
1535 return 0;
1536
1537 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1538 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1539
1540 return 1;
1541}
1542
1543int
1544ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
1545 int interval)
1546{
1547 struct ospf_nbr_nbma *nbr_nbma;
1548
1549 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1550 if (nbr_nbma == NULL)
1551 return 0;
1552
1553 if (nbr_nbma->v_poll != interval)
1554 {
1555 nbr_nbma->v_poll = interval;
1556 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1557 {
1558 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1559 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1560 nbr_nbma->v_poll);
1561 }
1562 }
1563
1564 return 1;
1565}
1566
1567int
1568ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1569{
1570 struct ospf_nbr_nbma *nbr_nbma;
1571
1572 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1573 if (nbr_nbma == NULL)
1574 return 0;
1575
1576 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1577 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1578
1579 return 1;
1580}
1581
1582
1583void
1584ospf_prefix_list_update (struct prefix_list *plist)
1585{
paul68980082003-03-25 05:07:42 +00001586 struct ospf *ospf = ospf_top;
paul718e3742002-12-13 20:15:29 +00001587 struct ospf_area *area;
1588 listnode node;
1589 int abr_inv = 0;
1590
1591 /* If OSPF instatnce does not exist, return right now. */
paul68980082003-03-25 05:07:42 +00001592 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001593 return;
1594
1595 /* Update Area prefix-list. */
paul68980082003-03-25 05:07:42 +00001596 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001597 {
1598 area = getdata (node);
1599
1600 /* Update filter-list in. */
1601 if (PREFIX_NAME_IN (area))
1602 if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
1603 {
1604 PREFIX_LIST_IN (area) =
1605 prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
1606 abr_inv++;
1607 }
1608
1609 /* Update filter-list out. */
1610 if (PREFIX_NAME_OUT (area))
1611 if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
1612 {
1613 PREFIX_LIST_IN (area) =
1614 prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
1615 abr_inv++;
1616 }
1617 }
1618
1619 /* Schedule ABR tasks. */
1620 if (OSPF_IS_ABR && abr_inv)
paul68980082003-03-25 05:07:42 +00001621 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001622}
1623
1624void
1625ospf_init ()
1626{
1627 /* Make empty list of ospf list. */
1628 ospf_top = NULL;
1629
1630 prefix_list_add_hook (ospf_prefix_list_update);
1631 prefix_list_delete_hook (ospf_prefix_list_update);
1632}