]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_abr.c
2004-02-18 Paul Jakma <paul@dishone.st>
[mirror_frr.git] / ospfd / ospf_abr.c
CommitLineData
718e3744 1/*
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"
718e3744 53\f
54struct ospf_area_range *
55ospf_area_range_new (struct prefix_ipv4 *p)
56{
57 struct ospf_area_range *range;
58
59 range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range));
60 range->addr = p->prefix;
61 range->masklen = p->prefixlen;
62 range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
63
64 return range;
65}
66
67void
68ospf_area_range_free (struct ospf_area_range *range)
69{
70 XFREE (MTYPE_OSPF_AREA_RANGE, range);
71}
72
73void
74ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)
75{
76 struct route_node *rn;
77 struct prefix_ipv4 p;
78
79 p.family = AF_INET;
80 p.prefixlen = range->masklen;
81 p.prefix = range->addr;
82
83 rn = route_node_get (area->ranges, (struct prefix *)&p);
84 if (rn->info)
85 route_unlock_node (rn);
86 else
87 rn->info = range;
88}
89
90void
91ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range)
92{
93 struct route_node *rn;
94 struct prefix_ipv4 p;
95
96 p.family = AF_INET;
97 p.prefixlen = range->masklen;
98 p.prefix = range->addr;
99
100 rn = route_node_lookup (area->ranges, (struct prefix *)&p);
101 if (rn)
102 {
103 ospf_area_range_free (rn->info);
104 rn->info = NULL;
105 route_unlock_node (rn);
106 route_unlock_node (rn);
107 }
108}
109
110struct ospf_area_range *
111ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p)
112{
113 struct route_node *rn;
114
115 rn = route_node_lookup (area->ranges, (struct prefix *)p);
116 if (rn)
117 {
118 route_unlock_node (rn);
119 return rn->info;
120 }
121 return NULL;
122}
123
124struct ospf_area_range *
d4a53d58 125ospf_area_range_lookup_next (struct ospf_area *area,
126 struct in_addr *range_net,
127 int first)
718e3744 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;
147193a2 204 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 205
147193a2 206 area = ospf_area_get (ospf, area_id, ret);
718e3744 207 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)))
147193a2 217 ospf_schedule_abr_task (ospf);
718e3744 218 }
219 else
220 {
221 range = ospf_area_range_new (p);
222 ospf_area_range_add (area, range);
147193a2 223 ospf_schedule_abr_task (ospf);
718e3744 224 }
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;
147193a2 240 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 241
147193a2 242 area = ospf_area_get (ospf, area_id, ret);
718e3744 243 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))
147193a2 254 ospf_schedule_abr_task (ospf);
718e3744 255 }
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
147193a2 267 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 268 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))
147193a2 276 ospf_schedule_abr_task (ospf);
718e3744 277
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;
147193a2 289 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 290
147193a2 291 area = ospf_area_get (ospf, area_id, ret);
718e3744 292 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))
147193a2 298 ospf_schedule_abr_task (ospf);
718e3744 299 }
300 else
301 {
302 range = ospf_area_range_new (p);
303 ospf_area_range_add (area, range);
147193a2 304 ospf_schedule_abr_task (ospf);
718e3744 305 }
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
147193a2 322 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 323 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))
147193a2 332 ospf_schedule_abr_task (ospf);
718e3744 333
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
147193a2 342ospf_act_bb_connection (struct ospf *ospf)
718e3744 343{
147193a2 344 if (ospf->backbone == NULL)
718e3744 345 return 0;
346
147193a2 347 return ospf->backbone->full_nbrs;
718e3744 348}
349
e2c6c153 350#ifdef HAVE_NSSA
351/* Determine whether this router is elected translator or not for area */
352int
353ospf_abr_nssa_am_elected (struct ospf_area *area)
354{
355 struct route_node *rn;
356 struct ospf_lsa *lsa;
357 struct router_lsa *rlsa;
358 struct in_addr *best = NULL;
359
360 LSDB_LOOP ( ROUTER_LSDB (area), rn, lsa)
361 {
362 /* sanity checks */
363 if (!lsa
364 || (lsa->data->type != OSPF_ROUTER_LSA)
365 || IS_LSA_SELF (lsa))
366 continue;
367
368 rlsa = (struct router_lsa *) lsa->data;
369
370 /* ignore non-ABR routers */
371 if (!IS_ROUTER_LSA_BORDER (rlsa))
372 continue;
373
374 /* Router has Nt flag - always translate */
375 if (IS_ROUTER_LSA_NT (rlsa))
376 {
377 if (IS_DEBUG_OSPF_NSSA)
d4a53d58 378 zlog_info ("ospf_abr_nssa_am_elected: "
e2c6c153 379 "router %s asserts Nt",
380 inet_ntoa (lsa->data->id) );
381 return 0;
382 }
383
384 if (best == NULL)
385 best = &lsa->data->id;
386 else
387 if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0)
388 best = &lsa->data->id;
389 }
390
391 if (IS_DEBUG_OSPF_NSSA)
392 zlog_info ("ospf_abr_nssa_am_elected: best electable ABR is: %s",
393 (best) ? inet_ntoa (*best) : "<none>" );
394
395 if (best == NULL)
396 return 1;
397
398 if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0)
399 return 1;
400 else
401 return 0;
402}
403
404/* Check NSSA ABR status
405 * assumes there are nssa areas
406 */
407void
408ospf_abr_nssa_check_status (struct ospf *ospf)
409{
410 struct ospf_area *area;
411 listnode lnode;
412
413 LIST_LOOP (ospf->areas, area, lnode)
414 {
415
416 if (area->external_routing != OSPF_AREA_NSSA)
417 continue;
418
419 if (IS_DEBUG_OSPF (nssa, NSSA))
420 zlog_info ("ospf_abr_nssa_check_status: "
421 "checking area %s",
422 inet_ntoa (area->area_id));
423
424 if (!IS_OSPF_ABR (area->ospf))
425 {
426 if (IS_DEBUG_OSPF (nssa, NSSA))
427 zlog_info ("ospf_abr_nssa_check_status: "
428 "not ABR");
d4a53d58 429 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
e2c6c153 430 continue;
431 }
432
433 switch (area->NSSATranslatorRole)
434 {
435 case OSPF_NSSA_ROLE_NEVER:
436 /* We never Translate Type-7 LSA. */
437 /* TODO: check previous state and flush? */
438 if (IS_DEBUG_OSPF (nssa, NSSA))
439 zlog_info ("ospf_abr_nssa_check_status: "
440 "never translate");
d4a53d58 441 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
e2c6c153 442 continue;
443
444 case OSPF_NSSA_ROLE_ALWAYS:
445 /* We always translate if we are an ABR
446 * TODO: originate new LSAs if state change?
447 * or let the nssa abr task take care of it?
448 */
449 if (IS_DEBUG_OSPF (nssa, NSSA))
450 zlog_info ("ospf_abr_nssa_check_status: "
451 "translate always");
d4a53d58 452 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
e2c6c153 453 continue;
454
455 case OSPF_NSSA_ROLE_CANDIDATE:
456 /* We are a candidate for Translation */
457 if (ospf_abr_nssa_am_elected (area) > 0 )
458 {
d4a53d58 459 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
e2c6c153 460 if (IS_DEBUG_OSPF (nssa, NSSA))
461 zlog_info ("ospf_abr_nssa_check_status: "
462 "elected translator");
463 }
464 else
465 {
d4a53d58 466 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
e2c6c153 467 if (IS_DEBUG_OSPF (nssa, NSSA))
468 zlog_info ("ospf_abr_nssa_check_status: "
469 "not elected");
470 }
471 continue;
472 }
473 }
474}
475#endif /* HAVE_NSSA */
476
718e3744 477/* Check area border router status. */
478void
147193a2 479ospf_check_abr_status (struct ospf *ospf)
718e3744 480{
481 struct ospf_area *area;
482 listnode node;
483 int bb_configured = 0;
484 int bb_act_attached = 0;
485 int areas_configured = 0;
486 int areas_act_attached = 0;
147193a2 487 u_char new_flags = ospf->flags;
718e3744 488
489 if (IS_DEBUG_OSPF_EVENT)
490 zlog_info ("ospf_check_abr_status(): Start");
491
147193a2 492 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 493 {
494 area = getdata (node);
e2c6c153 495
718e3744 496 if (listcount (area->oiflist))
497 {
498 areas_configured++;
499
500 if (OSPF_IS_AREA_BACKBONE (area))
501 bb_configured = 1;
502 }
503
504 if (ospf_area_actively_attached (area))
505 {
506 areas_act_attached++;
507
508 if (OSPF_IS_AREA_BACKBONE (area))
509 bb_act_attached = 1;
510 }
511 }
512
513 if (IS_DEBUG_OSPF_EVENT)
514 {
515 zlog_info ("ospf_check_abr_status(): looked through areas");
516 zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured);
517 zlog_info ("ospf_check_abr_status(): bb_act_attached: %d",
518 bb_act_attached);
519 zlog_info ("ospf_check_abr_status(): areas_configured: %d",
520 areas_configured);
521 zlog_info ("ospf_check_abr_status(): areas_act_attached: %d",
522 areas_act_attached);
523 }
524
147193a2 525 switch (ospf->abr_type)
718e3744 526 {
527 case OSPF_ABR_SHORTCUT:
528 case OSPF_ABR_STAND:
529 if (areas_act_attached > 1)
530 SET_FLAG (new_flags, OSPF_FLAG_ABR);
531 else
532 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
533 break;
534
535 case OSPF_ABR_IBM:
536 if ((areas_act_attached > 1) && bb_configured)
537 SET_FLAG (new_flags, OSPF_FLAG_ABR);
538 else
539 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
540 break;
541
542 case OSPF_ABR_CISCO:
543 if ((areas_configured > 1) && bb_act_attached)
544 SET_FLAG (new_flags, OSPF_FLAG_ABR);
545 else
546 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
547 break;
548 default:
549 break;
550 }
551
147193a2 552 if (new_flags != ospf->flags)
718e3744 553 {
147193a2 554 ospf_spf_calculate_schedule (ospf);
718e3744 555 if (IS_DEBUG_OSPF_EVENT)
556 zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags);
147193a2 557 ospf->flags = new_flags;
558 OSPF_TIMER_ON (ospf->t_router_lsa_update,
718e3744 559 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
560 }
561}
562
563void
564ospf_abr_update_aggregate (struct ospf_area_range *range,
565 struct ospf_route *or)
566{
567 if (IS_DEBUG_OSPF_EVENT)
568 zlog_info ("ospf_abr_update_aggregate(): Start");
569
570 if (range->cost_config != -1)
571 {
572 if (IS_DEBUG_OSPF_EVENT)
573 zlog_info ("ospf_abr_update_aggregate(): use configured cost %d",
574 range->cost_config);
575
576 range->cost = range->cost_config;
577 }
578 else
579 {
580 if (range->specifics == 0)
581 range->cost = or->cost; /* 1st time get 1st cost */
582
583 if (or->cost < range->cost)
584 {
585 if (IS_DEBUG_OSPF_EVENT)
586 zlog_info ("ospf_abr_update_aggregate(): lowest cost, update");
587
588 range->cost = or->cost;
589 }
590 }
591
592 range->specifics++;
593}
594
595static void
596set_metric (struct ospf_lsa *lsa, u_int32_t metric)
597{
598 struct summary_lsa *header;
599 u_char *mp;
600 metric = htonl (metric);
601 mp = (char *) &metric;
602 mp++;
603 header = (struct summary_lsa *) lsa->data;
604 memcpy(header->metric, mp, 3);
605}
606
607#ifdef HAVE_NSSA
608int
609ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost,
610 struct ospf_area *area)
611{
612 /* The Type-7 is tested against the aggregated prefix and forwarded
613 for lsa installation and flooding */
614 return 0;
615}
616
617/* ospf_abr_translate_nssa */
618int
147193a2 619ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
718e3744 620{
621 /* Incoming Type-7 or later aggregated Type-7
d4a53d58 622 *
623 * LSA is skipped if P-bit is off.
624 * LSA is aggregated if within range.
625 *
626 * The Type-7 is translated, Installed/Approved as a Type-5 into
627 * global LSDB, then Flooded through AS
628 *
629 * Later, any Unapproved Translated Type-5's are flushed/discarded
630 */
718e3744 631
d4a53d58 632 struct ospf_lsa *old = NULL,
633 *new = NULL;
634 struct as_external_lsa *ext7;
635 struct prefix_ipv4 p;
718e3744 636
637 if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
638 {
639 if (IS_DEBUG_OSPF_NSSA)
d4a53d58 640 zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation",
641 inet_ntoa (lsa->data->id));
642 return 1;
718e3744 643 }
d4a53d58 644
718e3744 645 if (IS_DEBUG_OSPF_NSSA)
d4a53d58 646 zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5",
647 inet_ntoa (lsa->data->id));
718e3744 648
d4a53d58 649 ext7 = (struct as_external_lsa *)(lsa->data);
650 p.prefix = lsa->data->id;
651 p.prefixlen = ip_masklen (ext7->mask);
652
653 if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION)
654 {
655 if (IS_DEBUG_OSPF_NSSA)
656 zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, "
657 "Forward address is 0, NO Translation",
658 inet_ntoa (lsa->data->id));
659 return 1;
660 }
661
662 /* try find existing AS-External LSA for this prefix */
663
664 old = ospf_external_info_find_lsa (area->ospf, &p);
665
666 if (old)
667 {
668 if (IS_DEBUG_OSPF_NSSA)
669 zlog_info ("ospf_abr_translate_nssa(): "
670 "found old translated LSA Id %s, refreshing",
671 inet_ntoa (old->data->id));
672
673 /* refresh */
674 new = ospf_translated_nssa_refresh (area->ospf, lsa, old);
675 if (!new)
676 {
677 if (IS_DEBUG_OSPF_NSSA)
678 zlog_info ("ospf_abr_translate_nssa(): "
679 "could not refresh translated LSA Id %s",
680 inet_ntoa (old->data->id));
681 }
682 }
683 else
684 {
685 /* no existing external route for this LSA Id
686 * originate translated LSA
687 */
688
689 if ((new = ospf_translated_nssa_originate (area->ospf, lsa))
690 == NULL)
691 {
692 if (IS_DEBUG_OSPF_NSSA)
693 zlog_info ("ospf_abr_translate_nssa(): Could not translate "
694 "Type-7 for %s to Type-5",
695 inet_ntoa (lsa->data->id));
696 return 1;
697 }
698 }
718e3744 699
700 /* Area where Aggregate testing will be inserted, just like summary
701 advertisements */
702 /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
703
718e3744 704 return 0;
705}
706
707void
708ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost)
709{
710 /* The Type-7 is created from the aggregated prefix and forwarded
711 for lsa installation and flooding... to be added... */
712}
713#endif /* HAVE_NSSA */
714
715void
716ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
717 struct ospf_area *area)
718{
719 struct ospf_lsa *lsa, *old = NULL;
720 struct summary_lsa *sl = NULL;
721
722 if (IS_DEBUG_OSPF_EVENT)
723 zlog_info ("ospf_abr_announce_network_to_area(): Start");
724
d4a53d58 725 old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA,
726 (struct prefix_ipv4 *) p,
727 area->ospf->router_id);
718e3744 728 if (old)
729 {
730 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 731 zlog_info ("ospf_abr_announce_network_to_area(): old summary found");
718e3744 732
d4a53d58 733 sl = (struct summary_lsa *) old->data;
718e3744 734
718e3744 735 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 736 zlog_info ("ospf_abr_announce_network_to_area(): "
737 "old metric: %d, new metric: %d",
738 GET_METRIC (sl->metric), cost);
739
740 if (GET_METRIC (sl->metric) == cost)
741 {
742 /* unchanged. simply reapprove it */
743 if (IS_DEBUG_OSPF_EVENT)
744 zlog_info ("ospf_abr_announce_network_to_area(): "
745 "old summary approved");
746 SET_FLAG (old->flags, OSPF_LSA_APPROVED);
747 }
748 else
749 {
750 /* LSA is changed, refresh it */
751 if (IS_DEBUG_OSPF_EVENT)
752 zlog_info ("ospf_abr_announce_network_to_area(): "
753 "refreshing summary");
754 set_metric (old, cost);
755 lsa = ospf_summary_lsa_refresh (area->ospf, old);
756 /* This will flood through area. */
757 }
718e3744 758 }
759 else
760 {
761 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 762 zlog_info ("ospf_abr_announce_network_to_area(): "
763 "creating new summary");
764 lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area);
765 /* This will flood through area. */
718e3744 766
718e3744 767 SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
768 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 769 zlog_info ("ospf_abr_announce_network_to_area(): "
770 "flooding new version of summary");
718e3744 771 }
772
773 if (IS_DEBUG_OSPF_EVENT)
774 zlog_info ("ospf_abr_announce_network_to_area(): Stop");
775}
776
777int
778ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
779 struct ospf_area *area)
780{
781 listnode node;
96735eea 782 struct ospf_path *path;
718e3744 783
96735eea 784 LIST_LOOP (or->paths, path, node)
718e3744 785 {
718e3744 786 struct ospf_interface *oi = path->oi;
787
788 if (oi != NULL)
96735eea 789 if (oi->area == area)
790 return 1;
718e3744 791 }
792
793 return 0;
794}
795
796int
d4a53d58 797ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area)
718e3744 798{
799 if (IMPORT_NAME (area))
800 {
801 if (IMPORT_LIST (area) == NULL)
802 IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area));
803
804 if (IMPORT_LIST (area))
805 if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY)
806 return 0;
807 }
808
809 return 1;
810}
811
812int
813ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
d4a53d58 814 struct prefix_ipv4 *p)
718e3744 815{
816 if (PREFIX_NAME_IN (area))
817 {
818 if (PREFIX_LIST_IN (area) == NULL)
819 PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP,
820 PREFIX_NAME_IN (area));
821 if (PREFIX_LIST_IN (area))
822 if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT)
823 return 0;
824 }
825 return 1;
826}
827
828int
829ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
d4a53d58 830 struct prefix_ipv4 *p)
718e3744 831{
832 if (PREFIX_NAME_OUT (area))
833 {
834 if (PREFIX_LIST_OUT (area) == NULL)
835 PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP,
836 PREFIX_NAME_OUT (area));
837 if (PREFIX_LIST_OUT (area))
838 if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT)
839 return 0;
840 }
841 return 1;
842}
843
844void
147193a2 845ospf_abr_announce_network (struct ospf *ospf,
d4a53d58 846 struct prefix_ipv4 *p, struct ospf_route *or)
718e3744 847{
718e3744 848 struct ospf_area_range *range;
718e3744 849 struct ospf_area *area, *or_area;
147193a2 850 listnode node;
718e3744 851
852 if (IS_DEBUG_OSPF_EVENT)
853 zlog_info ("ospf_abr_announce_network(): Start");
718e3744 854
147193a2 855 or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
718e3744 856 assert (or_area);
857
147193a2 858 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 859 {
860 area = getdata (node);
861
862 if (IS_DEBUG_OSPF_EVENT)
863 zlog_info ("ospf_abr_announce_network(): looking at area %s",
864 inet_ntoa (area->area_id));
865
866 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
867 continue;
868
869 if (ospf_abr_nexthops_belong_to_area (or, area))
870 continue;
871
d4a53d58 872 if (!ospf_abr_should_accept (p, area))
718e3744 873 {
874 if (IS_DEBUG_OSPF_EVENT)
875 zlog_info ("ospf_abr_announce_network(): "
876 "prefix %s/%d was denied by import-list",
877 inet_ntoa (p->prefix), p->prefixlen);
878 continue;
879 }
880
d4a53d58 881 if (!ospf_abr_plist_in_check (area, or, p))
718e3744 882 {
883 if (IS_DEBUG_OSPF_EVENT)
884 zlog_info ("ospf_abr_announce_network(): "
885 "prefix %s/%d was denied by prefix-list",
886 inet_ntoa (p->prefix), p->prefixlen);
887 continue;
888 }
889
890 if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary)
891 {
892 if (IS_DEBUG_OSPF_EVENT)
893 zlog_info ("ospf_abr_announce_network(): "
894 "area %s is stub and no_summary",
895 inet_ntoa (area->area_id));
896 continue;
897 }
898
899 if (or->path_type == OSPF_PATH_INTER_AREA)
900 {
901 if (IS_DEBUG_OSPF_EVENT)
902 zlog_info ("ospf_abr_announce_network(): this is "
903 "inter-area route to %s/%d",
904 inet_ntoa (p->prefix), p->prefixlen);
905
906 if (!OSPF_IS_AREA_BACKBONE (area))
907 ospf_abr_announce_network_to_area (p, or->cost, area);
908 }
909
910 if (or->path_type == OSPF_PATH_INTRA_AREA)
d4a53d58 911 {
912 if (IS_DEBUG_OSPF_EVENT)
913 zlog_info ("ospf_abr_announce_network(): "
914 "this is intra-area route to %s/%d",
915 inet_ntoa (p->prefix), p->prefixlen);
916 if ((range = ospf_area_range_match (or_area, p))
917 && !ospf_area_is_transit (area))
918 ospf_abr_update_aggregate (range, or);
919 else
920 ospf_abr_announce_network_to_area (p, or->cost, area);
921 }
718e3744 922 }
923}
924
925int
147193a2 926ospf_abr_should_announce (struct ospf *ospf,
d4a53d58 927 struct prefix_ipv4 *p, struct ospf_route *or)
718e3744 928{
147193a2 929 struct ospf_area *area;
930
931 area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
718e3744 932
933 assert (area);
934
935 if (EXPORT_NAME (area))
936 {
937 if (EXPORT_LIST (area) == NULL)
938 EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area));
939
940 if (EXPORT_LIST (area))
941 if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY)
942 return 0;
943 }
944
945 return 1;
946}
947
948#ifdef HAVE_NSSA
949void
147193a2 950ospf_abr_process_nssa_translates (struct ospf *ospf)
718e3744 951{
952 /* Scan through all NSSA_LSDB records for all areas;
953
954 If P-bit is on, translate all Type-7's to 5's and aggregate or
955 flood install as approved in Type-5 LSDB with XLATE Flag on
956 later, do same for all aggregates... At end, DISCARD all
957 remaining UNAPPROVED Type-5's (Aggregate is for future ) */
958 listnode node;
959 struct ospf_area *area;
147193a2 960 struct route_node *rn;
961 struct ospf_lsa *lsa;
718e3744 962
963 if (IS_DEBUG_OSPF_NSSA)
964 zlog_info ("ospf_abr_process_nssa_translates(): Start");
965
147193a2 966 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 967 {
968 area = getdata (node);
969
e2c6c153 970 if (! area->NSSATranslatorState)
d4a53d58 971 continue; /* skip if not translator */
718e3744 972
973 if (area->external_routing != OSPF_AREA_NSSA)
d4a53d58 974 continue; /* skip if not Nssa Area */
718e3744 975
976 if (IS_DEBUG_OSPF_NSSA)
d4a53d58 977 zlog_info ("ospf_abr_process_nssa_translates(): "
978 "looking at area %s", inet_ntoa (area->area_id));
718e3744 979
147193a2 980 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
d4a53d58 981 ospf_abr_translate_nssa (area, lsa);
718e3744 982 }
983
984 if (IS_DEBUG_OSPF_NSSA)
985 zlog_info ("ospf_abr_process_nssa_translates(): Stop");
986
987}
988#endif /* HAVE_NSSA */
989
990void
147193a2 991ospf_abr_process_network_rt (struct ospf *ospf,
992 struct route_table *rt)
718e3744 993{
718e3744 994 struct ospf_area *area;
147193a2 995 struct ospf_route *or;
996 struct route_node *rn;
718e3744 997
998 if (IS_DEBUG_OSPF_EVENT)
999 zlog_info ("ospf_abr_process_network_rt(): Start");
1000
1001 for (rn = route_top (rt); rn; rn = route_next (rn))
1002 {
1003 if ((or = rn->info) == NULL)
1004 continue;
1005
147193a2 1006 if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)))
718e3744 1007 {
1008 if (IS_DEBUG_OSPF_EVENT)
1009 zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists",
1010 inet_ntoa (or->u.std.area_id));
1011 continue;
1012 }
1013
1014 if (IS_DEBUG_OSPF_EVENT)
1015 zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d",
1016 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
1017 if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL)
1018 {
1019 if (IS_DEBUG_OSPF_EVENT)
1020 zlog_info ("ospf_abr_process_network_rt(): "
1021 "this is an External router, skipping");
1022 continue;
1023 }
1024
1025 if (or->cost >= OSPF_LS_INFINITY)
1026 {
1027 if (IS_DEBUG_OSPF_EVENT)
1028 zlog_info ("ospf_abr_process_network_rt():"
1029 " this route's cost is infinity, skipping");
1030 continue;
1031 }
1032
1033 if (or->type == OSPF_DESTINATION_DISCARD)
1034 {
1035 if (IS_DEBUG_OSPF_EVENT)
1036 zlog_info ("ospf_abr_process_network_rt():"
1037 " this is a discard entry, skipping");
1038 continue;
1039 }
1040
1041 if (or->path_type == OSPF_PATH_INTRA_AREA &&
d4a53d58 1042 !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or))
718e3744 1043 {
1044 if (IS_DEBUG_OSPF_EVENT)
1045 zlog_info("ospf_abr_process_network_rt(): denied by export-list");
1046 continue;
1047 }
1048
1049 if (or->path_type == OSPF_PATH_INTRA_AREA &&
d4a53d58 1050 !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p))
718e3744 1051 {
1052 if (IS_DEBUG_OSPF_EVENT)
1053 zlog_info("ospf_abr_process_network_rt(): denied by prefix-list");
1054 continue;
1055 }
1056
1057 if ((or->path_type == OSPF_PATH_INTER_AREA) &&
1058 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1059 {
1060 if (IS_DEBUG_OSPF_EVENT)
1061 zlog_info ("ospf_abr_process_network_rt():"
1062 " this is route is not backbone one, skipping");
1063 continue;
1064 }
1065
1066
147193a2 1067 if ((ospf->abr_type == OSPF_ABR_CISCO) ||
1068 (ospf->abr_type == OSPF_ABR_IBM))
718e3744 1069
147193a2 1070 if (!ospf_act_bb_connection (ospf) &&
718e3744 1071 or->path_type != OSPF_PATH_INTRA_AREA)
1072 {
1073 if (IS_DEBUG_OSPF_EVENT)
1074 zlog_info ("ospf_abr_process_network_rt(): ALT ABR: "
1075 "No BB connection, skip not intra-area routes");
1076 continue;
1077 }
1078
1079 if (IS_DEBUG_OSPF_EVENT)
1080 zlog_info ("ospf_abr_process_network_rt(): announcing");
d4a53d58 1081 ospf_abr_announce_network (ospf, &rn->p, or);
718e3744 1082 }
1083
1084 if (IS_DEBUG_OSPF_EVENT)
1085 zlog_info ("ospf_abr_process_network_rt(): Stop");
1086}
1087
1088void
1089ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
1090 struct ospf_area *area)
1091{
1092 struct ospf_lsa *lsa, *old = NULL;
1093 struct summary_lsa *slsa = NULL;
1094
1095 if (IS_DEBUG_OSPF_EVENT)
1096 zlog_info ("ospf_abr_announce_rtr_to_area(): Start");
1097
147193a2 1098 old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA,
1099 p, area->ospf->router_id);
718e3744 1100 if (old)
1101 {
1102 if (IS_DEBUG_OSPF_EVENT)
1103 zlog_info ("ospf_abr_announce_rtr_to_area(): old summary found");
1104 slsa = (struct summary_lsa *) old->data;
1105
1106 if (IS_DEBUG_OSPF_EVENT)
1107 zlog_info ("ospf_abr_announce_network_to_area(): "
1108 "old metric: %d, new metric: %d",
1109 GET_METRIC (slsa->metric), cost);
1110 }
1111
1112 if (old && (GET_METRIC (slsa->metric) == cost))
1113 {
1114 if (IS_DEBUG_OSPF_EVENT)
1115 zlog_info ("ospf_abr_announce_rtr_to_area(): old summary approved");
1116 SET_FLAG (old->flags, OSPF_LSA_APPROVED);
1117 }
1118 else
1119 {
1120 if (IS_DEBUG_OSPF_EVENT)
1121 zlog_info ("ospf_abr_announce_rtr_to_area(): 2.2");
1122
1123 if (old)
1124 {
1125 set_metric (old, cost);
147193a2 1126 lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
718e3744 1127 }
1128 else
1129 lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
1130
1131 if (IS_DEBUG_OSPF_EVENT)
1132 zlog_info ("ospf_abr_announce_rtr_to_area(): "
1133 "flooding new version of summary");
1134 /*
1135 zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary");
1136 lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
1137
1138 SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1139 /* ospf_flood_through_area (area, NULL, lsa);*/
1140 }
1141
1142 if (IS_DEBUG_OSPF_EVENT)
1143 zlog_info ("ospf_abr_announce_rtr_to_area(): Stop");
1144}
1145
1146
1147void
147193a2 1148ospf_abr_announce_rtr (struct ospf *ospf,
1149 struct prefix_ipv4 *p, struct ospf_route *or)
718e3744 1150{
1151 listnode node;
1152 struct ospf_area *area;
1153
1154 if (IS_DEBUG_OSPF_EVENT)
1155 zlog_info ("ospf_abr_announce_rtr(): Start");
1156
147193a2 1157 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1158 {
1159 area = getdata (node);
1160
1161 if (IS_DEBUG_OSPF_EVENT)
1162 zlog_info ("ospf_abr_announce_rtr(): looking at area %s",
1163 inet_ntoa (area->area_id));
1164
1165 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
1166 continue;
1167
1168 if (ospf_abr_nexthops_belong_to_area (or, area))
1169 continue;
1170
1171 if (area->external_routing != OSPF_AREA_DEFAULT)
1172 {
1173 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 1174 zlog_info ("ospf_abr_announce_rtr(): "
718e3744 1175 "area %s doesn't support external routing",
1176 inet_ntoa(area->area_id));
1177 continue;
1178 }
1179
1180 if (or->path_type == OSPF_PATH_INTER_AREA)
1181 {
1182 if (IS_DEBUG_OSPF_EVENT)
1183 zlog_info ("ospf_abr_announce_rtr(): "
1184 "this is inter-area route to %s", inet_ntoa (p->prefix));
1185 if (!OSPF_IS_AREA_BACKBONE (area))
1186 ospf_abr_announce_rtr_to_area (p, or->cost, area);
1187 }
1188
1189 if (or->path_type == OSPF_PATH_INTRA_AREA)
1190 {
1191 if (IS_DEBUG_OSPF_EVENT)
1192 zlog_info ("ospf_abr_announce_rtr(): "
1193 "this is intra-area route to %s", inet_ntoa (p->prefix));
1194 ospf_abr_announce_rtr_to_area (p, or->cost, area);
1195 }
1196 }
1197
1198 if (IS_DEBUG_OSPF_EVENT)
1199 zlog_info ("ospf_abr_announce_rtr(): Stop");
1200}
1201
1202void
147193a2 1203ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
718e3744 1204{
718e3744 1205 struct ospf_route *or;
147193a2 1206 struct route_node *rn;
718e3744 1207 struct list *l;
1208
1209 if (IS_DEBUG_OSPF_EVENT)
1210 zlog_info ("ospf_abr_process_router_rt(): Start");
1211
1212 for (rn = route_top (rt); rn; rn = route_next (rn))
1213 {
1214 listnode node;
1215 char flag = 0;
1216 struct ospf_route *best = NULL;
1217
1218 if (rn->info == NULL)
1219 continue;
1220
1221 l = rn->info;
1222
1223 if (IS_DEBUG_OSPF_EVENT)
1224 zlog_info ("ospf_abr_process_router_rt(): this is a route to %s",
1225 inet_ntoa (rn->p.u.prefix4));
1226
1227 for (node = listhead (l); node; nextnode (node))
1228 {
1229 or = getdata (node);
1230 if (or == NULL)
1231 continue;
1232
147193a2 1233 if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))
718e3744 1234 {
1235 if (IS_DEBUG_OSPF_EVENT)
1236 zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists",
1237 inet_ntoa (or->u.std.area_id));
1238 continue;
1239 }
1240
1241
1242 if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL))
1243 {
1244 if (IS_DEBUG_OSPF_EVENT)
1245 zlog_info ("ospf_abr_process_router_rt(): "
1246 "This is not an ASBR, skipping");
1247 continue;
1248 }
1249
1250 if (!flag)
1251 {
147193a2 1252 best = ospf_find_asbr_route (ospf, rt,
1253 (struct prefix_ipv4 *) &rn->p);
718e3744 1254 flag = 1;
1255 }
1256
1257 if (best == NULL)
1258 continue;
1259
1260 if (or != best)
1261 {
1262 if (IS_DEBUG_OSPF_EVENT)
1263 zlog_info ("ospf_abr_process_router_rt(): "
1264 "This route is not the best among possible, skipping");
1265 continue;
1266 }
1267
1268 if (or->path_type == OSPF_PATH_INTER_AREA &&
1269 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1270 {
1271 if (IS_DEBUG_OSPF_EVENT)
1272 zlog_info ("ospf_abr_process_router_rt(): "
1273 "This route is not a backbone one, skipping");
1274 continue;
1275 }
1276
1277 if (or->cost >= OSPF_LS_INFINITY)
1278 {
1279 if (IS_DEBUG_OSPF_EVENT)
1280 zlog_info ("ospf_abr_process_router_rt(): "
1281 "This route has LS_INFINITY metric, skipping");
1282 continue;
1283 }
1284
147193a2 1285 if (ospf->abr_type == OSPF_ABR_CISCO
1286 || ospf->abr_type == OSPF_ABR_IBM)
1287 if (!ospf_act_bb_connection (ospf)
1288 && or->path_type != OSPF_PATH_INTRA_AREA)
718e3744 1289 {
1290 if (IS_DEBUG_OSPF_EVENT)
1291 zlog_info("ospf_abr_process_network_rt(): ALT ABR: "
1292 "No BB connection, skip not intra-area routes");
1293 continue;
1294 }
1295
147193a2 1296 ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or);
718e3744 1297
1298 }
1299
1300 }
1301
1302 if (IS_DEBUG_OSPF_EVENT)
1303 zlog_info ("ospf_abr_process_router_rt(): Stop");
1304}
1305
1306#ifdef HAVE_NSSA
718e3744 1307void
147193a2 1308ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
718e3744 1309{
147193a2 1310 struct ospf_lsa *lsa;
1311 struct route_node *rn;
1312
718e3744 1313 if (IS_DEBUG_OSPF_NSSA)
1314 zlog_info ("ospf_abr_unapprove_translates(): Start");
1315
1316 /* NSSA Translator is not checked, because it may have gone away,
1317 and we would want to flush any residuals anyway */
1318
147193a2 1319 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1320 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
d4a53d58 1321 {
1322 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1323 if (IS_DEBUG_OSPF_NSSA)
1324 zlog_info ("ospf_abr_unapprove_translates(): "
1325 "approved unset on link id %s",
1326 inet_ntoa (lsa->data->id));
1327 }
718e3744 1328
1329 if (IS_DEBUG_OSPF_NSSA)
1330 zlog_info ("ospf_abr_unapprove_translates(): Stop");
1331}
1332#endif /* HAVE_NSSA */
1333
718e3744 1334void
147193a2 1335ospf_abr_unapprove_summaries (struct ospf *ospf)
718e3744 1336{
1337 listnode node;
1338 struct ospf_area *area;
147193a2 1339 struct route_node *rn;
1340 struct ospf_lsa *lsa;
718e3744 1341
1342 if (IS_DEBUG_OSPF_EVENT)
1343 zlog_info ("ospf_abr_unapprove_summaries(): Start");
1344
147193a2 1345 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1346 {
1347 area = getdata (node);
d4a53d58 1348 if (IS_DEBUG_OSPF_EVENT)
1349 zlog_info ("ospf_abr_unapprove_summaries(): "
1350 "considering area %s",
1351 inet_ntoa (area->area_id));
147193a2 1352 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
d4a53d58 1353 if (ospf_lsa_is_self_originated (ospf, lsa))
1354 {
1355 if (IS_DEBUG_OSPF_EVENT)
1356 zlog_info ("ospf_abr_unapprove_summaries(): "
1357 "approved unset on summary link id %s",
1358 inet_ntoa (lsa->data->id));
1359 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1360 }
147193a2 1361
1362 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
d4a53d58 1363 if (ospf_lsa_is_self_originated (ospf, lsa))
1364 {
1365 if (IS_DEBUG_OSPF_EVENT)
1366 zlog_info ("ospf_abr_unapprove_summaries(): "
1367 "approved unset on asbr-summary link id %s",
1368 inet_ntoa (lsa->data->id));
1369 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1370 }
718e3744 1371 }
1372
1373 if (IS_DEBUG_OSPF_EVENT)
1374 zlog_info ("ospf_abr_unapprove_summaries(): Stop");
1375}
1376
1377void
147193a2 1378ospf_abr_prepare_aggregates (struct ospf *ospf)
718e3744 1379{
1380 listnode node;
1381 struct route_node *rn;
1382 struct ospf_area_range *range;
1383
1384 if (IS_DEBUG_OSPF_EVENT)
1385 zlog_info ("ospf_abr_prepare_aggregates(): Start");
1386
147193a2 1387 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1388 {
1389 struct ospf_area *area = getdata (node);
1390
1391 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1392 if ((range = rn->info) != NULL)
1393 {
1394 range->cost = 0;
1395 range->specifics = 0;
1396 }
1397 }
1398
1399 if (IS_DEBUG_OSPF_EVENT)
1400 zlog_info ("ospf_abr_prepare_aggregates(): Stop");
1401}
1402
1403void
147193a2 1404ospf_abr_announce_aggregates (struct ospf *ospf)
718e3744 1405{
1406 struct ospf_area *area, *ar;
1407 struct ospf_area_range *range;
1408 struct route_node *rn;
d4a53d58 1409 struct prefix p;
718e3744 1410 listnode node, n;
1411
1412 if (IS_DEBUG_OSPF_EVENT)
1413 zlog_info ("ospf_abr_announce_aggregates(): Start");
1414
147193a2 1415 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1416 {
1417 area = getdata (node);
1418
1419 if (IS_DEBUG_OSPF_EVENT)
1420 zlog_info ("ospf_abr_announce_aggregates(): looking at area %s",
1421 inet_ntoa (area->area_id));
1422
1423 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1424 if ((range = rn->info))
1425 {
1426 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1427 {
1428 if (IS_DEBUG_OSPF_EVENT)
1429 zlog_info ("ospf_abr_announce_aggregates():"
1430 " discarding suppress-ranges");
1431 continue;
1432 }
1433
1434 p.family = AF_INET;
d4a53d58 1435 p.u.prefix4 = range->addr;
718e3744 1436 p.prefixlen = range->masklen;
1437
1438 if (IS_DEBUG_OSPF_EVENT)
1439 zlog_info ("ospf_abr_announce_aggregates():"
1440 " this is range: %s/%d",
d4a53d58 1441 inet_ntoa (p.u.prefix4), p.prefixlen);
718e3744 1442
1443 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1444 {
1445 p.family = AF_INET;
d4a53d58 1446 p.u.prefix4 = range->subst_addr;
718e3744 1447 p.prefixlen = range->subst_masklen;
1448 }
1449
1450 if (range->specifics)
1451 {
1452 if (IS_DEBUG_OSPF_EVENT)
1453 zlog_info ("ospf_abr_announce_aggregates(): active range");
1454
147193a2 1455 for (n = listhead (ospf->areas); n; nextnode (n))
718e3744 1456 {
1457 ar = getdata (n);
1458 if (ar == area)
1459 continue;
1460
1461 /* We do not check nexthops here, because
1462 intra-area routes can be associated with
1463 one area only */
1464
1465 /* backbone routes are not summarized
1466 when announced into transit areas */
1467
1468 if (ospf_area_is_transit (ar) &&
1469 OSPF_IS_AREA_BACKBONE (area))
1470 {
1471 if (IS_DEBUG_OSPF_EVENT)
1472 zlog_info ("ospf_abr_announce_aggregates(): Skipping "
1473 "announcement of BB aggregate into"
1474 " a transit area");
1475 continue;
1476 }
1477 ospf_abr_announce_network_to_area (&p, range->cost, ar);
1478 }
1479 }
1480 }
1481 }
1482
1483 if (IS_DEBUG_OSPF_EVENT)
1484 zlog_info ("ospf_abr_announce_aggregates(): Stop");
1485}
1486
1487#ifdef HAVE_NSSA
1488void
147193a2 1489ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
718e3744 1490{
1491 listnode node; /*, n; */
1492 struct ospf_area *area; /*, *ar; */
1493 struct route_node *rn;
1494 struct ospf_area_range *range;
1495 struct prefix_ipv4 p;
1496
1497 if (IS_DEBUG_OSPF_NSSA)
1498 zlog_info ("ospf_abr_send_nssa_aggregates(): Start");
1499
147193a2 1500 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1501 {
1502 area = getdata (node);
1503
e2c6c153 1504 if (! area->NSSATranslatorState)
718e3744 1505 continue;
1506
1507 if (IS_DEBUG_OSPF_NSSA)
1508 zlog_info ("ospf_abr_send_nssa_aggregates(): looking at area %s",
1509 inet_ntoa (area->area_id));
1510
1511 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1512 {
1513 if (rn->info == NULL)
1514 continue;
1515
1516 range = rn->info;
1517
1518 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1519 {
1520 if (IS_DEBUG_OSPF_NSSA)
1521 zlog_info ("ospf_abr_send_nssa_aggregates():"
1522 " discarding suppress-ranges");
1523 continue;
1524 }
1525
1526 p.family = AF_INET;
1527 p.prefix = range->addr;
1528 p.prefixlen = range->masklen;
1529
1530 if (IS_DEBUG_OSPF_NSSA)
1531 zlog_info ("ospf_abr_send_nssa_aggregates():"
1532 " this is range: %s/%d",
1533 inet_ntoa (p.prefix), p.prefixlen);
1534
1535 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1536 {
1537 p.family = AF_INET;
1538 p.prefix = range->subst_addr;
1539 p.prefixlen = range->subst_masklen;
1540 }
1541
1542 if (range->specifics)
e2c6c153 1543 {
1544 if (IS_DEBUG_OSPF_NSSA)
1545 zlog_info ("ospf_abr_send_nssa_aggregates(): active range");
1546
1547 /* Fetch LSA-Type-7 from aggregate prefix, and then
1548 * translate, Install (as Type-5), Approve, and Flood
1549 */
1550 ospf_abr_translate_nssa_range (&p, range->cost);
1551 }
1552 } /* all area ranges*/
718e3744 1553 } /* all areas */
1554
1555 if (IS_DEBUG_OSPF_NSSA)
1556 zlog_info ("ospf_abr_send_nssa_aggregates(): Stop");
1557}
1558
1559void
147193a2 1560ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
718e3744 1561{
1562 listnode node;
1563 struct ospf_area *area;
718e3744 1564
147193a2 1565 if (! IS_OSPF_ABR (ospf))
718e3744 1566 return;
1567
1568 if (IS_DEBUG_OSPF_NSSA)
1569 zlog_info ("ospf_abr_announce_stub_defaults(): Start");
1570
147193a2 1571 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1572 {
1573 area = getdata (node);
1574 if (IS_DEBUG_OSPF_NSSA)
e2c6c153 1575 zlog_info ("ospf_abr_announce_nssa_defaults(): looking at area %s",
1576 inet_ntoa (area->area_id));
718e3744 1577
1578 if (area->external_routing != OSPF_AREA_NSSA)
e2c6c153 1579 continue;
718e3744 1580
1581 if (OSPF_IS_AREA_BACKBONE (area))
e2c6c153 1582 continue; /* Sanity Check */
718e3744 1583
1584 /* if (!TranslatorRole continue V 1.0 look for "always" conf */
e2c6c153 1585 if (area->NSSATranslatorState)
1586 {
1587 if (IS_DEBUG_OSPF_NSSA)
1588 zlog_info ("ospf_abr_announce_nssa_defaults(): "
1589 "announcing 0.0.0.0/0 to this nssa");
1590 /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
d4a53d58 1591 /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/
e2c6c153 1592 }
718e3744 1593 }
1594}
1595#endif /* HAVE_NSSA */
1596
1597void
147193a2 1598ospf_abr_announce_stub_defaults (struct ospf *ospf)
718e3744 1599{
1600 listnode node;
1601 struct ospf_area *area;
1602 struct prefix_ipv4 p;
1603
147193a2 1604 if (! IS_OSPF_ABR (ospf))
718e3744 1605 return;
1606
1607 if (IS_DEBUG_OSPF_EVENT)
1608 zlog_info ("ospf_abr_announce_stub_defaults(): Start");
1609
1610 p.family = AF_INET;
1611 p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1612 p.prefixlen = 0;
1613
147193a2 1614 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1615 {
1616 area = getdata (node);
1617 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 1618 zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s",
1619 inet_ntoa (area->area_id));
718e3744 1620
d4a53d58 1621 if ( (area->external_routing != OSPF_AREA_STUB)
718e3744 1622#ifdef HAVE_NSSA
d4a53d58 1623 && (area->external_routing != OSPF_AREA_NSSA)
718e3744 1624#endif /* HAVE_NSSA */
d4a53d58 1625 )
1626 continue;
718e3744 1627
1628 if (OSPF_IS_AREA_BACKBONE (area))
d4a53d58 1629 continue; /* Sanity Check */
1630
1631 if (area->no_summary)
1632 continue;
718e3744 1633
1634 if (IS_DEBUG_OSPF_EVENT)
d4a53d58 1635 zlog_info ("ospf_abr_announce_stub_defaults(): "
1636 "announcing 0.0.0.0/0 to area %s",
1637 inet_ntoa (area->area_id));
718e3744 1638 ospf_abr_announce_network_to_area (&p, area->default_cost, area);
1639 }
1640
1641 if (IS_DEBUG_OSPF_EVENT)
1642 zlog_info ("ospf_abr_announce_stub_defaults(): Stop");
1643}
1644
1645#ifdef HAVE_NSSA
1646int
147193a2 1647ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
1648 struct ospf_lsa *lsa)
718e3744 1649{
1650 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)
1651 && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1652 {
1653 zlog_info ("ospf_abr_remove_unapproved_translates(): "
1654 "removing unapproved translates, ID: %s",
1655 inet_ntoa (lsa->data->id));
1656
1657 /* FLUSH THROUGHOUT AS */
147193a2 1658 ospf_lsa_flush_as (ospf, lsa);
718e3744 1659
1660 /* DISCARD from LSDB */
1661 }
1662 return 0;
1663}
1664
1665void
147193a2 1666ospf_abr_remove_unapproved_translates (struct ospf *ospf)
718e3744 1667{
147193a2 1668 struct route_node *rn;
1669 struct ospf_lsa *lsa;
1670
718e3744 1671 /* All AREA PROCESS should have APPROVED necessary LSAs */
1672 /* Remove any left over and not APPROVED */
1673 if (IS_DEBUG_OSPF_NSSA)
1674 zlog_info ("ospf_abr_remove_unapproved_translates(): Start");
1675
147193a2 1676 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1677 ospf_abr_remove_unapproved_translates_apply (ospf, lsa);
718e3744 1678
1679 if (IS_DEBUG_OSPF_NSSA)
1680 zlog_info ("ospf_abr_remove_unapproved_translates(): Stop");
1681}
1682#endif /* HAVE_NSSA */
1683
718e3744 1684void
147193a2 1685ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
718e3744 1686{
1687 listnode node;
1688 struct ospf_area *area;
147193a2 1689 struct route_node *rn;
1690 struct ospf_lsa *lsa;
718e3744 1691
1692 if (IS_DEBUG_OSPF_EVENT)
1693 zlog_info ("ospf_abr_remove_unapproved_summaries(): Start");
1694
147193a2 1695 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1696 {
1697 area = getdata (node);
1698
1699 if (IS_DEBUG_OSPF_EVENT)
1700 zlog_info ("ospf_abr_remove_unapproved_summaries(): "
1701 "looking at area %s", inet_ntoa (area->area_id));
1702
147193a2 1703 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1704 if (ospf_lsa_is_self_originated (ospf, lsa))
1705 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1706 ospf_lsa_flush_area (lsa, area);
1707
1708 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1709 if (ospf_lsa_is_self_originated (ospf, lsa))
1710 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1711 ospf_lsa_flush_area (lsa, area);
718e3744 1712 }
1713
1714 if (IS_DEBUG_OSPF_EVENT)
1715 zlog_info ("ospf_abr_remove_unapproved_summaries(): Stop");
1716}
1717
1718void
147193a2 1719ospf_abr_manage_discard_routes (struct ospf *ospf)
718e3744 1720{
1721 listnode node;
1722 struct route_node *rn;
1723 struct ospf_area *area;
1724 struct ospf_area_range *range;
1725
147193a2 1726 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 1727 if ((area = node->data) != NULL)
1728 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1729 if ((range = rn->info) != NULL)
1730 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1731 {
1732 if (range->specifics)
147193a2 1733 ospf_add_discard_route (ospf->new_table, area,
718e3744 1734 (struct prefix_ipv4 *) &rn->p);
1735 else
1736 ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
1737 }
1738}
1739
1740#ifdef HAVE_NSSA
1741/* This is the function taking care about ABR NSSA, i.e. NSSA
1742 Translator, -LSA aggregation and flooding. For all NSSAs
1743
1744 Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's
1745 are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
1746 with the P-bit set.
1747
1748 Any received Type-5s are legal for an ABR, else illegal for IR.
1749 Received Type-7s are installed, by area, with incoming P-bit. They
1750 are flooded; if the Elected NSSA Translator, then P-bit off.
1751
1752 Additionally, this ABR will place "translated type-7's" into the
1753 Type-5 LSDB in order to keep track of APPROVAL or not.
1754
1755 It will scan through every area, looking for Type-7 LSAs with P-Bit
1756 SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
1757 AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED &
1758 5-INSTALLED.
1759
1760 5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
1761 left over are FLUSHED and DISCARDED.
1762
1763 For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
1764 any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
1765
1766void
147193a2 1767ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */
718e3744 1768{
1769 if (IS_DEBUG_OSPF_NSSA)
1770 zlog_info ("Check for NSSA-ABR Tasks():");
1771
147193a2 1772 if (! IS_OSPF_ABR (ospf))
718e3744 1773 return;
1774
147193a2 1775 if (! ospf->anyNSSA)
718e3744 1776 return;
1777
1778 /* Each area must confirm TranslatorRole */
1779 if (IS_DEBUG_OSPF_NSSA)
1780 zlog_info ("ospf_abr_nssa_task(): Start");
1781
1782 /* For all Global Entries flagged "local-translate", unset APPROVED */
1783 if (IS_DEBUG_OSPF_NSSA)
1784 zlog_info ("ospf_abr_nssa_task(): unapprove translates");
1785
147193a2 1786 ospf_abr_unapprove_translates (ospf);
718e3744 1787
1788 /* RESET all Ranges in every Area, same as summaries */
1789 if (IS_DEBUG_OSPF_NSSA)
1790 zlog_info ("ospf_abr_nssa_task(): NSSA initialize aggregates");
e2c6c153 1791 ospf_abr_prepare_aggregates (ospf); /*TURNED OFF just for now */
718e3744 1792
1793 /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
e2c6c153 1794 * Aggregate as Type-7
1795 * Install or Approve in Type-5 Global LSDB
1796 */
718e3744 1797 if (IS_DEBUG_OSPF_NSSA)
1798 zlog_info ("ospf_abr_nssa_task(): process translates");
147193a2 1799 ospf_abr_process_nssa_translates (ospf);
718e3744 1800
1801 /* Translate/Send any "ranged" aggregates, and also 5-Install and
e2c6c153 1802 * Approve
1803 * Scan Type-7's for aggregates, translate to Type-5's,
1804 * Install/Flood/Approve
1805 */
718e3744 1806 if (IS_DEBUG_OSPF_NSSA)
1807 zlog_info("ospf_abr_nssa_task(): send NSSA aggregates");
e2c6c153 1808 ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */
718e3744 1809
d4a53d58 1810 /* Send any NSSA defaults as Type-5
1811 *if (IS_DEBUG_OSPF_NSSA)
1812 * zlog_info ("ospf_abr_nssa_task(): announce nssa defaults");
1813 *ospf_abr_announce_nssa_defaults (ospf);
1814 * havnt a clue what above is supposed to do.
1815 */
718e3744 1816
1817 /* Flush any unapproved previous translates from Global Data Base */
1818 if (IS_DEBUG_OSPF_NSSA)
1819 zlog_info ("ospf_abr_nssa_task(): remove unapproved translates");
147193a2 1820 ospf_abr_remove_unapproved_translates (ospf);
718e3744 1821
147193a2 1822 ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */
718e3744 1823
1824 if (IS_DEBUG_OSPF_NSSA)
1825 zlog_info ("ospf_abr_nssa_task(): Stop");
1826}
1827#endif /* HAVE_NSSA */
1828
1829/* This is the function taking care about ABR stuff, i.e.
1830 summary-LSA origination and flooding. */
1831void
147193a2 1832ospf_abr_task (struct ospf *ospf)
718e3744 1833{
1834 if (IS_DEBUG_OSPF_EVENT)
1835 zlog_info ("ospf_abr_task(): Start");
1836
147193a2 1837 if (ospf->new_table == NULL || ospf->new_rtrs == NULL)
718e3744 1838 {
1839 if (IS_DEBUG_OSPF_EVENT)
1840 zlog_info ("ospf_abr_task(): Routing tables are not yet ready");
1841 return;
1842 }
1843
1844 if (IS_DEBUG_OSPF_EVENT)
1845 zlog_info ("ospf_abr_task(): unapprove summaries");
147193a2 1846 ospf_abr_unapprove_summaries (ospf);
718e3744 1847
1848 if (IS_DEBUG_OSPF_EVENT)
1849 zlog_info ("ospf_abr_task(): prepare aggregates");
147193a2 1850 ospf_abr_prepare_aggregates (ospf);
718e3744 1851
147193a2 1852 if (IS_OSPF_ABR (ospf))
718e3744 1853 {
1854 if (IS_DEBUG_OSPF_EVENT)
1855 zlog_info ("ospf_abr_task(): process network RT");
147193a2 1856 ospf_abr_process_network_rt (ospf, ospf->new_table);
718e3744 1857
1858 if (IS_DEBUG_OSPF_EVENT)
1859 zlog_info ("ospf_abr_task(): process router RT");
147193a2 1860 ospf_abr_process_router_rt (ospf, ospf->new_rtrs);
718e3744 1861
1862 if (IS_DEBUG_OSPF_EVENT)
1863 zlog_info ("ospf_abr_task(): announce aggregates");
147193a2 1864 ospf_abr_announce_aggregates (ospf);
718e3744 1865
1866 if (IS_DEBUG_OSPF_EVENT)
1867 zlog_info ("ospf_abr_task(): announce stub defaults");
147193a2 1868 ospf_abr_announce_stub_defaults (ospf);
718e3744 1869 }
1870
1871 if (IS_DEBUG_OSPF_EVENT)
1872 zlog_info ("ospf_abr_task(): remove unapproved summaries");
147193a2 1873 ospf_abr_remove_unapproved_summaries (ospf);
718e3744 1874
147193a2 1875 ospf_abr_manage_discard_routes (ospf);
718e3744 1876
718e3744 1877 if (IS_DEBUG_OSPF_EVENT)
1878 zlog_info ("ospf_abr_task(): Stop");
1879}
1880
1881
1882int
147193a2 1883ospf_abr_task_timer (struct thread *thread)
718e3744 1884{
147193a2 1885 struct ospf *ospf = THREAD_ARG (thread);
1886
1887 ospf->t_abr_task = 0;
718e3744 1888
1889 if (IS_DEBUG_OSPF_EVENT)
1890 zlog_info ("Running ABR task on timer");
1891
147193a2 1892 ospf_check_abr_status (ospf);
d4a53d58 1893#ifdef HAVE_NSSA
1894 ospf_abr_nssa_check_status (ospf);
1895#endif /* HAVE_NSSA */
718e3744 1896
147193a2 1897 ospf_abr_task (ospf);
e2c6c153 1898#ifdef HAVE_NSSA
e2c6c153 1899 ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */
1900#endif /* HAVE_NSSA */
718e3744 1901
147193a2 1902 return 0;
718e3744 1903}
1904
1905void
147193a2 1906ospf_schedule_abr_task (struct ospf *ospf)
718e3744 1907{
1908 if (IS_DEBUG_OSPF_EVENT)
1909 zlog_info ("Scheduling ABR task");
147193a2 1910
1911 if (ospf->t_abr_task == NULL)
1912 ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
1913 ospf, OSPF_ABR_TASK_DELAY);
718e3744 1914}