ospf_ia.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:20k
源码类别:

网络

开发平台:

Unix_Linux

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