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