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>