blob: 638cf1cc8909d412773644304a324fe51f322eeb [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF ABR functions.
3 * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23
24#include <zebra.h>
25
26#include "thread.h"
27#include "memory.h"
28#include "linklist.h"
29#include "prefix.h"
30#include "if.h"
31#include "table.h"
32#include "vty.h"
33#include "filter.h"
34#include "plist.h"
35#include "log.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_spf.h"
46#include "ospfd/ospf_route.h"
47#include "ospfd/ospf_ia.h"
48#include "ospfd/ospf_flood.h"
49#include "ospfd/ospf_abr.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52#include "ospfd/ospf_dump.h"
53
54
55struct ospf_area_range *
56ospf_area_range_new (struct prefix_ipv4 *p)
57{
58 struct ospf_area_range *range;
59
60 range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range));
61 range->addr = p->prefix;
62 range->masklen = p->prefixlen;
63 range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
64
65 return range;
66}
67
68void
69ospf_area_range_free (struct ospf_area_range *range)
70{
71 XFREE (MTYPE_OSPF_AREA_RANGE, range);
72}
73
74void
75ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)
76{
77 struct route_node *rn;
78 struct prefix_ipv4 p;
79
80 p.family = AF_INET;
81 p.prefixlen = range->masklen;
82 p.prefix = range->addr;
83
84 rn = route_node_get (area->ranges, (struct prefix *)&p);
85 if (rn->info)
86 route_unlock_node (rn);
87 else
88 rn->info = range;
89}
90
91void
92ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range)
93{
94 struct route_node *rn;
95 struct prefix_ipv4 p;
96
97 p.family = AF_INET;
98 p.prefixlen = range->masklen;
99 p.prefix = range->addr;
100
101 rn = route_node_lookup (area->ranges, (struct prefix *)&p);
102 if (rn)
103 {
104 ospf_area_range_free (rn->info);
105 rn->info = NULL;
106 route_unlock_node (rn);
107 route_unlock_node (rn);
108 }
109}
110
111struct ospf_area_range *
112ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p)
113{
114 struct route_node *rn;
115
116 rn = route_node_lookup (area->ranges, (struct prefix *)p);
117 if (rn)
118 {
119 route_unlock_node (rn);
120 return rn->info;
121 }
122 return NULL;
123}
124
125struct ospf_area_range *
126ospf_area_range_lookup_next (struct ospf_area *area, struct in_addr *range_net,
127 int first)
128{
129 struct route_node *rn;
130 struct prefix_ipv4 p;
131 struct ospf_area_range *find;
132
133 p.family = AF_INET;
134 p.prefixlen = IPV4_MAX_BITLEN;
135 p.prefix = *range_net;
136
137 if (first)
138 rn = route_top (area->ranges);
139 else
140 {
141 rn = route_node_get (area->ranges, (struct prefix *) &p);
142 rn = route_next (rn);
143 }
144
145 for (; rn; rn = route_next (rn))
146 if (rn->info)
147 break;
148
149 if (rn && rn->info)
150 {
151 find = rn->info;
152 *range_net = rn->p.u.prefix4;
153 route_unlock_node (rn);
154 return find;
155 }
156 return NULL;
157}
158
159struct ospf_area_range *
160ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p)
161{
162 struct route_node *node;
163
164 node = route_node_match (area->ranges, (struct prefix *) p);
165 if (node)
166 {
167 route_unlock_node (node);
168 return node->info;
169 }
170 return NULL;
171}
172
173struct ospf_area_range *
174ospf_area_range_match_any (struct ospf *ospf, struct prefix_ipv4 *p)
175{
176 struct ospf_area_range *range;
177 listnode node;
178
179 for (node = listhead (ospf->areas); node; nextnode (node))
180 if ((range = ospf_area_range_match (node->data, p)))
181 return range;
182
183 return NULL;
184}
185
186int
187ospf_area_range_active (struct ospf_area_range *range)
188{
189 return range->specifics;
190}
191
192int
193ospf_area_actively_attached (struct ospf_area *area)
194{
195 return area->act_ints;
196}
197
198int
199ospf_area_range_set (struct ospf *ospf, struct in_addr area_id,
200 struct prefix_ipv4 *p, int advertise)
201{
202 struct ospf_area *area;
203 struct ospf_area_range *range;
paul147193a2003-04-19 00:31:59 +0000204 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000205
paul147193a2003-04-19 00:31:59 +0000206 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000207 if (area == NULL)
208 return 0;
209
210 range = ospf_area_range_lookup (area, p);
211 if (range != NULL)
212 {
213 if ((CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)
214 && !CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))
215 || (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)
216 && CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)))
paul147193a2003-04-19 00:31:59 +0000217 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000218 }
219 else
220 {
221 range = ospf_area_range_new (p);
222 ospf_area_range_add (area, range);
paul147193a2003-04-19 00:31:59 +0000223 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000224 }
225
226 if (CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))
227 SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE);
228 else
229 UNSET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE);
230
231 return 1;
232}
233
234int
235ospf_area_range_cost_set (struct ospf *ospf, struct in_addr area_id,
236 struct prefix_ipv4 *p, u_int32_t cost)
237{
238 struct ospf_area *area;
239 struct ospf_area_range *range;
paul147193a2003-04-19 00:31:59 +0000240 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000241
paul147193a2003-04-19 00:31:59 +0000242 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000243 if (area == NULL)
244 return 0;
245
246 range = ospf_area_range_new (p);
247 if (range == NULL)
248 return 0;
249
250 if (range->cost_config != cost)
251 {
252 range->cost_config = cost;
253 if (ospf_area_range_active (range))
paul147193a2003-04-19 00:31:59 +0000254 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000255 }
256
257 return 1;
258}
259
260int
261ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id,
262 struct prefix_ipv4 *p)
263{
264 struct ospf_area *area;
265 struct ospf_area_range *range;
266
paul147193a2003-04-19 00:31:59 +0000267 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000268 if (area == NULL)
269 return 0;
270
271 range = ospf_area_range_lookup (area, p);
272 if (range == NULL)
273 return 0;
274
275 if (ospf_area_range_active (range))
paul147193a2003-04-19 00:31:59 +0000276 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000277
278 ospf_area_range_delete (area, range);
279
280 return 1;
281}
282
283int
284ospf_area_range_substitute_set (struct ospf *ospf, struct in_addr area_id,
285 struct prefix_ipv4 *p, struct prefix_ipv4 *s)
286{
287 struct ospf_area *area;
288 struct ospf_area_range *range;
paul147193a2003-04-19 00:31:59 +0000289 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000290
paul147193a2003-04-19 00:31:59 +0000291 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000292 range = ospf_area_range_lookup (area, p);
293
294 if (range != NULL)
295 {
296 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) ||
297 !CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
paul147193a2003-04-19 00:31:59 +0000298 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000299 }
300 else
301 {
302 range = ospf_area_range_new (p);
303 ospf_area_range_add (area, range);
paul147193a2003-04-19 00:31:59 +0000304 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000305 }
306
307 SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE);
308 SET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
309 range->subst_addr = s->prefix;
310 range->subst_masklen = s->prefixlen;
311
312 return 1;
313}
314
315int
316ospf_area_range_substitute_unset (struct ospf *ospf, struct in_addr area_id,
317 struct prefix_ipv4 *p)
318{
319 struct ospf_area *area;
320 struct ospf_area_range *range;
321
paul147193a2003-04-19 00:31:59 +0000322 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000323 if (area == NULL)
324 return 0;
325
326 range = ospf_area_range_lookup (area, p);
327 if (range == NULL)
328 return 0;
329
330 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
331 if (ospf_area_range_active (range))
paul147193a2003-04-19 00:31:59 +0000332 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000333
334 UNSET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
335 range->subst_addr.s_addr = 0;
336 range->subst_masklen = 0;
337
338 return 1;
339}
340
341int
paul147193a2003-04-19 00:31:59 +0000342ospf_act_bb_connection (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000343{
paul147193a2003-04-19 00:31:59 +0000344 if (ospf->backbone == NULL)
paul718e3742002-12-13 20:15:29 +0000345 return 0;
346
paul147193a2003-04-19 00:31:59 +0000347 return ospf->backbone->full_nbrs;
paul718e3742002-12-13 20:15:29 +0000348}
349
350/* Check area border router status. */
351void
paul147193a2003-04-19 00:31:59 +0000352ospf_check_abr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000353{
354 struct ospf_area *area;
355 listnode node;
356 int bb_configured = 0;
357 int bb_act_attached = 0;
358 int areas_configured = 0;
359 int areas_act_attached = 0;
paul147193a2003-04-19 00:31:59 +0000360 u_char new_flags = ospf->flags;
paul718e3742002-12-13 20:15:29 +0000361
362 if (IS_DEBUG_OSPF_EVENT)
363 zlog_info ("ospf_check_abr_status(): Start");
364
paul147193a2003-04-19 00:31:59 +0000365 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000366 {
367 area = getdata (node);
368
369 if (listcount (area->oiflist))
370 {
371 areas_configured++;
372
373 if (OSPF_IS_AREA_BACKBONE (area))
374 bb_configured = 1;
375 }
376
377 if (ospf_area_actively_attached (area))
378 {
379 areas_act_attached++;
380
381 if (OSPF_IS_AREA_BACKBONE (area))
382 bb_act_attached = 1;
383 }
384 }
385
386 if (IS_DEBUG_OSPF_EVENT)
387 {
388 zlog_info ("ospf_check_abr_status(): looked through areas");
389 zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured);
390 zlog_info ("ospf_check_abr_status(): bb_act_attached: %d",
391 bb_act_attached);
392 zlog_info ("ospf_check_abr_status(): areas_configured: %d",
393 areas_configured);
394 zlog_info ("ospf_check_abr_status(): areas_act_attached: %d",
395 areas_act_attached);
396 }
397
paul147193a2003-04-19 00:31:59 +0000398 switch (ospf->abr_type)
paul718e3742002-12-13 20:15:29 +0000399 {
400 case OSPF_ABR_SHORTCUT:
401 case OSPF_ABR_STAND:
402 if (areas_act_attached > 1)
403 SET_FLAG (new_flags, OSPF_FLAG_ABR);
404 else
405 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
406 break;
407
408 case OSPF_ABR_IBM:
409 if ((areas_act_attached > 1) && bb_configured)
410 SET_FLAG (new_flags, OSPF_FLAG_ABR);
411 else
412 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
413 break;
414
415 case OSPF_ABR_CISCO:
416 if ((areas_configured > 1) && bb_act_attached)
417 SET_FLAG (new_flags, OSPF_FLAG_ABR);
418 else
419 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
420 break;
421 default:
422 break;
423 }
424
paul147193a2003-04-19 00:31:59 +0000425 if (new_flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +0000426 {
paul147193a2003-04-19 00:31:59 +0000427 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +0000428 if (IS_DEBUG_OSPF_EVENT)
429 zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags);
paul147193a2003-04-19 00:31:59 +0000430 ospf->flags = new_flags;
431 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000432 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
433 }
434}
435
436void
437ospf_abr_update_aggregate (struct ospf_area_range *range,
438 struct ospf_route *or)
439{
440 if (IS_DEBUG_OSPF_EVENT)
441 zlog_info ("ospf_abr_update_aggregate(): Start");
442
443 if (range->cost_config != -1)
444 {
445 if (IS_DEBUG_OSPF_EVENT)
446 zlog_info ("ospf_abr_update_aggregate(): use configured cost %d",
447 range->cost_config);
448
449 range->cost = range->cost_config;
450 }
451 else
452 {
453 if (range->specifics == 0)
454 range->cost = or->cost; /* 1st time get 1st cost */
455
456 if (or->cost < range->cost)
457 {
458 if (IS_DEBUG_OSPF_EVENT)
459 zlog_info ("ospf_abr_update_aggregate(): lowest cost, update");
460
461 range->cost = or->cost;
462 }
463 }
464
465 range->specifics++;
466}
467
468static void
469set_metric (struct ospf_lsa *lsa, u_int32_t metric)
470{
471 struct summary_lsa *header;
472 u_char *mp;
473 metric = htonl (metric);
474 mp = (char *) &metric;
475 mp++;
476 header = (struct summary_lsa *) lsa->data;
477 memcpy(header->metric, mp, 3);
478}
479
480#ifdef HAVE_NSSA
481int
482ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost,
483 struct ospf_area *area)
484{
485 /* The Type-7 is tested against the aggregated prefix and forwarded
486 for lsa installation and flooding */
487 return 0;
488}
489
490/* ospf_abr_translate_nssa */
491int
paul147193a2003-04-19 00:31:59 +0000492ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +0000493{
494 /* Incoming Type-7 or later aggregated Type-7
495
496 LSA is skipped if P-bit is off.
497 LSA is aggregated if within range.
498
499 The Type-7 is translated, Installed/Approved as a Type-5 into
500 global LSDB, then Flooded through AS
501
502 Later, any Unapproved Translated Type-5's are flushed/discarded */
503
504 struct ospf_lsa *dup;
505
506 if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
507 {
508 if (IS_DEBUG_OSPF_NSSA)
509 zlog_info ("ospf_abr_nssa(): P-bit off, NO Translation");
510 return 0;
511 }
512
513 if (IS_DEBUG_OSPF_NSSA)
514 zlog_info ("ospf_abr_nssa(): TRANSLATING 7 to 5");
515
516 /* No more P-bit. */
517 /* UNSET_FLAG (lsa->data->options, OSPF_OPTION_NP); */
518
519 /* Area where Aggregate testing will be inserted, just like summary
520 advertisements */
521 /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
522
523 /* Follow thru here means no aggregation */
524 dup = ospf_lsa_dup (lsa); /* keep LSDB intact, lock = 1 */
525
526 SET_FLAG (dup->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
527 SET_FLAG (dup->flags, OSPF_LSA_APPROVED); /* So, do not remove it */
528
529 dup->data->type = OSPF_AS_EXTERNAL_LSA; /* make Type-5 */
530
531 ospf_lsa_checksum (dup->data);
532
paul147193a2003-04-19 00:31:59 +0000533 ospf_lsa_install (area->ospf, NULL, dup); /* Install this Type-5 into LSDB, Lock = 2. */
paul718e3742002-12-13 20:15:29 +0000534
paul147193a2003-04-19 00:31:59 +0000535 ospf_flood_through_as (area->ospf, NULL, dup); /* flood non-NSSA/STUB areas */
paul718e3742002-12-13 20:15:29 +0000536
537 /* This translated Type-5 will go to all non-NSSA areas connected to
538 this ABR; The Type-5 could come from any of the NSSA's connected
539 to this ABR. */
540
541 return 0;
542}
543
544void
545ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost)
546{
547 /* The Type-7 is created from the aggregated prefix and forwarded
548 for lsa installation and flooding... to be added... */
549}
550#endif /* HAVE_NSSA */
551
552void
553ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
554 struct ospf_area *area)
555{
556 struct ospf_lsa *lsa, *old = NULL;
557 struct summary_lsa *sl = NULL;
558
559 if (IS_DEBUG_OSPF_EVENT)
560 zlog_info ("ospf_abr_announce_network_to_area(): Start");
561
paul147193a2003-04-19 00:31:59 +0000562 old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, p,
563 area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000564 if (old)
565 {
566 if (IS_DEBUG_OSPF_EVENT)
567 zlog_info ("ospf_abr_announce_network_to_area(): old summary found");
568 sl = (struct summary_lsa *) old->data;
569
570 if (IS_DEBUG_OSPF_EVENT)
571 zlog_info ("ospf_abr_announce_network_to_area(): "
572 "old metric: %d, new metric: %d",
573 GET_METRIC (sl->metric), cost);
574 }
575
576 if (old && (GET_METRIC (sl->metric) == cost))
577 {
578 if (IS_DEBUG_OSPF_EVENT)
579 zlog_info ("ospf_abr_announce_network_to_area(): "
580 "old summary approved");
581 SET_FLAG (old->flags, OSPF_LSA_APPROVED);
582 }
583 else
584 {
585 if (IS_DEBUG_OSPF_EVENT)
586 zlog_info ("ospf_abr_announce_network_to_area(): "
587 "creating new summary");
588 if (old)
589 {
590
591 set_metric (old, cost);
paul147193a2003-04-19 00:31:59 +0000592 lsa = ospf_summary_lsa_refresh (area->ospf, old);
paul718e3742002-12-13 20:15:29 +0000593 /* This will flood through area. */
594 }
595 else
596 {
597 lsa = ospf_summary_lsa_originate (p, cost, area);
598 /* This will flood through area. */
599 }
600
601
602 SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
603 if (IS_DEBUG_OSPF_EVENT)
604 zlog_info ("ospf_abr_announce_network_to_area(): "
605 "flooding new version of summary");
606
607#ifndef HAVE_NSSA
608 ospf_flood_through_area (area, NULL, lsa);
609#endif /* ! HAVE_NSSA */
610 }
611
612 if (IS_DEBUG_OSPF_EVENT)
613 zlog_info ("ospf_abr_announce_network_to_area(): Stop");
614}
615
616int
617ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
618 struct ospf_area *area)
619{
620 listnode node;
621
622 for (node = listhead (or->path); node; nextnode (node))
623 {
624 struct ospf_path *path = node->data;
625 struct ospf_interface *oi = path->oi;
626
627 if (oi != NULL)
628 if (oi->area == area)
629 return 1;
630 }
631
632 return 0;
633}
634
635int
636ospf_abr_should_accept (struct prefix *p, struct ospf_area *area)
637{
638 if (IMPORT_NAME (area))
639 {
640 if (IMPORT_LIST (area) == NULL)
641 IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area));
642
643 if (IMPORT_LIST (area))
644 if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY)
645 return 0;
646 }
647
648 return 1;
649}
650
651int
652ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
653 struct prefix *p)
654{
655 if (PREFIX_NAME_IN (area))
656 {
657 if (PREFIX_LIST_IN (area) == NULL)
658 PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP,
659 PREFIX_NAME_IN (area));
660 if (PREFIX_LIST_IN (area))
661 if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT)
662 return 0;
663 }
664 return 1;
665}
666
667int
668ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
669 struct prefix *p)
670{
671 if (PREFIX_NAME_OUT (area))
672 {
673 if (PREFIX_LIST_OUT (area) == NULL)
674 PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP,
675 PREFIX_NAME_OUT (area));
676 if (PREFIX_LIST_OUT (area))
677 if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT)
678 return 0;
679 }
680 return 1;
681}
682
683void
paul147193a2003-04-19 00:31:59 +0000684ospf_abr_announce_network (struct ospf *ospf,
685 struct route_node *n, struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +0000686{
paul718e3742002-12-13 20:15:29 +0000687 struct ospf_area_range *range;
paul718e3742002-12-13 20:15:29 +0000688 struct ospf_area *area, *or_area;
paul147193a2003-04-19 00:31:59 +0000689 struct prefix_ipv4 *p;
690 listnode node;
paul718e3742002-12-13 20:15:29 +0000691
692 if (IS_DEBUG_OSPF_EVENT)
693 zlog_info ("ospf_abr_announce_network(): Start");
694 p = (struct prefix_ipv4 *) &n->p;
695
paul147193a2003-04-19 00:31:59 +0000696 or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
paul718e3742002-12-13 20:15:29 +0000697 assert (or_area);
698
paul147193a2003-04-19 00:31:59 +0000699 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000700 {
701 area = getdata (node);
702
703 if (IS_DEBUG_OSPF_EVENT)
704 zlog_info ("ospf_abr_announce_network(): looking at area %s",
705 inet_ntoa (area->area_id));
706
707 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
708 continue;
709
710 if (ospf_abr_nexthops_belong_to_area (or, area))
711 continue;
712
713 if (!ospf_abr_should_accept (&n->p, area))
714 {
715 if (IS_DEBUG_OSPF_EVENT)
716 zlog_info ("ospf_abr_announce_network(): "
717 "prefix %s/%d was denied by import-list",
718 inet_ntoa (p->prefix), p->prefixlen);
719 continue;
720 }
721
722 if (!ospf_abr_plist_in_check (area, or, &n->p))
723 {
724 if (IS_DEBUG_OSPF_EVENT)
725 zlog_info ("ospf_abr_announce_network(): "
726 "prefix %s/%d was denied by prefix-list",
727 inet_ntoa (p->prefix), p->prefixlen);
728 continue;
729 }
730
731 if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary)
732 {
733 if (IS_DEBUG_OSPF_EVENT)
734 zlog_info ("ospf_abr_announce_network(): "
735 "area %s is stub and no_summary",
736 inet_ntoa (area->area_id));
737 continue;
738 }
739
740 if (or->path_type == OSPF_PATH_INTER_AREA)
741 {
742 if (IS_DEBUG_OSPF_EVENT)
743 zlog_info ("ospf_abr_announce_network(): this is "
744 "inter-area route to %s/%d",
745 inet_ntoa (p->prefix), p->prefixlen);
746
747 if (!OSPF_IS_AREA_BACKBONE (area))
748 ospf_abr_announce_network_to_area (p, or->cost, area);
749 }
750
751 if (or->path_type == OSPF_PATH_INTRA_AREA)
752 {
753 if (IS_DEBUG_OSPF_EVENT)
754 zlog_info ("ospf_abr_announce_network(): "
755 "this is intra-area route to %s/%d",
756 inet_ntoa (p->prefix), p->prefixlen);
757 if ((range = ospf_area_range_match (or_area, p)) &&
758 !ospf_area_is_transit (area))
759 ospf_abr_update_aggregate (range, or);
760 else
761 ospf_abr_announce_network_to_area (p, or->cost, area);
762 }
763 }
764}
765
766int
paul147193a2003-04-19 00:31:59 +0000767ospf_abr_should_announce (struct ospf *ospf,
768 struct prefix *p, struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +0000769{
paul147193a2003-04-19 00:31:59 +0000770 struct ospf_area *area;
771
772 area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
paul718e3742002-12-13 20:15:29 +0000773
774 assert (area);
775
776 if (EXPORT_NAME (area))
777 {
778 if (EXPORT_LIST (area) == NULL)
779 EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area));
780
781 if (EXPORT_LIST (area))
782 if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY)
783 return 0;
784 }
785
786 return 1;
787}
788
789#ifdef HAVE_NSSA
790void
paul147193a2003-04-19 00:31:59 +0000791ospf_abr_process_nssa_translates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000792{
793 /* Scan through all NSSA_LSDB records for all areas;
794
795 If P-bit is on, translate all Type-7's to 5's and aggregate or
796 flood install as approved in Type-5 LSDB with XLATE Flag on
797 later, do same for all aggregates... At end, DISCARD all
798 remaining UNAPPROVED Type-5's (Aggregate is for future ) */
799 listnode node;
800 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +0000801 struct route_node *rn;
802 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000803
804 if (IS_DEBUG_OSPF_NSSA)
805 zlog_info ("ospf_abr_process_nssa_translates(): Start");
806
paul147193a2003-04-19 00:31:59 +0000807 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000808 {
809 area = getdata (node);
810
811 if (! area->NSSATranslator)
812 continue; /* skip if not translator */
813
814 if (area->external_routing != OSPF_AREA_NSSA)
815 continue; /* skip if not Nssa Area */
816
817 if (IS_DEBUG_OSPF_NSSA)
818 zlog_info ("ospf_abr_process_nssa_translates(): "
819 "looking at area %s", inet_ntoa (area->area_id));
820
paul147193a2003-04-19 00:31:59 +0000821 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
822 ospf_abr_translate_nssa (area, lsa);
paul718e3742002-12-13 20:15:29 +0000823 }
824
825 if (IS_DEBUG_OSPF_NSSA)
826 zlog_info ("ospf_abr_process_nssa_translates(): Stop");
827
828}
829#endif /* HAVE_NSSA */
830
831void
paul147193a2003-04-19 00:31:59 +0000832ospf_abr_process_network_rt (struct ospf *ospf,
833 struct route_table *rt)
paul718e3742002-12-13 20:15:29 +0000834{
paul718e3742002-12-13 20:15:29 +0000835 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +0000836 struct ospf_route *or;
837 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000838
839 if (IS_DEBUG_OSPF_EVENT)
840 zlog_info ("ospf_abr_process_network_rt(): Start");
841
842 for (rn = route_top (rt); rn; rn = route_next (rn))
843 {
844 if ((or = rn->info) == NULL)
845 continue;
846
paul147193a2003-04-19 00:31:59 +0000847 if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)))
paul718e3742002-12-13 20:15:29 +0000848 {
849 if (IS_DEBUG_OSPF_EVENT)
850 zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists",
851 inet_ntoa (or->u.std.area_id));
852 continue;
853 }
854
855 if (IS_DEBUG_OSPF_EVENT)
856 zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d",
857 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
858 if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL)
859 {
860 if (IS_DEBUG_OSPF_EVENT)
861 zlog_info ("ospf_abr_process_network_rt(): "
862 "this is an External router, skipping");
863 continue;
864 }
865
866 if (or->cost >= OSPF_LS_INFINITY)
867 {
868 if (IS_DEBUG_OSPF_EVENT)
869 zlog_info ("ospf_abr_process_network_rt():"
870 " this route's cost is infinity, skipping");
871 continue;
872 }
873
874 if (or->type == OSPF_DESTINATION_DISCARD)
875 {
876 if (IS_DEBUG_OSPF_EVENT)
877 zlog_info ("ospf_abr_process_network_rt():"
878 " this is a discard entry, skipping");
879 continue;
880 }
881
882 if (or->path_type == OSPF_PATH_INTRA_AREA &&
paul147193a2003-04-19 00:31:59 +0000883 !ospf_abr_should_announce (ospf, &rn->p, or))
paul718e3742002-12-13 20:15:29 +0000884 {
885 if (IS_DEBUG_OSPF_EVENT)
886 zlog_info("ospf_abr_process_network_rt(): denied by export-list");
887 continue;
888 }
889
890 if (or->path_type == OSPF_PATH_INTRA_AREA &&
891 !ospf_abr_plist_out_check (area, or, &rn->p))
892 {
893 if (IS_DEBUG_OSPF_EVENT)
894 zlog_info("ospf_abr_process_network_rt(): denied by prefix-list");
895 continue;
896 }
897
898 if ((or->path_type == OSPF_PATH_INTER_AREA) &&
899 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
900 {
901 if (IS_DEBUG_OSPF_EVENT)
902 zlog_info ("ospf_abr_process_network_rt():"
903 " this is route is not backbone one, skipping");
904 continue;
905 }
906
907
paul147193a2003-04-19 00:31:59 +0000908 if ((ospf->abr_type == OSPF_ABR_CISCO) ||
909 (ospf->abr_type == OSPF_ABR_IBM))
paul718e3742002-12-13 20:15:29 +0000910
paul147193a2003-04-19 00:31:59 +0000911 if (!ospf_act_bb_connection (ospf) &&
paul718e3742002-12-13 20:15:29 +0000912 or->path_type != OSPF_PATH_INTRA_AREA)
913 {
914 if (IS_DEBUG_OSPF_EVENT)
915 zlog_info ("ospf_abr_process_network_rt(): ALT ABR: "
916 "No BB connection, skip not intra-area routes");
917 continue;
918 }
919
920 if (IS_DEBUG_OSPF_EVENT)
921 zlog_info ("ospf_abr_process_network_rt(): announcing");
paul147193a2003-04-19 00:31:59 +0000922 ospf_abr_announce_network (ospf, rn, or);
paul718e3742002-12-13 20:15:29 +0000923 }
924
925 if (IS_DEBUG_OSPF_EVENT)
926 zlog_info ("ospf_abr_process_network_rt(): Stop");
927}
928
929void
930ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
931 struct ospf_area *area)
932{
933 struct ospf_lsa *lsa, *old = NULL;
934 struct summary_lsa *slsa = NULL;
935
936 if (IS_DEBUG_OSPF_EVENT)
937 zlog_info ("ospf_abr_announce_rtr_to_area(): Start");
938
paul147193a2003-04-19 00:31:59 +0000939 old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA,
940 p, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000941 if (old)
942 {
943 if (IS_DEBUG_OSPF_EVENT)
944 zlog_info ("ospf_abr_announce_rtr_to_area(): old summary found");
945 slsa = (struct summary_lsa *) old->data;
946
947 if (IS_DEBUG_OSPF_EVENT)
948 zlog_info ("ospf_abr_announce_network_to_area(): "
949 "old metric: %d, new metric: %d",
950 GET_METRIC (slsa->metric), cost);
951 }
952
953 if (old && (GET_METRIC (slsa->metric) == cost))
954 {
955 if (IS_DEBUG_OSPF_EVENT)
956 zlog_info ("ospf_abr_announce_rtr_to_area(): old summary approved");
957 SET_FLAG (old->flags, OSPF_LSA_APPROVED);
958 }
959 else
960 {
961 if (IS_DEBUG_OSPF_EVENT)
962 zlog_info ("ospf_abr_announce_rtr_to_area(): 2.2");
963
964 if (old)
965 {
966 set_metric (old, cost);
paul147193a2003-04-19 00:31:59 +0000967 lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
paul718e3742002-12-13 20:15:29 +0000968 }
969 else
970 lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
971
972 if (IS_DEBUG_OSPF_EVENT)
973 zlog_info ("ospf_abr_announce_rtr_to_area(): "
974 "flooding new version of summary");
975 /*
976 zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary");
977 lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
978
979 SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
980 /* ospf_flood_through_area (area, NULL, lsa);*/
981 }
982
983 if (IS_DEBUG_OSPF_EVENT)
984 zlog_info ("ospf_abr_announce_rtr_to_area(): Stop");
985}
986
987
988void
paul147193a2003-04-19 00:31:59 +0000989ospf_abr_announce_rtr (struct ospf *ospf,
990 struct prefix_ipv4 *p, struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +0000991{
992 listnode node;
993 struct ospf_area *area;
994
995 if (IS_DEBUG_OSPF_EVENT)
996 zlog_info ("ospf_abr_announce_rtr(): Start");
997
paul147193a2003-04-19 00:31:59 +0000998 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000999 {
1000 area = getdata (node);
1001
1002 if (IS_DEBUG_OSPF_EVENT)
1003 zlog_info ("ospf_abr_announce_rtr(): looking at area %s",
1004 inet_ntoa (area->area_id));
1005
1006 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
1007 continue;
1008
1009 if (ospf_abr_nexthops_belong_to_area (or, area))
1010 continue;
1011
1012 if (area->external_routing != OSPF_AREA_DEFAULT)
1013 {
1014 if (IS_DEBUG_OSPF_EVENT)
1015 zlog_info ("ospf_abr_announce_network(): "
1016 "area %s doesn't support external routing",
1017 inet_ntoa(area->area_id));
1018 continue;
1019 }
1020
1021 if (or->path_type == OSPF_PATH_INTER_AREA)
1022 {
1023 if (IS_DEBUG_OSPF_EVENT)
1024 zlog_info ("ospf_abr_announce_rtr(): "
1025 "this is inter-area route to %s", inet_ntoa (p->prefix));
1026 if (!OSPF_IS_AREA_BACKBONE (area))
1027 ospf_abr_announce_rtr_to_area (p, or->cost, area);
1028 }
1029
1030 if (or->path_type == OSPF_PATH_INTRA_AREA)
1031 {
1032 if (IS_DEBUG_OSPF_EVENT)
1033 zlog_info ("ospf_abr_announce_rtr(): "
1034 "this is intra-area route to %s", inet_ntoa (p->prefix));
1035 ospf_abr_announce_rtr_to_area (p, or->cost, area);
1036 }
1037 }
1038
1039 if (IS_DEBUG_OSPF_EVENT)
1040 zlog_info ("ospf_abr_announce_rtr(): Stop");
1041}
1042
1043void
paul147193a2003-04-19 00:31:59 +00001044ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
paul718e3742002-12-13 20:15:29 +00001045{
paul718e3742002-12-13 20:15:29 +00001046 struct ospf_route *or;
paul147193a2003-04-19 00:31:59 +00001047 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00001048 struct list *l;
1049
1050 if (IS_DEBUG_OSPF_EVENT)
1051 zlog_info ("ospf_abr_process_router_rt(): Start");
1052
1053 for (rn = route_top (rt); rn; rn = route_next (rn))
1054 {
1055 listnode node;
1056 char flag = 0;
1057 struct ospf_route *best = NULL;
1058
1059 if (rn->info == NULL)
1060 continue;
1061
1062 l = rn->info;
1063
1064 if (IS_DEBUG_OSPF_EVENT)
1065 zlog_info ("ospf_abr_process_router_rt(): this is a route to %s",
1066 inet_ntoa (rn->p.u.prefix4));
1067
1068 for (node = listhead (l); node; nextnode (node))
1069 {
1070 or = getdata (node);
1071 if (or == NULL)
1072 continue;
1073
paul147193a2003-04-19 00:31:59 +00001074 if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))
paul718e3742002-12-13 20:15:29 +00001075 {
1076 if (IS_DEBUG_OSPF_EVENT)
1077 zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists",
1078 inet_ntoa (or->u.std.area_id));
1079 continue;
1080 }
1081
1082
1083 if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL))
1084 {
1085 if (IS_DEBUG_OSPF_EVENT)
1086 zlog_info ("ospf_abr_process_router_rt(): "
1087 "This is not an ASBR, skipping");
1088 continue;
1089 }
1090
1091 if (!flag)
1092 {
paul147193a2003-04-19 00:31:59 +00001093 best = ospf_find_asbr_route (ospf, rt,
1094 (struct prefix_ipv4 *) &rn->p);
paul718e3742002-12-13 20:15:29 +00001095 flag = 1;
1096 }
1097
1098 if (best == NULL)
1099 continue;
1100
1101 if (or != best)
1102 {
1103 if (IS_DEBUG_OSPF_EVENT)
1104 zlog_info ("ospf_abr_process_router_rt(): "
1105 "This route is not the best among possible, skipping");
1106 continue;
1107 }
1108
1109 if (or->path_type == OSPF_PATH_INTER_AREA &&
1110 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1111 {
1112 if (IS_DEBUG_OSPF_EVENT)
1113 zlog_info ("ospf_abr_process_router_rt(): "
1114 "This route is not a backbone one, skipping");
1115 continue;
1116 }
1117
1118 if (or->cost >= OSPF_LS_INFINITY)
1119 {
1120 if (IS_DEBUG_OSPF_EVENT)
1121 zlog_info ("ospf_abr_process_router_rt(): "
1122 "This route has LS_INFINITY metric, skipping");
1123 continue;
1124 }
1125
paul147193a2003-04-19 00:31:59 +00001126 if (ospf->abr_type == OSPF_ABR_CISCO
1127 || ospf->abr_type == OSPF_ABR_IBM)
1128 if (!ospf_act_bb_connection (ospf)
1129 && or->path_type != OSPF_PATH_INTRA_AREA)
paul718e3742002-12-13 20:15:29 +00001130 {
1131 if (IS_DEBUG_OSPF_EVENT)
1132 zlog_info("ospf_abr_process_network_rt(): ALT ABR: "
1133 "No BB connection, skip not intra-area routes");
1134 continue;
1135 }
1136
paul147193a2003-04-19 00:31:59 +00001137 ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or);
paul718e3742002-12-13 20:15:29 +00001138
1139 }
1140
1141 }
1142
1143 if (IS_DEBUG_OSPF_EVENT)
1144 zlog_info ("ospf_abr_process_router_rt(): Stop");
1145}
1146
1147#ifdef HAVE_NSSA
paul718e3742002-12-13 20:15:29 +00001148void
paul147193a2003-04-19 00:31:59 +00001149ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
paul718e3742002-12-13 20:15:29 +00001150{
paul147193a2003-04-19 00:31:59 +00001151 struct ospf_lsa *lsa;
1152 struct route_node *rn;
1153
paul718e3742002-12-13 20:15:29 +00001154 if (IS_DEBUG_OSPF_NSSA)
1155 zlog_info ("ospf_abr_unapprove_translates(): Start");
1156
1157 /* NSSA Translator is not checked, because it may have gone away,
1158 and we would want to flush any residuals anyway */
1159
paul147193a2003-04-19 00:31:59 +00001160 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1161 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1162 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
paul718e3742002-12-13 20:15:29 +00001163
1164 if (IS_DEBUG_OSPF_NSSA)
1165 zlog_info ("ospf_abr_unapprove_translates(): Stop");
1166}
1167#endif /* HAVE_NSSA */
1168
paul718e3742002-12-13 20:15:29 +00001169void
paul147193a2003-04-19 00:31:59 +00001170ospf_abr_unapprove_summaries (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001171{
1172 listnode node;
1173 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001174 struct route_node *rn;
1175 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00001176
1177 if (IS_DEBUG_OSPF_EVENT)
1178 zlog_info ("ospf_abr_unapprove_summaries(): Start");
1179
paul147193a2003-04-19 00:31:59 +00001180 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001181 {
1182 area = getdata (node);
paul147193a2003-04-19 00:31:59 +00001183 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1184 if (ospf_lsa_is_self_originated (ospf, lsa))
1185 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1186
1187 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1188 if (ospf_lsa_is_self_originated (ospf, lsa))
1189 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
paul718e3742002-12-13 20:15:29 +00001190 }
1191
1192 if (IS_DEBUG_OSPF_EVENT)
1193 zlog_info ("ospf_abr_unapprove_summaries(): Stop");
1194}
1195
1196void
paul147193a2003-04-19 00:31:59 +00001197ospf_abr_prepare_aggregates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001198{
1199 listnode node;
1200 struct route_node *rn;
1201 struct ospf_area_range *range;
1202
1203 if (IS_DEBUG_OSPF_EVENT)
1204 zlog_info ("ospf_abr_prepare_aggregates(): Start");
1205
paul147193a2003-04-19 00:31:59 +00001206 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001207 {
1208 struct ospf_area *area = getdata (node);
1209
1210 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1211 if ((range = rn->info) != NULL)
1212 {
1213 range->cost = 0;
1214 range->specifics = 0;
1215 }
1216 }
1217
1218 if (IS_DEBUG_OSPF_EVENT)
1219 zlog_info ("ospf_abr_prepare_aggregates(): Stop");
1220}
1221
1222void
paul147193a2003-04-19 00:31:59 +00001223ospf_abr_announce_aggregates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001224{
1225 struct ospf_area *area, *ar;
1226 struct ospf_area_range *range;
1227 struct route_node *rn;
1228 struct prefix_ipv4 p;
1229 listnode node, n;
1230
1231 if (IS_DEBUG_OSPF_EVENT)
1232 zlog_info ("ospf_abr_announce_aggregates(): Start");
1233
paul147193a2003-04-19 00:31:59 +00001234 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001235 {
1236 area = getdata (node);
1237
1238 if (IS_DEBUG_OSPF_EVENT)
1239 zlog_info ("ospf_abr_announce_aggregates(): looking at area %s",
1240 inet_ntoa (area->area_id));
1241
1242 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1243 if ((range = rn->info))
1244 {
1245 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1246 {
1247 if (IS_DEBUG_OSPF_EVENT)
1248 zlog_info ("ospf_abr_announce_aggregates():"
1249 " discarding suppress-ranges");
1250 continue;
1251 }
1252
1253 p.family = AF_INET;
1254 p.prefix = range->addr;
1255 p.prefixlen = range->masklen;
1256
1257 if (IS_DEBUG_OSPF_EVENT)
1258 zlog_info ("ospf_abr_announce_aggregates():"
1259 " this is range: %s/%d",
1260 inet_ntoa (p.prefix), p.prefixlen);
1261
1262 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1263 {
1264 p.family = AF_INET;
1265 p.prefix = range->subst_addr;
1266 p.prefixlen = range->subst_masklen;
1267 }
1268
1269 if (range->specifics)
1270 {
1271 if (IS_DEBUG_OSPF_EVENT)
1272 zlog_info ("ospf_abr_announce_aggregates(): active range");
1273
paul147193a2003-04-19 00:31:59 +00001274 for (n = listhead (ospf->areas); n; nextnode (n))
paul718e3742002-12-13 20:15:29 +00001275 {
1276 ar = getdata (n);
1277 if (ar == area)
1278 continue;
1279
1280 /* We do not check nexthops here, because
1281 intra-area routes can be associated with
1282 one area only */
1283
1284 /* backbone routes are not summarized
1285 when announced into transit areas */
1286
1287 if (ospf_area_is_transit (ar) &&
1288 OSPF_IS_AREA_BACKBONE (area))
1289 {
1290 if (IS_DEBUG_OSPF_EVENT)
1291 zlog_info ("ospf_abr_announce_aggregates(): Skipping "
1292 "announcement of BB aggregate into"
1293 " a transit area");
1294 continue;
1295 }
1296 ospf_abr_announce_network_to_area (&p, range->cost, ar);
1297 }
1298 }
1299 }
1300 }
1301
1302 if (IS_DEBUG_OSPF_EVENT)
1303 zlog_info ("ospf_abr_announce_aggregates(): Stop");
1304}
1305
1306#ifdef HAVE_NSSA
1307void
paul147193a2003-04-19 00:31:59 +00001308ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
paul718e3742002-12-13 20:15:29 +00001309{
1310 listnode node; /*, n; */
1311 struct ospf_area *area; /*, *ar; */
1312 struct route_node *rn;
1313 struct ospf_area_range *range;
1314 struct prefix_ipv4 p;
1315
1316 if (IS_DEBUG_OSPF_NSSA)
1317 zlog_info ("ospf_abr_send_nssa_aggregates(): Start");
1318
paul147193a2003-04-19 00:31:59 +00001319 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001320 {
1321 area = getdata (node);
1322
1323 if (! area->NSSATranslator)
1324 continue;
1325
1326 if (IS_DEBUG_OSPF_NSSA)
1327 zlog_info ("ospf_abr_send_nssa_aggregates(): looking at area %s",
1328 inet_ntoa (area->area_id));
1329
1330 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1331 {
1332 if (rn->info == NULL)
1333 continue;
1334
1335 range = rn->info;
1336
1337 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1338 {
1339 if (IS_DEBUG_OSPF_NSSA)
1340 zlog_info ("ospf_abr_send_nssa_aggregates():"
1341 " discarding suppress-ranges");
1342 continue;
1343 }
1344
1345 p.family = AF_INET;
1346 p.prefix = range->addr;
1347 p.prefixlen = range->masklen;
1348
1349 if (IS_DEBUG_OSPF_NSSA)
1350 zlog_info ("ospf_abr_send_nssa_aggregates():"
1351 " this is range: %s/%d",
1352 inet_ntoa (p.prefix), p.prefixlen);
1353
1354 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1355 {
1356 p.family = AF_INET;
1357 p.prefix = range->subst_addr;
1358 p.prefixlen = range->subst_masklen;
1359 }
1360
1361 if (range->specifics)
1362 {
1363 if (IS_DEBUG_OSPF_NSSA)
1364 zlog_info ("ospf_abr_send_nssa_aggregates(): active range");
1365
1366 /* Fetch LSA-Type-7 from aggregate prefix, and then
1367 translate, Install (as Type-5), Approve, and Flood */
1368 ospf_abr_translate_nssa_range (&p, range->cost);
1369 } /* if (range->specifics)*/
1370 } /* all area ranges*/
1371 } /* all areas */
1372
1373 if (IS_DEBUG_OSPF_NSSA)
1374 zlog_info ("ospf_abr_send_nssa_aggregates(): Stop");
1375}
1376
1377void
paul147193a2003-04-19 00:31:59 +00001378ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
paul718e3742002-12-13 20:15:29 +00001379{
1380 listnode node;
1381 struct ospf_area *area;
1382 struct prefix_ipv4 p;
1383
paul147193a2003-04-19 00:31:59 +00001384 if (! IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001385 return;
1386
1387 if (IS_DEBUG_OSPF_NSSA)
1388 zlog_info ("ospf_abr_announce_stub_defaults(): Start");
1389
1390 p.family = AF_INET;
1391 p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1392 p.prefixlen = 0;
1393
paul147193a2003-04-19 00:31:59 +00001394 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001395 {
1396 area = getdata (node);
1397 if (IS_DEBUG_OSPF_NSSA)
1398 zlog_info ("ospf_abr_announce_nssa_defaults(): looking at area %s",
1399 inet_ntoa (area->area_id));
1400
1401 if (area->external_routing != OSPF_AREA_NSSA)
1402 continue;
1403
1404 if (OSPF_IS_AREA_BACKBONE (area))
1405 continue; /* Sanity Check */
1406
1407 /* if (!TranslatorRole continue V 1.0 look for "always" conf */
1408 if (area->NSSATranslator)
1409 {
1410 if (IS_DEBUG_OSPF_NSSA)
1411 zlog_info ("ospf_abr_announce_nssa_defaults(): "
1412 "announcing 0.0.0.0/0 to this nssa");
1413 /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
1414 }
1415 }
1416}
1417#endif /* HAVE_NSSA */
1418
1419void
paul147193a2003-04-19 00:31:59 +00001420ospf_abr_announce_stub_defaults (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001421{
1422 listnode node;
1423 struct ospf_area *area;
1424 struct prefix_ipv4 p;
1425
paul147193a2003-04-19 00:31:59 +00001426 if (! IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001427 return;
1428
1429 if (IS_DEBUG_OSPF_EVENT)
1430 zlog_info ("ospf_abr_announce_stub_defaults(): Start");
1431
1432 p.family = AF_INET;
1433 p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1434 p.prefixlen = 0;
1435
paul147193a2003-04-19 00:31:59 +00001436 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001437 {
1438 area = getdata (node);
1439 if (IS_DEBUG_OSPF_EVENT)
1440 zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s",
1441 inet_ntoa (area->area_id));
1442
1443#ifdef HAVE_NSSA
1444 if (area->external_routing != OSPF_AREA_STUB)
1445#else /* ! HAVE_NSSA */
1446 if (area->external_routing == OSPF_AREA_DEFAULT)
1447#endif /* HAVE_NSSA */
1448 continue;
1449
1450 if (OSPF_IS_AREA_BACKBONE (area))
1451 continue; /* Sanity Check */
1452
1453 if (IS_DEBUG_OSPF_EVENT)
1454 zlog_info ("ospf_abr_announce_stub_defaults(): "
1455 "announcing 0.0.0.0/0 to this area");
1456 ospf_abr_announce_network_to_area (&p, area->default_cost, area);
1457 }
1458
1459 if (IS_DEBUG_OSPF_EVENT)
1460 zlog_info ("ospf_abr_announce_stub_defaults(): Stop");
1461}
1462
1463#ifdef HAVE_NSSA
1464int
paul147193a2003-04-19 00:31:59 +00001465ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
1466 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001467{
1468 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)
1469 && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1470 {
1471 zlog_info ("ospf_abr_remove_unapproved_translates(): "
1472 "removing unapproved translates, ID: %s",
1473 inet_ntoa (lsa->data->id));
1474
1475 /* FLUSH THROUGHOUT AS */
paul147193a2003-04-19 00:31:59 +00001476 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001477
1478 /* DISCARD from LSDB */
1479 }
1480 return 0;
1481}
1482
1483void
paul147193a2003-04-19 00:31:59 +00001484ospf_abr_remove_unapproved_translates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001485{
paul147193a2003-04-19 00:31:59 +00001486 struct route_node *rn;
1487 struct ospf_lsa *lsa;
1488
paul718e3742002-12-13 20:15:29 +00001489 /* All AREA PROCESS should have APPROVED necessary LSAs */
1490 /* Remove any left over and not APPROVED */
1491 if (IS_DEBUG_OSPF_NSSA)
1492 zlog_info ("ospf_abr_remove_unapproved_translates(): Start");
1493
paul147193a2003-04-19 00:31:59 +00001494 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1495 ospf_abr_remove_unapproved_translates_apply (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001496
1497 if (IS_DEBUG_OSPF_NSSA)
1498 zlog_info ("ospf_abr_remove_unapproved_translates(): Stop");
1499}
1500#endif /* HAVE_NSSA */
1501
paul718e3742002-12-13 20:15:29 +00001502void
paul147193a2003-04-19 00:31:59 +00001503ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001504{
1505 listnode node;
1506 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001507 struct route_node *rn;
1508 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00001509
1510 if (IS_DEBUG_OSPF_EVENT)
1511 zlog_info ("ospf_abr_remove_unapproved_summaries(): Start");
1512
paul147193a2003-04-19 00:31:59 +00001513 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001514 {
1515 area = getdata (node);
1516
1517 if (IS_DEBUG_OSPF_EVENT)
1518 zlog_info ("ospf_abr_remove_unapproved_summaries(): "
1519 "looking at area %s", inet_ntoa (area->area_id));
1520
paul147193a2003-04-19 00:31:59 +00001521 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1522 if (ospf_lsa_is_self_originated (ospf, lsa))
1523 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1524 ospf_lsa_flush_area (lsa, area);
1525
1526 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1527 if (ospf_lsa_is_self_originated (ospf, lsa))
1528 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1529 ospf_lsa_flush_area (lsa, area);
paul718e3742002-12-13 20:15:29 +00001530 }
1531
1532 if (IS_DEBUG_OSPF_EVENT)
1533 zlog_info ("ospf_abr_remove_unapproved_summaries(): Stop");
1534}
1535
1536void
paul147193a2003-04-19 00:31:59 +00001537ospf_abr_manage_discard_routes (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001538{
1539 listnode node;
1540 struct route_node *rn;
1541 struct ospf_area *area;
1542 struct ospf_area_range *range;
1543
paul147193a2003-04-19 00:31:59 +00001544 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001545 if ((area = node->data) != NULL)
1546 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1547 if ((range = rn->info) != NULL)
1548 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1549 {
1550 if (range->specifics)
paul147193a2003-04-19 00:31:59 +00001551 ospf_add_discard_route (ospf->new_table, area,
paul718e3742002-12-13 20:15:29 +00001552 (struct prefix_ipv4 *) &rn->p);
1553 else
1554 ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
1555 }
1556}
1557
1558#ifdef HAVE_NSSA
1559/* This is the function taking care about ABR NSSA, i.e. NSSA
1560 Translator, -LSA aggregation and flooding. For all NSSAs
1561
1562 Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's
1563 are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
1564 with the P-bit set.
1565
1566 Any received Type-5s are legal for an ABR, else illegal for IR.
1567 Received Type-7s are installed, by area, with incoming P-bit. They
1568 are flooded; if the Elected NSSA Translator, then P-bit off.
1569
1570 Additionally, this ABR will place "translated type-7's" into the
1571 Type-5 LSDB in order to keep track of APPROVAL or not.
1572
1573 It will scan through every area, looking for Type-7 LSAs with P-Bit
1574 SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
1575 AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED &
1576 5-INSTALLED.
1577
1578 5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
1579 left over are FLUSHED and DISCARDED.
1580
1581 For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
1582 any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
1583
1584void
paul147193a2003-04-19 00:31:59 +00001585ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */
paul718e3742002-12-13 20:15:29 +00001586{
1587 if (IS_DEBUG_OSPF_NSSA)
1588 zlog_info ("Check for NSSA-ABR Tasks():");
1589
paul147193a2003-04-19 00:31:59 +00001590 if (! IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001591 return;
1592
paul147193a2003-04-19 00:31:59 +00001593 if (! ospf->anyNSSA)
paul718e3742002-12-13 20:15:29 +00001594 return;
1595
1596 /* Each area must confirm TranslatorRole */
1597 if (IS_DEBUG_OSPF_NSSA)
1598 zlog_info ("ospf_abr_nssa_task(): Start");
1599
1600 /* For all Global Entries flagged "local-translate", unset APPROVED */
1601 if (IS_DEBUG_OSPF_NSSA)
1602 zlog_info ("ospf_abr_nssa_task(): unapprove translates");
1603
paul147193a2003-04-19 00:31:59 +00001604 ospf_abr_unapprove_translates (ospf);
paul718e3742002-12-13 20:15:29 +00001605
1606 /* RESET all Ranges in every Area, same as summaries */
1607 if (IS_DEBUG_OSPF_NSSA)
1608 zlog_info ("ospf_abr_nssa_task(): NSSA initialize aggregates");
1609
1610 /* ospf_abr_prepare_aggregates (); TURNED OFF just for now */
1611
1612 /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
1613 Aggregate as Type-7 */
1614 /* Install or Approve in Type-5 Global LSDB */
1615 if (IS_DEBUG_OSPF_NSSA)
1616 zlog_info ("ospf_abr_nssa_task(): process translates");
1617
paul147193a2003-04-19 00:31:59 +00001618 ospf_abr_process_nssa_translates (ospf);
paul718e3742002-12-13 20:15:29 +00001619
1620 /* Translate/Send any "ranged" aggregates, and also 5-Install and
1621 Approve */
1622 /* Scan Type-7's for aggregates, translate to Type-5's,
1623 Install/Flood/Approve */
1624 if (IS_DEBUG_OSPF_NSSA)
1625 zlog_info("ospf_abr_nssa_task(): send NSSA aggregates");
1626 /* ospf_abr_send_nssa_aggregates (); TURNED OFF FOR NOW */
1627
1628 /* Send any NSSA defaults as Type-5 */
1629 if (IS_DEBUG_OSPF_NSSA)
1630 zlog_info ("ospf_abr_nssa_task(): announce nssa defaults");
paul147193a2003-04-19 00:31:59 +00001631 ospf_abr_announce_nssa_defaults (ospf);
paul718e3742002-12-13 20:15:29 +00001632
1633 /* Flush any unapproved previous translates from Global Data Base */
1634 if (IS_DEBUG_OSPF_NSSA)
1635 zlog_info ("ospf_abr_nssa_task(): remove unapproved translates");
paul147193a2003-04-19 00:31:59 +00001636 ospf_abr_remove_unapproved_translates (ospf);
paul718e3742002-12-13 20:15:29 +00001637
paul147193a2003-04-19 00:31:59 +00001638 ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */
paul718e3742002-12-13 20:15:29 +00001639
1640 if (IS_DEBUG_OSPF_NSSA)
1641 zlog_info ("ospf_abr_nssa_task(): Stop");
1642}
1643#endif /* HAVE_NSSA */
1644
1645/* This is the function taking care about ABR stuff, i.e.
1646 summary-LSA origination and flooding. */
1647void
paul147193a2003-04-19 00:31:59 +00001648ospf_abr_task (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001649{
1650 if (IS_DEBUG_OSPF_EVENT)
1651 zlog_info ("ospf_abr_task(): Start");
1652
paul147193a2003-04-19 00:31:59 +00001653 if (ospf->new_table == NULL || ospf->new_rtrs == NULL)
paul718e3742002-12-13 20:15:29 +00001654 {
1655 if (IS_DEBUG_OSPF_EVENT)
1656 zlog_info ("ospf_abr_task(): Routing tables are not yet ready");
1657 return;
1658 }
1659
1660 if (IS_DEBUG_OSPF_EVENT)
1661 zlog_info ("ospf_abr_task(): unapprove summaries");
paul147193a2003-04-19 00:31:59 +00001662 ospf_abr_unapprove_summaries (ospf);
paul718e3742002-12-13 20:15:29 +00001663
1664 if (IS_DEBUG_OSPF_EVENT)
1665 zlog_info ("ospf_abr_task(): prepare aggregates");
paul147193a2003-04-19 00:31:59 +00001666 ospf_abr_prepare_aggregates (ospf);
paul718e3742002-12-13 20:15:29 +00001667
paul147193a2003-04-19 00:31:59 +00001668 if (IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001669 {
1670 if (IS_DEBUG_OSPF_EVENT)
1671 zlog_info ("ospf_abr_task(): process network RT");
paul147193a2003-04-19 00:31:59 +00001672 ospf_abr_process_network_rt (ospf, ospf->new_table);
paul718e3742002-12-13 20:15:29 +00001673
1674 if (IS_DEBUG_OSPF_EVENT)
1675 zlog_info ("ospf_abr_task(): process router RT");
paul147193a2003-04-19 00:31:59 +00001676 ospf_abr_process_router_rt (ospf, ospf->new_rtrs);
paul718e3742002-12-13 20:15:29 +00001677
1678 if (IS_DEBUG_OSPF_EVENT)
1679 zlog_info ("ospf_abr_task(): announce aggregates");
paul147193a2003-04-19 00:31:59 +00001680 ospf_abr_announce_aggregates (ospf);
paul718e3742002-12-13 20:15:29 +00001681
1682 if (IS_DEBUG_OSPF_EVENT)
1683 zlog_info ("ospf_abr_task(): announce stub defaults");
paul147193a2003-04-19 00:31:59 +00001684 ospf_abr_announce_stub_defaults (ospf);
paul718e3742002-12-13 20:15:29 +00001685 }
1686
1687 if (IS_DEBUG_OSPF_EVENT)
1688 zlog_info ("ospf_abr_task(): remove unapproved summaries");
paul147193a2003-04-19 00:31:59 +00001689 ospf_abr_remove_unapproved_summaries (ospf);
paul718e3742002-12-13 20:15:29 +00001690
paul147193a2003-04-19 00:31:59 +00001691 ospf_abr_manage_discard_routes (ospf);
paul718e3742002-12-13 20:15:29 +00001692
1693#ifdef HAVE_NSSA
paul147193a2003-04-19 00:31:59 +00001694 ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */
paul718e3742002-12-13 20:15:29 +00001695#endif /* HAVE_NSSA */
1696
1697 if (IS_DEBUG_OSPF_EVENT)
1698 zlog_info ("ospf_abr_task(): Stop");
1699}
1700
1701
1702int
paul147193a2003-04-19 00:31:59 +00001703ospf_abr_task_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001704{
paul147193a2003-04-19 00:31:59 +00001705 struct ospf *ospf = THREAD_ARG (thread);
1706
1707 ospf->t_abr_task = 0;
paul718e3742002-12-13 20:15:29 +00001708
1709 if (IS_DEBUG_OSPF_EVENT)
1710 zlog_info ("Running ABR task on timer");
1711
paul147193a2003-04-19 00:31:59 +00001712 ospf_check_abr_status (ospf);
paul718e3742002-12-13 20:15:29 +00001713
paul147193a2003-04-19 00:31:59 +00001714 ospf_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001715
paul147193a2003-04-19 00:31:59 +00001716 return 0;
paul718e3742002-12-13 20:15:29 +00001717}
1718
1719void
paul147193a2003-04-19 00:31:59 +00001720ospf_schedule_abr_task (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001721{
1722 if (IS_DEBUG_OSPF_EVENT)
1723 zlog_info ("Scheduling ABR task");
paul147193a2003-04-19 00:31:59 +00001724
1725 if (ospf->t_abr_task == NULL)
1726 ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
1727 ospf, OSPF_ABR_TASK_DELAY);
paul718e3742002-12-13 20:15:29 +00001728}