]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_ia.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ospfd / ospf_ia.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
718e3744 2/*
3 * OSPF inter-area routing.
4 * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
718e3744 5 */
6
7
8#include <zebra.h>
9
10#include "thread.h"
11#include "memory.h"
12#include "hash.h"
13#include "linklist.h"
14#include "prefix.h"
15#include "table.h"
16#include "log.h"
17
18#include "ospfd/ospfd.h"
19#include "ospfd/ospf_interface.h"
20#include "ospfd/ospf_ism.h"
21#include "ospfd/ospf_asbr.h"
22#include "ospfd/ospf_lsa.h"
23#include "ospfd/ospf_lsdb.h"
24#include "ospfd/ospf_neighbor.h"
25#include "ospfd/ospf_nsm.h"
26#include "ospfd/ospf_spf.h"
27#include "ospfd/ospf_route.h"
28#include "ospfd/ospf_ase.h"
29#include "ospfd/ospf_abr.h"
30#include "ospfd/ospf_ia.h"
31#include "ospfd/ospf_dump.h"
32
d62a17ae 33static struct ospf_route *ospf_find_abr_route(struct route_table *rtrs,
34 struct prefix_ipv4 *abr,
35 struct ospf_area *area)
718e3744 36{
d62a17ae 37 struct route_node *rn;
38 struct ospf_route * or ;
39 struct listnode *node;
718e3744 40
d62a17ae 41 if ((rn = route_node_lookup(rtrs, (struct prefix *)abr)) == NULL)
42 return NULL;
718e3744 43
d62a17ae 44 route_unlock_node(rn);
718e3744 45
d62a17ae 46 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or))
47 if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)
48 && (or->u.std.flags & ROUTER_LSA_BORDER))
49 return or ;
718e3744 50
d62a17ae 51 return NULL;
718e3744 52}
53
d62a17ae 54static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt,
55 struct prefix_ipv4 *p,
56 struct ospf_route *new_or,
57 struct ospf_route *abr_or)
718e3744 58{
d62a17ae 59 struct route_node *rn1;
60 struct ospf_route * or ;
61
62 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 63 zlog_debug("%s: processing summary route to %pFX", __func__, p);
d62a17ae 64
65 /* Find a route to the same dest */
66 if ((rn1 = route_node_lookup(rt, (struct prefix *)p))) {
67 int res;
68
69 route_unlock_node(rn1);
70
71 if ((or = rn1->info)) {
72 if (IS_DEBUG_OSPF_EVENT)
73 zlog_debug(
0faaabfb 74 "%s: Found a route to the same network",
75 __func__);
d62a17ae 76 /* Check the existing route. */
77 if ((res = ospf_route_cmp(ospf, new_or, or)) < 0) {
78 /* New route is better, so replace old one. */
79 ospf_route_subst(rn1, new_or, abr_or);
80 } else if (res == 0) {
81 /* New and old route are equal, so next hops can
82 * be added. */
83 route_lock_node(rn1);
84 ospf_route_copy_nexthops(or, abr_or->paths);
85 route_unlock_node(rn1);
86
87 /* new route can be deleted, because existing
88 * route has been updated. */
89 ospf_route_free(new_or);
90 } else {
91 /* New route is worse, so free it. */
92 ospf_route_free(new_or);
93 return;
94 }
95 } /* if (or)*/
96 } /*if (rn1)*/
97 else { /* no route */
98 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 99 zlog_debug("%s: add new route to %pFX", __func__, p);
d62a17ae 100 ospf_route_add(rt, p, new_or, abr_or);
101 }
718e3744 102}
103
d62a17ae 104static void ospf_ia_router_route(struct ospf *ospf, struct route_table *rtrs,
105 struct prefix_ipv4 *p,
106 struct ospf_route *new_or,
107 struct ospf_route *abr_or)
718e3744 108{
d62a17ae 109 struct ospf_route * or = NULL;
110 struct route_node *rn;
111 int ret;
112
113 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 114 zlog_debug("%s: considering %pFX", __func__, p);
96b663a3 115
d62a17ae 116 /* Find a route to the same dest */
117 rn = route_node_get(rtrs, (struct prefix *)p);
118
119 if (rn->info == NULL)
120 /* This is a new route */
121 rn->info = list_new();
122 else {
123 struct ospf_area *or_area;
124 or_area = ospf_area_lookup_by_area_id(ospf,
125 new_or->u.std.area_id);
126 assert(or_area);
127 /* This is an additional route */
128 route_unlock_node(rn);
129 or = ospf_find_asbr_route_through_area(rtrs, p, or_area);
718e3744 130 }
718e3744 131
d62a17ae 132 if (or) {
133 if (IS_DEBUG_OSPF_EVENT)
134 zlog_debug(
0faaabfb 135 "%s: a route to the same ABR through the same area exists",
136 __func__);
d62a17ae 137 /* New route is better */
138 if ((ret = ospf_route_cmp(ospf, new_or, or)) < 0) {
139 listnode_delete(rn->info, or);
140 ospf_route_free(or);
141 /* proceed down */
142 }
143 /* Routes are the same */
144 else if (ret == 0) {
145 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 146 zlog_debug("%s: merging the new route",
147 __func__);
d62a17ae 148
149 ospf_route_copy_nexthops(or, abr_or->paths);
150 ospf_route_free(new_or);
151 return;
152 }
153 /* New route is worse */
154 else {
155 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 156 zlog_debug("%s: skipping the new route",
157 __func__);
d62a17ae 158 ospf_route_free(new_or);
159 return;
160 }
718e3744 161 }
718e3744 162
d62a17ae 163 ospf_route_copy_nexthops(new_or, abr_or->paths);
718e3744 164
d62a17ae 165 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 166 zlog_debug("%s: adding the new route", __func__);
718e3744 167
d62a17ae 168 listnode_add(rn->info, new_or);
718e3744 169}
170
6b0655a2 171
d62a17ae 172static int process_summary_lsa(struct ospf_area *area, struct route_table *rt,
173 struct route_table *rtrs, struct ospf_lsa *lsa)
718e3744 174{
d62a17ae 175 struct ospf *ospf = area->ospf;
176 struct ospf_area_range *range;
177 struct ospf_route *abr_or, *new_or;
178 struct summary_lsa *sl;
179 struct prefix_ipv4 p, abr;
d7c0a89a 180 uint32_t metric;
d62a17ae 181
182 if (lsa == NULL)
183 return 0;
184
185 sl = (struct summary_lsa *)lsa->data;
186
187 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 188 zlog_debug("%s: LS ID: %pI4", __func__, &sl->header.id);
d62a17ae 189
190 metric = GET_METRIC(sl->metric);
191
192 if (metric == OSPF_LS_INFINITY)
193 return 0;
194
195 if (IS_LSA_MAXAGE(lsa))
196 return 0;
197
198 if (ospf_lsa_is_self_originated(area->ospf, lsa))
199 return 0;
200
201 p.family = AF_INET;
202 p.prefix = sl->header.id;
203
204 if (sl->header.type == OSPF_SUMMARY_LSA)
205 p.prefixlen = ip_masklen(sl->mask);
206 else
207 p.prefixlen = IPV4_MAX_BITLEN;
208
209 apply_mask_ipv4(&p);
210
211 if (sl->header.type == OSPF_SUMMARY_LSA
212 && (range = ospf_area_range_match_any(ospf, &p))
213 && ospf_area_range_active(range))
214 return 0;
215
216 /* XXX: This check seems dubious to me. If an ABR has already decided
217 * to consider summaries received in this area, then why would one wish
218 * to exclude default?
219 */
220 if (IS_OSPF_ABR(ospf) && ospf->abr_type != OSPF_ABR_STAND
221 && area->external_routing != OSPF_AREA_DEFAULT
222 && p.prefix.s_addr == OSPF_DEFAULT_DESTINATION && p.prefixlen == 0)
223 return 0; /* Ignore summary default from a stub area */
224
225 abr.family = AF_INET;
226 abr.prefix = sl->header.adv_router;
227 abr.prefixlen = IPV4_MAX_BITLEN;
228 apply_mask_ipv4(&abr);
229
230 abr_or = ospf_find_abr_route(rtrs, &abr, area);
231
232 if (abr_or == NULL)
233 return 0;
234
235 new_or = ospf_route_new();
236 new_or->type = OSPF_DESTINATION_NETWORK;
237 new_or->id = sl->header.id;
238 new_or->mask = sl->mask;
239 new_or->u.std.options = sl->header.options;
240 new_or->u.std.origin = (struct lsa_header *)sl;
241 new_or->cost = abr_or->cost + metric;
242 new_or->u.std.area_id = area->area_id;
243 new_or->u.std.external_routing = area->external_routing;
244 new_or->path_type = OSPF_PATH_INTER_AREA;
245
246 if (sl->header.type == OSPF_SUMMARY_LSA)
247 ospf_ia_network_route(ospf, rt, &p, new_or, abr_or);
248 else {
249 new_or->type = OSPF_DESTINATION_ROUTER;
250 new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
251 ospf_ia_router_route(ospf, rtrs, &p, new_or, abr_or);
252 }
253
254 return 0;
718e3744 255}
256
d62a17ae 257static void ospf_examine_summaries(struct ospf_area *area,
258 struct route_table *lsdb_rt,
259 struct route_table *rt,
260 struct route_table *rtrs)
718e3744 261{
d62a17ae 262 struct ospf_lsa *lsa;
263 struct route_node *rn;
96735eea 264
996c9314 265 LSDB_LOOP (lsdb_rt, rn, lsa)
044506e7 266 process_summary_lsa(area, rt, rtrs, lsa);
718e3744 267}
268
d62a17ae 269int ospf_area_is_transit(struct ospf_area *area)
718e3744 270{
d62a17ae 271 return (area->transit == OSPF_TRANSIT_TRUE)
272 || ospf_full_virtual_nbrs(
273 area); /* Cisco forgets to set the V-bit :( */
718e3744 274}
275
d62a17ae 276static void ospf_update_network_route(struct ospf *ospf, struct route_table *rt,
277 struct route_table *rtrs,
278 struct summary_lsa *lsa,
279 struct prefix_ipv4 *p,
280 struct ospf_area *area)
718e3744 281{
d62a17ae 282 struct route_node *rn;
283 struct ospf_route * or, *abr_or, *new_or;
284 struct prefix_ipv4 abr;
d7c0a89a 285 uint32_t cost;
d62a17ae 286
287 abr.family = AF_INET;
288 abr.prefix = lsa->header.adv_router;
289 abr.prefixlen = IPV4_MAX_BITLEN;
290 apply_mask_ipv4(&abr);
291
292 abr_or = ospf_find_abr_route(rtrs, &abr, area);
293
294 if (abr_or == NULL) {
295 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 296 zlog_debug("%s: can't find a route to the ABR",
297 __func__);
d62a17ae 298 return;
718e3744 299 }
d62a17ae 300
301 cost = abr_or->cost + GET_METRIC(lsa->metric);
302
303 rn = route_node_lookup(rt, (struct prefix *)p);
304
305 if (!rn) {
306 if (ospf->abr_type != OSPF_ABR_SHORTCUT)
307 return; /* Standard ABR can update only already
308 installed
309 backbone paths */
310 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 311 zlog_debug("%s: Allowing Shortcut ABR to add new route",
312 __func__);
d62a17ae 313 new_or = ospf_route_new();
314 new_or->type = OSPF_DESTINATION_NETWORK;
315 new_or->id = lsa->header.id;
316 new_or->mask = lsa->mask;
317 new_or->u.std.options = lsa->header.options;
318 new_or->u.std.origin = (struct lsa_header *)lsa;
319 new_or->cost = cost;
320 new_or->u.std.area_id = area->area_id;
321 new_or->u.std.external_routing = area->external_routing;
322 new_or->path_type = OSPF_PATH_INTER_AREA;
323 ospf_route_add(rt, p, new_or, abr_or);
324
325 return;
326 } else {
327 route_unlock_node(rn);
328 if (rn->info == NULL)
329 return;
718e3744 330 }
718e3744 331
d62a17ae 332 or = rn->info;
333
334 if (or->path_type != OSPF_PATH_INTRA_AREA &&
335 or->path_type != OSPF_PATH_INTER_AREA) {
336 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 337 zlog_debug("%s: ERR: path type is wrong", __func__);
d62a17ae 338 return;
339 }
340
341 if (ospf->abr_type == OSPF_ABR_SHORTCUT) {
9d303b37
DL
342 if (
343 or->path_type == OSPF_PATH_INTRA_AREA
344 && !OSPF_IS_AREA_ID_BACKBONE(
345 or->u.std.area_id)) {
d62a17ae 346 if (IS_DEBUG_OSPF_EVENT)
347 zlog_debug(
0faaabfb 348 "%s: Shortcut: this intra-area path is not backbone",
349 __func__);
d62a17ae 350 return;
351 }
352 } else /* Not Shortcut ABR */
718e3744 353 {
d62a17ae 354 if (!OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
355 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 356 zlog_debug("%s: route is not BB-associated",
357 __func__);
d62a17ae 358 return; /* We can update only BB routes */
359 }
360 }
718e3744 361
d62a17ae 362 if (or->cost < cost) {
363 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 364 zlog_debug("%s: new route is worse", __func__);
d62a17ae 365 return;
366 }
718e3744 367
d62a17ae 368 if (or->cost == cost) {
369 if (IS_DEBUG_OSPF_EVENT)
370 zlog_debug(
0faaabfb 371 "%s: new route is same distance, adding nexthops",
372 __func__);
d62a17ae 373 ospf_route_copy_nexthops(or, abr_or->paths);
374 }
718e3744 375
d62a17ae 376 if (or->cost > cost) {
377 if (IS_DEBUG_OSPF_EVENT)
378 zlog_debug(
0faaabfb 379 "%s: new route is better, overriding nexthops",
380 __func__);
d62a17ae 381 ospf_route_subst_nexthops(or, abr_or->paths);
382 or->cost = cost;
383
384 if ((ospf->abr_type == OSPF_ABR_SHORTCUT)
385 && !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
386 or->path_type = OSPF_PATH_INTER_AREA;
387 or->u.std.area_id = area->area_id;
388 or->u.std.external_routing = area->external_routing;
389 /* Note that we can do this only in Shortcut ABR mode,
390 because standard ABR must leave the route type and
391 area
392 unchanged
393 */
394 }
395 }
718e3744 396}
397
d62a17ae 398static void ospf_update_router_route(struct ospf *ospf,
399 struct route_table *rtrs,
400 struct summary_lsa *lsa,
401 struct prefix_ipv4 *p,
402 struct ospf_area *area)
718e3744 403{
d62a17ae 404 struct ospf_route * or, *abr_or, *new_or;
405 struct prefix_ipv4 abr;
d7c0a89a 406 uint32_t cost;
d62a17ae 407
408 abr.family = AF_INET;
409 abr.prefix = lsa->header.adv_router;
410 abr.prefixlen = IPV4_MAX_BITLEN;
411 apply_mask_ipv4(&abr);
412
413 abr_or = ospf_find_abr_route(rtrs, &abr, area);
414
415 if (abr_or == NULL) {
416 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 417 zlog_debug("%s: can't find a route to the ABR",
418 __func__);
d62a17ae 419 return;
420 }
718e3744 421
d62a17ae 422 cost = abr_or->cost + GET_METRIC(lsa->metric);
718e3744 423
d62a17ae 424 /* First try to find a backbone path,
425 because standard ABR can update only BB-associated paths */
718e3744 426
d62a17ae 427 if ((ospf->backbone == NULL) && (ospf->abr_type != OSPF_ABR_SHORTCUT))
428 return; /* no BB area, not Shortcut ABR, exiting */
718e3744 429
d62a17ae 430 /* find the backbone route, if possible */
431 if ((ospf->backbone == NULL)
432 || !(or = ospf_find_asbr_route_through_area(rtrs, p,
433 ospf->backbone))) {
434 if (ospf->abr_type != OSPF_ABR_SHORTCUT)
718e3744 435
d62a17ae 436 /* route to ASBR through the BB not found
437 the router is not Shortcut ABR, exiting */
718e3744 438
d62a17ae 439 return;
440 else
441 /* We're a Shortcut ABR*/
718e3744 442 {
d62a17ae 443 /* Let it either add a new router or update the route
444 through the same (non-BB) area. */
445
446 new_or = ospf_route_new();
447 new_or->type = OSPF_DESTINATION_ROUTER;
448 new_or->id = lsa->header.id;
449 new_or->mask = lsa->mask;
450 new_or->u.std.options = lsa->header.options;
451 new_or->u.std.origin = (struct lsa_header *)lsa;
452 new_or->cost = cost;
453 new_or->u.std.area_id = area->area_id;
454 new_or->u.std.external_routing = area->external_routing;
455 new_or->path_type = OSPF_PATH_INTER_AREA;
456 new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
457 ospf_ia_router_route(ospf, rtrs, p, new_or, abr_or);
458
459 return;
718e3744 460 }
d62a17ae 461 }
718e3744 462
d62a17ae 463 /* At this point the "or" is always bb-associated */
464
465 if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL)) {
466 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 467 zlog_debug("%s: the remote router is not an ASBR",
468 __func__);
d62a17ae 469 return;
470 }
471
472 if (or->path_type != OSPF_PATH_INTRA_AREA &&
473 or->path_type != OSPF_PATH_INTER_AREA)
474 return;
475
476 if (or->cost < cost)
477 return;
478
479 else if (or->cost == cost)
480 ospf_route_copy_nexthops(or, abr_or->paths);
481
482 else if (or->cost > cost) {
483 ospf_route_subst_nexthops(or, abr_or->paths);
484 or->cost = cost;
485
486 /* Even if the ABR runs in Shortcut mode, we can't change
487 the path type and area, because the "or" is always
488 bb-associated
489 at this point and even Shortcut ABR can't change these
490 attributes */
491 }
492}
493
494static int process_transit_summary_lsa(struct ospf_area *area,
495 struct route_table *rt,
496 struct route_table *rtrs,
497 struct ospf_lsa *lsa)
498{
499 struct ospf *ospf = area->ospf;
500 struct summary_lsa *sl;
501 struct prefix_ipv4 p;
d7c0a89a 502 uint32_t metric;
d62a17ae 503
504 if (lsa == NULL)
505 return 0;
506
507 sl = (struct summary_lsa *)lsa->data;
508
509 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 510 zlog_debug("%s: LS ID: %pI4", __func__, &lsa->data->id);
d62a17ae 511 metric = GET_METRIC(sl->metric);
512
513 if (metric == OSPF_LS_INFINITY) {
514 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 515 zlog_debug("%s: metric is infinity, skip", __func__);
d62a17ae 516 return 0;
517 }
518
519 if (IS_LSA_MAXAGE(lsa)) {
520 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 521 zlog_debug("%s: This LSA is too old", __func__);
d62a17ae 522 return 0;
523 }
524
525 if (ospf_lsa_is_self_originated(area->ospf, lsa)) {
526 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 527 zlog_debug("%s: This LSA is mine, skip", __func__);
d62a17ae 528 return 0;
529 }
530
531 p.family = AF_INET;
532 p.prefix = sl->header.id;
533
534 if (sl->header.type == OSPF_SUMMARY_LSA)
535 p.prefixlen = ip_masklen(sl->mask);
536 else
537 p.prefixlen = IPV4_MAX_BITLEN;
538
539 apply_mask_ipv4(&p);
540
541 if (sl->header.type == OSPF_SUMMARY_LSA)
542 ospf_update_network_route(ospf, rt, rtrs, sl, &p, area);
543 else
544 ospf_update_router_route(ospf, rtrs, sl, &p, area);
545
546 return 0;
547}
548
549static void ospf_examine_transit_summaries(struct ospf_area *area,
550 struct route_table *lsdb_rt,
551 struct route_table *rt,
552 struct route_table *rtrs)
553{
554 struct ospf_lsa *lsa;
555 struct route_node *rn;
556
996c9314 557 LSDB_LOOP (lsdb_rt, rn, lsa)
044506e7 558 process_transit_summary_lsa(area, rt, rtrs, lsa);
d62a17ae 559}
560
561void ospf_ia_routing(struct ospf *ospf, struct route_table *rt,
562 struct route_table *rtrs)
563{
f7813c7c 564 struct listnode *node;
d62a17ae 565 struct ospf_area *area;
566
567 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 568 zlog_debug("%s:start", __func__);
d62a17ae 569
570 if (IS_OSPF_ABR(ospf)) {
d62a17ae 571 switch (ospf->abr_type) {
572 case OSPF_ABR_STAND:
573 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 574 zlog_debug("%s:Standard ABR", __func__);
d62a17ae 575
576 if ((area = ospf->backbone)) {
d62a17ae 577 if (IS_DEBUG_OSPF_EVENT) {
578 zlog_debug(
0faaabfb 579 "%s:backbone area found, examining summaries",
580 __func__);
d62a17ae 581 }
582
583 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
584
585 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node,
586 area))
587 if (area != ospf->backbone)
588 if (ospf_area_is_transit(area))
589 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
590 area, rt, rtrs);
591 } else if (IS_DEBUG_OSPF_EVENT)
0faaabfb 592 zlog_debug("%s:backbone area NOT found",
593 __func__);
d62a17ae 594 break;
595 case OSPF_ABR_IBM:
596 case OSPF_ABR_CISCO:
597 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 598 zlog_debug("%s:Alternative Cisco/IBM ABR",
599 __func__);
d62a17ae 600 area = ospf->backbone; /* Find the BB */
601
602 /* If we have an active BB connection */
603 if (area && ospf_act_bb_connection(ospf)) {
604 if (IS_DEBUG_OSPF_EVENT) {
605 zlog_debug(
0faaabfb 606 "%s: backbone area found, examining BB summaries",
607 __func__);
d62a17ae 608 }
609
610 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
611
612 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node,
613 area))
614 if (area != ospf->backbone)
615 if (ospf_area_is_transit(area))
616 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
617 area, rt, rtrs);
618 } else { /* No active BB connection--consider all areas
9d303b37 619 */
d62a17ae 620 if (IS_DEBUG_OSPF_EVENT)
621 zlog_debug(
0faaabfb 622 "%s: Active BB connection not found",
623 __func__);
d62a17ae 624 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node,
625 area))
626 OSPF_EXAMINE_SUMMARIES_ALL(area, rt,
627 rtrs);
628 }
629 break;
630 case OSPF_ABR_SHORTCUT:
631 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 632 zlog_debug("%s:Alternative Shortcut", __func__);
d62a17ae 633 area = ospf->backbone; /* Find the BB */
634
635 /* If we have an active BB connection */
636 if (area && ospf_act_bb_connection(ospf)) {
637 if (IS_DEBUG_OSPF_EVENT) {
638 zlog_debug(
0faaabfb 639 "%s: backbone area found, examining BB summaries",
640 __func__);
d62a17ae 641 }
642 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
643 }
644
645 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
646 if (area != ospf->backbone)
647 if (ospf_area_is_transit(area)
648 || ((area->shortcut_configured
649 != OSPF_SHORTCUT_DISABLE)
650 && ((ospf->backbone == NULL)
651 || ((area->shortcut_configured
652 == OSPF_SHORTCUT_ENABLE)
653 && area->shortcut_capability))))
654 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
655 area, rt, rtrs);
656 break;
657 default:
658 break;
718e3744 659 }
d62a17ae 660 } else {
d62a17ae 661 if (IS_DEBUG_OSPF_EVENT)
0faaabfb 662 zlog_debug("%s:not ABR, considering all areas",
663 __func__);
d62a17ae 664
665 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
666 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
667 }
718e3744 668}