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