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