File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_ia.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

    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>