Annotation of embedaddon/quagga/ospfd/ospf_ia.c, revision 1.1.1.2

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: 
1.1.1.2 ! misho     196: 
1.1       misho     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>