File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_abr.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (7 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /*
    2:  * Area Border Router function.
    3:  * Copyright (C) 2004 Yasuhiro Ohara
    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 
   19:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
   20:  * Boston, MA 02111-1307, USA.  
   21:  */
   22: 
   23: #include <zebra.h>
   24: 
   25: #include "log.h"
   26: #include "prefix.h"
   27: #include "table.h"
   28: #include "vty.h"
   29: #include "linklist.h"
   30: #include "command.h"
   31: #include "thread.h"
   32: #include "plist.h"
   33: #include "filter.h"
   34: 
   35: #include "ospf6_proto.h"
   36: #include "ospf6_route.h"
   37: #include "ospf6_lsa.h"
   38: #include "ospf6_route.h"
   39: #include "ospf6_lsdb.h"
   40: #include "ospf6_message.h"
   41: 
   42: #include "ospf6_top.h"
   43: #include "ospf6_area.h"
   44: #include "ospf6_interface.h"
   45: #include "ospf6_neighbor.h"
   46: 
   47: #include "ospf6_flood.h"
   48: #include "ospf6_intra.h"
   49: #include "ospf6_abr.h"
   50: #include "ospf6d.h"
   51: 
   52: unsigned char conf_debug_ospf6_abr;
   53: 
   54: int
   55: ospf6_is_router_abr (struct ospf6 *o)
   56: {
   57:   struct listnode *node;
   58:   struct ospf6_area *oa;
   59:   int area_count = 0;
   60: 
   61:   for (ALL_LIST_ELEMENTS_RO (o->area_list, node, oa))
   62:     if (IS_AREA_ENABLED (oa))
   63:       area_count++;
   64: 
   65:   if (area_count > 1)
   66:     return 1;
   67:   return 0;
   68: }
   69: 
   70: void
   71: ospf6_abr_enable_area (struct ospf6_area *area)
   72: {
   73:   struct ospf6_area *oa;
   74:   struct ospf6_route *ro;
   75:   struct listnode *node, *nnode;
   76: 
   77:   for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
   78:     {
   79:       /* update B bit for each area */
   80:       OSPF6_ROUTER_LSA_SCHEDULE (oa);
   81: 
   82:       /* install other area's configured address range */
   83:       if (oa != area)
   84:         {
   85:           for (ro = ospf6_route_head (oa->range_table); ro;
   86:                ro = ospf6_route_next (ro))
   87:             {
   88:               if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
   89:                 ospf6_abr_originate_summary_to_area (ro, area);
   90:             }
   91:         }
   92:     }
   93: 
   94:   /* install calculated routes to border routers */
   95:   for (ro = ospf6_route_head (area->ospf6->brouter_table); ro;
   96:        ro = ospf6_route_next (ro))
   97:     ospf6_abr_originate_summary_to_area (ro, area);
   98: 
   99:   /* install calculated routes to network (may be rejected by ranges) */
  100:   for (ro = ospf6_route_head (area->ospf6->route_table); ro;
  101:        ro = ospf6_route_next (ro))
  102:     ospf6_abr_originate_summary_to_area (ro, area);
  103: }
  104: 
  105: void
  106: ospf6_abr_disable_area (struct ospf6_area *area)
  107: {
  108:   struct ospf6_area *oa;
  109:   struct ospf6_route *ro;
  110:   struct ospf6_lsa *old;
  111:   struct listnode *node, *nnode;
  112: 
  113:   /* Withdraw all summary prefixes previously originated */
  114:   for (ro = ospf6_route_head (area->summary_prefix); ro;
  115:        ro = ospf6_route_next (ro))
  116:     {
  117:       old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
  118:                                area->ospf6->router_id, area->lsdb);
  119:       if (old)
  120:         ospf6_lsa_purge (old);
  121:       ospf6_route_remove (ro, area->summary_prefix);
  122:     }
  123: 
  124:   /* Withdraw all summary router-routes previously originated */
  125:   for (ro = ospf6_route_head (area->summary_router); ro;
  126:        ro = ospf6_route_next (ro))
  127:     {
  128:       old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
  129:                                area->ospf6->router_id, area->lsdb);
  130:       if (old)
  131:         ospf6_lsa_purge (old);
  132:       ospf6_route_remove (ro, area->summary_router);
  133:     }
  134: 
  135:   /* Schedule Router-LSA for each area (ABR status may change) */
  136:   for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
  137:     /* update B bit for each area */
  138:     OSPF6_ROUTER_LSA_SCHEDULE (oa);
  139: }
  140: 
  141: /* RFC 2328 12.4.3. Summary-LSAs */
  142: void
  143: ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
  144:                                      struct ospf6_area *area)
  145: {
  146:   struct ospf6_lsa *lsa, *old = NULL;
  147:   struct ospf6_interface *oi;
  148:   struct ospf6_route *summary, *range = NULL;
  149:   struct ospf6_area *route_area;
  150:   char buffer[OSPF6_MAX_LSASIZE];
  151:   struct ospf6_lsa_header *lsa_header;
  152:   caddr_t p;
  153:   struct ospf6_inter_prefix_lsa *prefix_lsa;
  154:   struct ospf6_inter_router_lsa *router_lsa;
  155:   struct ospf6_route_table *summary_table = NULL;
  156:   u_int16_t type;
  157:   char buf[64];
  158:   int is_debug = 0;
  159: 
  160:   if (route->type == OSPF6_DEST_TYPE_ROUTER)
  161:     {
  162:       if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER))
  163:         {
  164:           is_debug++;
  165:           inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
  166:                      buf, sizeof (buf));
  167:           zlog_debug ("Originating summary in area %s for ASBR %s",
  168: 		      area->name, buf);
  169:         }
  170:       summary_table = area->summary_router;
  171:     }
  172:   else
  173:     {
  174:       if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX))
  175:         {
  176:           is_debug++;
  177:           prefix2str (&route->prefix, buf, sizeof (buf));
  178:           zlog_debug ("Originating summary in area %s for %s",
  179: 		      area->name, buf);
  180:         }
  181:       summary_table = area->summary_prefix;
  182:     }
  183: 
  184:   summary = ospf6_route_lookup (&route->prefix, summary_table);
  185:   if (summary)
  186:     old = ospf6_lsdb_lookup (summary->path.origin.type,
  187:                              summary->path.origin.id,
  188:                              area->ospf6->router_id, area->lsdb);
  189: 
  190:   /* if this route has just removed, remove corresponding LSA */
  191:   if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
  192:     {
  193:       if (is_debug)
  194:         zlog_debug ("The route has just removed, purge previous LSA");
  195:       if (summary)
  196:         ospf6_route_remove (summary, summary_table);
  197:       if (old)
  198:         ospf6_lsa_purge (old);
  199:       return;
  200:     }
  201: 
  202:   /* Only destination type network, range or ASBR are considered */
  203:   if (route->type != OSPF6_DEST_TYPE_NETWORK &&
  204:       route->type != OSPF6_DEST_TYPE_RANGE &&
  205:       (route->type != OSPF6_DEST_TYPE_ROUTER ||
  206:        ! CHECK_FLAG (route->path.router_bits, OSPF6_ROUTER_BIT_E)))
  207:     {
  208:       if (is_debug)
  209:         zlog_debug ("Route type is none of network, range nor ASBR, withdraw");
  210:       if (summary)
  211:         ospf6_route_remove (summary, summary_table);
  212:       if (old)
  213:         ospf6_lsa_purge (old);
  214:       return;
  215:     }
  216: 
  217:   /* AS External routes are never considered */
  218:   if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
  219:       route->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
  220:     {
  221:       if (is_debug)
  222:         zlog_debug ("Path type is external, withdraw");
  223:       if (summary)
  224:         ospf6_route_remove (summary, summary_table);
  225:       if (old)
  226:         ospf6_lsa_purge (old);
  227:       return;
  228:     }
  229: 
  230:   /* do not generate if the path's area is the same as target area */
  231:   if (route->path.area_id == area->area_id)
  232:     {
  233:       if (is_debug)
  234:         zlog_debug ("The route is in the area itself, ignore");
  235:       if (summary)
  236:         ospf6_route_remove (summary, summary_table);
  237:       if (old)
  238:         ospf6_lsa_purge (old);
  239:       return;
  240:     }
  241: 
  242:   /* do not generate if the nexthops belongs to the target area */
  243:   oi = ospf6_interface_lookup_by_ifindex (route->nexthop[0].ifindex);
  244:   if (oi && oi->area && oi->area == area)
  245:     {
  246:       if (is_debug)
  247:         zlog_debug ("The route's nexthop is in the same area, ignore");
  248:       if (summary)
  249:         ospf6_route_remove (summary, summary_table);
  250:       if (old)
  251:         ospf6_lsa_purge (old);
  252:       return;
  253:     }
  254: 
  255:   /* do not generate if the route cost is greater or equal to LSInfinity */
  256:   if (route->path.cost >= OSPF_LS_INFINITY)
  257:     {
  258:       if (is_debug)
  259:         zlog_debug ("The cost exceeds LSInfinity, withdraw");
  260:       if (summary)
  261:         ospf6_route_remove (summary, summary_table);
  262:       if (old)
  263:         ospf6_lsa_purge (old);
  264:       return;
  265:     }
  266: 
  267:   /* if this is a route to ASBR */
  268:   if (route->type == OSPF6_DEST_TYPE_ROUTER)
  269:     {
  270:       /* Only the prefered best path is considered */
  271:       if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST))
  272:         {
  273:           if (is_debug)
  274:             zlog_debug ("This is the secondary path to the ASBR, ignore");
  275:           if (summary)
  276:             ospf6_route_remove (summary, summary_table);
  277:           if (old)
  278:             ospf6_lsa_purge (old);
  279:           return;
  280:         }
  281: 
  282:       /* Do not generate if the area is stub */
  283:       /* XXX */
  284:     }
  285: 
  286:   /* if this is an intra-area route, this may be suppressed by aggregation */
  287:   if (route->type == OSPF6_DEST_TYPE_NETWORK &&
  288:       route->path.type == OSPF6_PATH_TYPE_INTRA)
  289:     {
  290:       /* search for configured address range for the route's area */
  291:       route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);
  292:       assert (route_area);
  293:       range = ospf6_route_lookup_bestmatch (&route->prefix,
  294:                                             route_area->range_table);
  295: 
  296:       /* ranges are ignored when originate backbone routes to transit area.
  297:          Otherwise, if ranges are configured, the route is suppressed. */
  298:       if (range && ! CHECK_FLAG (range->flag, OSPF6_ROUTE_REMOVE) &&
  299:           (route->path.area_id != OSPF_AREA_BACKBONE ||
  300:            ! IS_AREA_TRANSIT (area)))
  301:         {
  302:           if (is_debug)
  303:             {
  304:               prefix2str (&range->prefix, buf, sizeof (buf));
  305:               zlog_debug ("Suppressed by range %s of area %s",
  306:                          buf, route_area->name);
  307:             }
  308: 
  309:           if (summary)
  310:             ospf6_route_remove (summary, summary_table);
  311:           if (old)
  312:             ospf6_lsa_purge (old);
  313:           return;
  314:         }
  315:     }
  316: 
  317:   /* If this is a configured address range */
  318:   if (route->type == OSPF6_DEST_TYPE_RANGE)
  319:     {
  320:       /* If DoNotAdvertise is set */
  321:       if (CHECK_FLAG (route->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
  322:         {
  323:           if (is_debug)
  324:             zlog_debug ("This is the range with DoNotAdvertise set. ignore");
  325:           if (summary)
  326:             ospf6_route_remove (summary, summary_table);
  327:           if (old)
  328:             ospf6_lsa_purge (old);
  329:           return;
  330:         }
  331: 
  332:       /* Whether the route have active longer prefix */
  333:       if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
  334:         {
  335:           if (is_debug)
  336:             zlog_debug ("The range is not active. withdraw");
  337:           if (summary)
  338:             ospf6_route_remove (summary, summary_table);
  339:           if (old)
  340:             ospf6_lsa_purge (old);
  341:           return;
  342:         }
  343:     }
  344: 
  345:   /* Check export list */
  346:   if (EXPORT_NAME (area))
  347:     {
  348:       if (EXPORT_LIST (area) == NULL)
  349:         EXPORT_LIST (area) =
  350:           access_list_lookup (AFI_IP6, EXPORT_NAME (area));
  351: 
  352:       if (EXPORT_LIST (area))
  353:         if (access_list_apply (EXPORT_LIST (area),
  354:                                &route->prefix) == FILTER_DENY)
  355:           {
  356:             if (is_debug)
  357:               {
  358:                 inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
  359:                            buf, sizeof(buf));
  360:                 zlog_debug ("prefix %s was denied by export list", buf);
  361:               }
  362:             return;
  363:           }
  364:     }
  365: 
  366:   /* Check filter-list */
  367:   if (PREFIX_NAME_OUT (area))
  368:     {
  369:       if (PREFIX_LIST_OUT (area) == NULL)
  370:         PREFIX_LIST_OUT (area) =
  371:           prefix_list_lookup(AFI_IP6, PREFIX_NAME_OUT (area));
  372: 
  373:       if (PREFIX_LIST_OUT (area))
  374:          if (prefix_list_apply (PREFIX_LIST_OUT (area), 
  375:                                 &route->prefix) != PREFIX_PERMIT) 
  376:            {
  377:              if (is_debug)
  378:                {
  379:                  inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
  380:                             buf, sizeof (buf));
  381:                  zlog_debug ("prefix %s was denied by filter-list out", buf);
  382:                }
  383:              return;
  384:            }
  385:     }
  386: 
  387:   /* the route is going to be originated. store it in area's summary_table */
  388:   if (summary == NULL)
  389:     {
  390:       summary = ospf6_route_copy (route);
  391:       if (route->type == OSPF6_DEST_TYPE_NETWORK ||
  392:           route->type == OSPF6_DEST_TYPE_RANGE)
  393:         summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  394:       else
  395:         summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  396:       summary->path.origin.adv_router = area->ospf6->router_id;
  397:       summary->path.origin.id =
  398:         ospf6_new_ls_id (summary->path.origin.type,
  399:                          summary->path.origin.adv_router, area->lsdb);
  400:       summary = ospf6_route_add (summary, summary_table);
  401:     }
  402:   else
  403:     {
  404:       summary->type = route->type;
  405:       quagga_gettime (QUAGGA_CLK_MONOTONIC, &summary->changed);
  406:     }
  407: 
  408:   summary->path.router_bits = route->path.router_bits;
  409:   summary->path.options[0] = route->path.options[0];
  410:   summary->path.options[1] = route->path.options[1];
  411:   summary->path.options[2] = route->path.options[2];
  412:   summary->path.prefix_options = route->path.prefix_options;
  413:   summary->path.area_id = area->area_id;
  414:   summary->path.type = OSPF6_PATH_TYPE_INTER;
  415:   summary->path.cost = route->path.cost;
  416:   summary->nexthop[0] = route->nexthop[0];
  417: 
  418:   /* prepare buffer */
  419:   memset (buffer, 0, sizeof (buffer));
  420:   lsa_header = (struct ospf6_lsa_header *) buffer;
  421: 
  422:   if (route->type == OSPF6_DEST_TYPE_ROUTER)
  423:     {
  424:       router_lsa = (struct ospf6_inter_router_lsa *)
  425:         ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  426:       p = (caddr_t) router_lsa + sizeof (struct ospf6_inter_router_lsa);
  427: 
  428:       /* Fill Inter-Area-Router-LSA */
  429:       router_lsa->options[0] = route->path.options[0];
  430:       router_lsa->options[1] = route->path.options[1];
  431:       router_lsa->options[2] = route->path.options[2];
  432:       OSPF6_ABR_SUMMARY_METRIC_SET (router_lsa, route->path.cost);
  433:       router_lsa->router_id = ADV_ROUTER_IN_PREFIX (&route->prefix);
  434:       type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  435:     }
  436:   else
  437:     {
  438:       prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  439:         ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  440:       p = (caddr_t) prefix_lsa + sizeof (struct ospf6_inter_prefix_lsa);
  441: 
  442:       /* Fill Inter-Area-Prefix-LSA */
  443:       OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa, route->path.cost);
  444:       prefix_lsa->prefix.prefix_length = route->prefix.prefixlen;
  445:       prefix_lsa->prefix.prefix_options = route->path.prefix_options;
  446: 
  447:       /* set Prefix */
  448:       memcpy (p, &route->prefix.u.prefix6,
  449:               OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
  450:       ospf6_prefix_apply_mask (&prefix_lsa->prefix);
  451:       p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
  452:       type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  453:     }
  454: 
  455:   /* Fill LSA Header */
  456:   lsa_header->age = 0;
  457:   lsa_header->type = type;
  458:   lsa_header->id = summary->path.origin.id;
  459:   lsa_header->adv_router = area->ospf6->router_id;
  460:   lsa_header->seqnum =
  461:     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  462:                          lsa_header->adv_router, area->lsdb);
  463:   lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
  464: 
  465:   /* LSA checksum */
  466:   ospf6_lsa_checksum (lsa_header);
  467: 
  468:   /* create LSA */
  469:   lsa = ospf6_lsa_create (lsa_header);
  470: 
  471:   /* Originate */
  472:   ospf6_lsa_originate_area (lsa, area);
  473: }
  474: 
  475: static void
  476: ospf6_abr_range_update (struct ospf6_route *range)
  477: {
  478:   u_int32_t cost = 0;
  479:   struct ospf6_route *ro;
  480: 
  481:   assert (range->type == OSPF6_DEST_TYPE_RANGE);
  482: 
  483:   /* update range's cost and active flag */
  484:   for (ro = ospf6_route_match_head (&range->prefix, ospf6->route_table);
  485:        ro; ro = ospf6_route_match_next (&range->prefix, ro))
  486:     {
  487:       if (ro->path.area_id == range->path.area_id &&
  488:           ! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE))
  489:         cost = MAX (cost, ro->path.cost);
  490:     }
  491: 
  492:   if (range->path.cost != cost)
  493:     {
  494:       range->path.cost = cost;
  495: 
  496:       if (range->path.cost)
  497:         SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
  498:       else
  499:         UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
  500: 
  501:       ospf6_abr_originate_summary (range);
  502:     }
  503: }
  504: 
  505: void
  506: ospf6_abr_originate_summary (struct ospf6_route *route)
  507: {
  508:   struct listnode *node, *nnode;
  509:   struct ospf6_area *oa;
  510:   struct ospf6_route *range = NULL;
  511: 
  512:   if (route->type == OSPF6_DEST_TYPE_NETWORK)
  513:     {
  514:       oa = ospf6_area_lookup (route->path.area_id, ospf6);
  515:       range = ospf6_route_lookup_bestmatch (&route->prefix, oa->range_table);
  516:       if (range)
  517:         ospf6_abr_range_update (range);
  518:     }
  519: 
  520:   for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
  521:     ospf6_abr_originate_summary_to_area (route, oa);
  522: }
  523: 
  524: /* RFC 2328 16.2. Calculating the inter-area routes */
  525: void
  526: ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
  527: {
  528:   struct prefix prefix, abr_prefix;
  529:   struct ospf6_route_table *table = NULL;
  530:   struct ospf6_route *range, *route, *old = NULL;
  531:   struct ospf6_route *abr_entry;
  532:   u_char type = 0;
  533:   char options[3] = {0, 0, 0};
  534:   u_int8_t prefix_options = 0;
  535:   u_int32_t cost = 0;
  536:   u_char router_bits = 0;
  537:   int i;
  538:   char buf[64];
  539:   int is_debug = 0;
  540:   struct ospf6_inter_prefix_lsa *prefix_lsa = NULL;
  541:   struct ospf6_inter_router_lsa *router_lsa = NULL;
  542: 
  543:   memset (&prefix, 0, sizeof (prefix));
  544: 
  545:   if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
  546:     {
  547:       if (IS_OSPF6_DEBUG_EXAMIN (INTER_PREFIX))
  548:         {
  549:           is_debug++;
  550:           zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
  551:         }
  552: 
  553:       prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  554:         OSPF6_LSA_HEADER_END (lsa->header);
  555:       prefix.family = AF_INET6;
  556:       prefix.prefixlen = prefix_lsa->prefix.prefix_length;
  557:       ospf6_prefix_in6_addr (&prefix.u.prefix6, &prefix_lsa->prefix);
  558:       if (is_debug)
  559:         prefix2str (&prefix, buf, sizeof (buf));
  560:       table = oa->ospf6->route_table;
  561:       type = OSPF6_DEST_TYPE_NETWORK;
  562:       prefix_options = prefix_lsa->prefix.prefix_options;
  563:       cost = OSPF6_ABR_SUMMARY_METRIC (prefix_lsa);
  564:     }
  565:   else if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER))
  566:     {
  567:       if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER))
  568:         {
  569:           is_debug++;
  570:           zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
  571:         }
  572: 
  573:       router_lsa = (struct ospf6_inter_router_lsa *)
  574:         OSPF6_LSA_HEADER_END (lsa->header);
  575:       ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix);
  576:       if (is_debug)
  577:         inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
  578:       table = oa->ospf6->brouter_table;
  579:       type = OSPF6_DEST_TYPE_ROUTER;
  580:       options[0] = router_lsa->options[0];
  581:       options[1] = router_lsa->options[1];
  582:       options[2] = router_lsa->options[2];
  583:       cost = OSPF6_ABR_SUMMARY_METRIC (router_lsa);
  584:       SET_FLAG (router_bits, OSPF6_ROUTER_BIT_E);
  585:     }
  586:   else
  587:     assert (0);
  588: 
  589:   /* Find existing route */
  590:   route = ospf6_route_lookup (&prefix, table);
  591:   if (route)
  592:     ospf6_route_lock (route);
  593:   while (route && ospf6_route_is_prefix (&prefix, route))
  594:     {
  595:       if (route->path.area_id == oa->area_id &&
  596:           route->path.origin.type == lsa->header->type &&
  597:           route->path.origin.id == lsa->header->id &&
  598:           route->path.origin.adv_router == lsa->header->adv_router &&
  599:           ! CHECK_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED))
  600:         old = route;
  601:       route = ospf6_route_next (route);
  602:     }
  603: 
  604:   /* (1) if cost == LSInfinity or if the LSA is MaxAge */
  605:   if (cost == OSPF_LS_INFINITY)
  606:     {
  607:       if (is_debug)
  608:         zlog_debug ("cost is LS_INFINITY, ignore");
  609:       if (old)
  610:         ospf6_route_remove (old, table);
  611:       return;
  612:     }
  613:   if (OSPF6_LSA_IS_MAXAGE (lsa))
  614:     {
  615:       if (is_debug)
  616:         zlog_debug ("LSA is MaxAge, ignore");
  617:       if (old)
  618:         ospf6_route_remove (old, table);
  619:       return;
  620:     }
  621: 
  622:   /* (2) if the LSA is self-originated, ignore */
  623:   if (lsa->header->adv_router == oa->ospf6->router_id)
  624:     {
  625:       if (is_debug)
  626:         zlog_debug ("LSA is self-originated, ignore");
  627:       if (old)
  628:         ospf6_route_remove (old, table);
  629:       return;
  630:     }
  631: 
  632:   /* (3) if the prefix is equal to an active configured address range */
  633:   /*     or if the NU bit is set in the prefix */
  634:   if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
  635:     {
  636:       range = ospf6_route_lookup (&prefix, oa->range_table);
  637:       if (range)
  638:         {
  639:           if (is_debug)
  640:             zlog_debug ("Prefix is equal to address range, ignore");
  641:           if (old)
  642:             ospf6_route_remove (old, table);
  643:           return;
  644:         }
  645: 
  646:       if (CHECK_FLAG (prefix_lsa->prefix.prefix_options,
  647: 		      OSPF6_PREFIX_OPTION_NU) ||
  648: 	  CHECK_FLAG (prefix_lsa->prefix.prefix_options,
  649: 		      OSPF6_PREFIX_OPTION_LA))
  650: 	{
  651:           if (is_debug)
  652:             zlog_debug ("Prefix has NU/LA bit set, ignore");
  653:           if (old)
  654:             ospf6_route_remove (old, table);
  655:           return;
  656: 	}
  657:     }
  658: 
  659:   if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER))
  660:     {
  661:       /* To pass test suites */
  662:       if (! OSPF6_OPT_ISSET (router_lsa->options, OSPF6_OPT_R) ||
  663: 	  ! OSPF6_OPT_ISSET (router_lsa->options, OSPF6_OPT_V6))
  664: 	{
  665:           if (is_debug)
  666:             zlog_debug ("Prefix has NU/LA bit set, ignore");
  667:           if (old)
  668:             ospf6_route_remove (old, table);
  669:           return;
  670: 	}
  671:     }
  672: 
  673:   /* (4) if the routing table entry for the ABR does not exist */
  674:   ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &abr_prefix);
  675:   abr_entry = ospf6_route_lookup (&abr_prefix, oa->ospf6->brouter_table);
  676:   if (abr_entry == NULL || abr_entry->path.area_id != oa->area_id ||
  677:       CHECK_FLAG (abr_entry->flag, OSPF6_ROUTE_REMOVE) ||
  678:       ! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B))
  679:     {
  680:       if (is_debug)
  681:         zlog_debug ("ABR router entry does not exist, ignore");
  682:       if (old)
  683:         ospf6_route_remove (old, table);
  684:       return;
  685:     }
  686: 
  687:   /* Check import list */
  688:   if (IMPORT_NAME (oa))
  689:     {
  690:       if (IMPORT_LIST (oa) == NULL)
  691:         IMPORT_LIST (oa) = access_list_lookup (AFI_IP6, IMPORT_NAME (oa));
  692: 
  693:       if (IMPORT_LIST (oa))
  694:         if (access_list_apply (IMPORT_LIST (oa), &prefix) == FILTER_DENY)
  695:           {
  696:             if (is_debug)
  697:               zlog_debug ("Prefix was denied by import-list");
  698:             if (old)
  699:               ospf6_route_remove (old, table);
  700:             return;
  701:           }
  702:     }
  703: 
  704:   /* Check input prefix-list */
  705:   if (PREFIX_NAME_IN (oa))
  706:     {
  707:       if (PREFIX_LIST_IN (oa) == NULL)
  708:         PREFIX_LIST_IN (oa) = prefix_list_lookup (AFI_IP6, PREFIX_NAME_IN (oa));
  709: 
  710:       if (PREFIX_LIST_IN (oa))
  711:         if (prefix_list_apply (PREFIX_LIST_IN (oa), &prefix) != PREFIX_PERMIT)
  712:           {
  713:             if (is_debug)
  714:               zlog_debug ("Prefix was denied by prefix-list");
  715:             if (old)
  716:               ospf6_route_remove (old, table);
  717:             return;
  718:           }
  719:     }
  720: 
  721:   /* (5),(6),(7) the path preference is handled by the sorting
  722:      in the routing table. Always install the path by substituting
  723:      old route (if any). */
  724:   if (old)
  725:     route = ospf6_route_copy (old);
  726:   else
  727:     route = ospf6_route_create ();
  728: 
  729:   route->type = type;
  730:   route->prefix = prefix;
  731:   route->path.origin.type = lsa->header->type;
  732:   route->path.origin.id = lsa->header->id;
  733:   route->path.origin.adv_router = lsa->header->adv_router;
  734:   route->path.router_bits = router_bits;
  735:   route->path.options[0] = options[0];
  736:   route->path.options[1] = options[1];
  737:   route->path.options[2] = options[2];
  738:   route->path.prefix_options = prefix_options;
  739:   route->path.area_id = oa->area_id;
  740:   route->path.type = OSPF6_PATH_TYPE_INTER;
  741:   route->path.cost = abr_entry->path.cost + cost;
  742:   for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
  743:     route->nexthop[i] = abr_entry->nexthop[i];
  744: 
  745:   if (is_debug)
  746:     zlog_debug ("Install route: %s", buf);
  747:   ospf6_route_add (route, table);
  748: }
  749: 
  750: void
  751: ospf6_abr_examin_brouter (u_int32_t router_id)
  752: {
  753:   struct ospf6_lsa *lsa;
  754:   struct ospf6_area *oa;
  755:   struct listnode *node, *nnode;
  756:   u_int16_t type;
  757: 
  758:   for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
  759:     {
  760:       type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  761:       for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
  762:            lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
  763:         ospf6_abr_examin_summary (lsa, oa);
  764: 
  765:       type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  766:       for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
  767:            lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
  768:         ospf6_abr_examin_summary (lsa, oa);
  769:     }
  770: }
  771: 
  772: void
  773: ospf6_abr_reimport (struct ospf6_area *oa)
  774: {
  775:   struct ospf6_lsa *lsa;
  776:   u_int16_t type;
  777: 
  778:   type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  779:   for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
  780:        lsa = ospf6_lsdb_type_next (type, lsa))
  781:     ospf6_abr_examin_summary (lsa, oa);
  782: 
  783:   type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  784:   for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
  785:        lsa = ospf6_lsdb_type_next (type, lsa))
  786:     ospf6_abr_examin_summary (lsa, oa);
  787: }
  788: 
  789: 
  790: 
  791: /* Display functions */
  792: static char *
  793: ospf6_inter_area_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
  794: 					    int buflen, int pos)
  795: {
  796:   struct ospf6_inter_prefix_lsa *prefix_lsa;
  797:   struct in6_addr in6;
  798: 
  799:   if (lsa != NULL)
  800:     {
  801:       prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  802: 	OSPF6_LSA_HEADER_END (lsa->header);
  803: 
  804:       ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
  805:       if (buf)
  806: 	{
  807: 	  inet_ntop (AF_INET6, &in6, buf, buflen);
  808: 	  sprintf (&buf[strlen(buf)], "/%d", prefix_lsa->prefix.prefix_length);
  809: 	}
  810:     }
  811: 
  812:   return (buf);
  813: }
  814: 
  815: static int
  816: ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  817: {
  818:   struct ospf6_inter_prefix_lsa *prefix_lsa;
  819:   char buf[INET6_ADDRSTRLEN];
  820: 
  821:   prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  822:     OSPF6_LSA_HEADER_END (lsa->header);
  823: 
  824:   vty_out (vty, "     Metric: %lu%s",
  825:            (u_long) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa), VNL);
  826: 
  827:   ospf6_prefix_options_printbuf (prefix_lsa->prefix.prefix_options,
  828:                                  buf, sizeof (buf));
  829:   vty_out (vty, "     Prefix Options: %s%s", buf, VNL);
  830: 
  831:   vty_out (vty, "     Prefix: %s%s",
  832: 	   ospf6_inter_area_prefix_lsa_get_prefix_str (lsa, buf, sizeof(buf),
  833: 						       0), VNL);
  834: 
  835:   return 0;
  836: }
  837: 
  838: static char *
  839: ospf6_inter_area_router_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
  840: 					    int buflen, int pos)
  841: {
  842:   struct ospf6_inter_router_lsa *router_lsa;
  843: 
  844:   if (lsa != NULL)
  845:     {
  846:       router_lsa = (struct ospf6_inter_router_lsa *)
  847: 	OSPF6_LSA_HEADER_END (lsa->header);
  848: 
  849: 
  850:       if (buf)
  851: 	inet_ntop (AF_INET, &router_lsa->router_id, buf, buflen);
  852:     }
  853: 
  854:   return (buf);
  855: }
  856: 
  857: static int
  858: ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  859: {
  860:   struct ospf6_inter_router_lsa *router_lsa;
  861:   char buf[64];
  862: 
  863:   router_lsa = (struct ospf6_inter_router_lsa *)
  864:     OSPF6_LSA_HEADER_END (lsa->header);
  865: 
  866:   ospf6_options_printbuf (router_lsa->options, buf, sizeof (buf));
  867:   vty_out (vty, "     Options: %s%s", buf, VNL);
  868:   vty_out (vty, "     Metric: %lu%s",
  869:            (u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa), VNL);
  870: 
  871:   inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
  872:   vty_out (vty, "     Destination Router ID: %s%s", buf, VNL);
  873: 
  874:   return 0;
  875: }
  876: 
  877: /* Debug commands */
  878: DEFUN (debug_ospf6_abr,
  879:        debug_ospf6_abr_cmd,
  880:        "debug ospf6 abr",
  881:        DEBUG_STR
  882:        OSPF6_STR
  883:        "Debug OSPFv3 ABR function\n"
  884:       )
  885: {
  886:   OSPF6_DEBUG_ABR_ON ();
  887:   return CMD_SUCCESS;
  888: }
  889: 
  890: DEFUN (no_debug_ospf6_abr,
  891:        no_debug_ospf6_abr_cmd,
  892:        "no debug ospf6 abr",
  893:        NO_STR
  894:        DEBUG_STR
  895:        OSPF6_STR
  896:        "Debug OSPFv3 ABR function\n"
  897:       )
  898: {
  899:   OSPF6_DEBUG_ABR_OFF ();
  900:   return CMD_SUCCESS;
  901: }
  902: 
  903: int
  904: config_write_ospf6_debug_abr (struct vty *vty)
  905: {
  906:   if (IS_OSPF6_DEBUG_ABR)
  907:     vty_out (vty, "debug ospf6 abr%s", VNL);
  908:   return 0;
  909: }
  910: 
  911: void
  912: install_element_ospf6_debug_abr (void)
  913: {
  914:   install_element (ENABLE_NODE, &debug_ospf6_abr_cmd);
  915:   install_element (ENABLE_NODE, &no_debug_ospf6_abr_cmd);
  916:   install_element (CONFIG_NODE, &debug_ospf6_abr_cmd);
  917:   install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd);
  918: }
  919: 
  920: struct ospf6_lsa_handler inter_prefix_handler =
  921: {
  922:   OSPF6_LSTYPE_INTER_PREFIX,
  923:   "Inter-Prefix",
  924:   "IAP",
  925:   ospf6_inter_area_prefix_lsa_show,
  926:   ospf6_inter_area_prefix_lsa_get_prefix_str,
  927: };
  928: 
  929: struct ospf6_lsa_handler inter_router_handler =
  930: {
  931:   OSPF6_LSTYPE_INTER_ROUTER,
  932:   "Inter-Router",
  933:   "IAR",
  934:   ospf6_inter_area_router_lsa_show,
  935:   ospf6_inter_area_router_lsa_get_prefix_str,
  936: };
  937: 
  938: void
  939: ospf6_abr_init (void)
  940: {
  941:   ospf6_install_lsa_handler (&inter_prefix_handler);
  942:   ospf6_install_lsa_handler (&inter_router_handler);
  943: }
  944: 
  945: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>