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