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