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

    1: /*
    2:  * Copyright (C) 2003 Yasuhiro Ohara
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    6:  * GNU Zebra is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2, or (at your option) any
    9:  * later version.
   10:  *
   11:  * GNU Zebra is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
   18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
   19:  * Boston, MA 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: 
   24: #include "log.h"
   25: #include "memory.h"
   26: #include "prefix.h"
   27: #include "command.h"
   28: #include "vty.h"
   29: #include "routemap.h"
   30: #include "table.h"
   31: #include "plist.h"
   32: #include "thread.h"
   33: #include "linklist.h"
   34: 
   35: #include "ospf6_proto.h"
   36: #include "ospf6_lsa.h"
   37: #include "ospf6_lsdb.h"
   38: #include "ospf6_route.h"
   39: #include "ospf6_zebra.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: #include "ospf6_asbr.h"
   47: #include "ospf6_intra.h"
   48: #include "ospf6_flood.h"
   49: #include "ospf6d.h"
   50: 
   51: unsigned char conf_debug_ospf6_asbr = 0;
   52: 
   53: #define ZROUTE_NAME(x) zebra_route_string(x)
   54: 
   55: /* AS External LSA origination */
   56: static void
   57: ospf6_as_external_lsa_originate (struct ospf6_route *route)
   58: {
   59:   char buffer[OSPF6_MAX_LSASIZE];
   60:   struct ospf6_lsa_header *lsa_header;
   61:   struct ospf6_lsa *old, *lsa;
   62:   struct ospf6_external_info *info = route->route_option;
   63: 
   64:   struct ospf6_as_external_lsa *as_external_lsa;
   65:   char buf[64];
   66:   caddr_t p;
   67: 
   68:   /* find previous LSA */
   69:   old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
   70:                            route->path.origin.id, ospf6->router_id,
   71:                            ospf6->lsdb);
   72: 
   73:   if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
   74:     {
   75:       prefix2str (&route->prefix, buf, sizeof (buf));
   76:       zlog_debug ("Originate AS-External-LSA for %s", buf);
   77:     }
   78: 
   79:   /* prepare buffer */
   80:   memset (buffer, 0, sizeof (buffer));
   81:   lsa_header = (struct ospf6_lsa_header *) buffer;
   82:   as_external_lsa = (struct ospf6_as_external_lsa *)
   83:     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
   84:   p = (caddr_t)
   85:     ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
   86: 
   87:   /* Fill AS-External-LSA */
   88:   /* Metric type */
   89:   if (route->path.metric_type == 2)
   90:     SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
   91:   else
   92:     UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
   93: 
   94:   /* forwarding address */
   95:   if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
   96:     SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
   97:   else
   98:     UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
   99: 
  100:   /* external route tag */
  101:   UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
  102: 
  103:   /* Set metric */
  104:   OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
  105: 
  106:   /* prefixlen */
  107:   as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
  108: 
  109:   /* PrefixOptions */
  110:   as_external_lsa->prefix.prefix_options = route->path.prefix_options;
  111: 
  112:   /* don't use refer LS-type */
  113:   as_external_lsa->prefix.prefix_refer_lstype = htons (0);
  114: 
  115:   /* set Prefix */
  116:   memcpy (p, &route->prefix.u.prefix6,
  117:           OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
  118:   ospf6_prefix_apply_mask (&as_external_lsa->prefix);
  119:   p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
  120: 
  121:   /* Forwarding address */
  122:   if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
  123:     {
  124:       memcpy (p, &info->forwarding, sizeof (struct in6_addr));
  125:       p += sizeof (struct in6_addr);
  126:     }
  127: 
  128:   /* External Route Tag */
  129:   if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
  130:     {
  131:       /* xxx */
  132:     }
  133: 
  134:   /* Fill LSA Header */
  135:   lsa_header->age = 0;
  136:   lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
  137:   lsa_header->id = route->path.origin.id;
  138:   lsa_header->adv_router = ospf6->router_id;
  139:   lsa_header->seqnum =
  140:     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  141:                          lsa_header->adv_router, ospf6->lsdb);
  142:   lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
  143: 
  144:   /* LSA checksum */
  145:   ospf6_lsa_checksum (lsa_header);
  146: 
  147:   /* create LSA */
  148:   lsa = ospf6_lsa_create (lsa_header);
  149: 
  150:   /* Originate */
  151:   ospf6_lsa_originate_process (lsa, ospf6);
  152: }
  153: 
  154: 
  155: void
  156: ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
  157: {
  158:   struct ospf6_as_external_lsa *external;
  159:   struct prefix asbr_id;
  160:   struct ospf6_route *asbr_entry, *route;
  161:   char buf[64];
  162:   int i;
  163: 
  164:   external = (struct ospf6_as_external_lsa *)
  165:     OSPF6_LSA_HEADER_END (lsa->header);
  166: 
  167:   if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  168:     zlog_debug ("Calculate AS-External route for %s", lsa->name);
  169: 
  170:   if (lsa->header->adv_router == ospf6->router_id)
  171:     {
  172:       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  173:         zlog_debug ("Ignore self-originated AS-External-LSA");
  174:       return;
  175:     }
  176: 
  177:   if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
  178:     {
  179:       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  180:         zlog_debug ("Ignore LSA with LSInfinity Metric");
  181:       return;
  182:     }
  183: 
  184:   ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
  185:   asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
  186:   if (asbr_entry == NULL ||
  187:       ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
  188:     {
  189:       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  190:         {
  191:           prefix2str (&asbr_id, buf, sizeof (buf));
  192:           zlog_debug ("ASBR entry not found: %s", buf);
  193:         }
  194:       return;
  195:     }
  196: 
  197:   route = ospf6_route_create ();
  198:   route->type = OSPF6_DEST_TYPE_NETWORK;
  199:   route->prefix.family = AF_INET6;
  200:   route->prefix.prefixlen = external->prefix.prefix_length;
  201:   ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
  202: 
  203:   route->path.area_id = asbr_entry->path.area_id;
  204:   route->path.origin.type = lsa->header->type;
  205:   route->path.origin.id = lsa->header->id;
  206:   route->path.origin.adv_router = lsa->header->adv_router;
  207: 
  208:   route->path.prefix_options = external->prefix.prefix_options;
  209:   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
  210:     {
  211:       route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
  212:       route->path.metric_type = 2;
  213:       route->path.cost = asbr_entry->path.cost;
  214:       route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
  215:     }
  216:   else
  217:     {
  218:       route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
  219:       route->path.metric_type = 1;
  220:       route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
  221:       route->path.cost_e2 = 0;
  222:     }
  223: 
  224:   for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
  225:     ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
  226: 
  227:   if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  228:     {
  229:       prefix2str (&route->prefix, buf, sizeof (buf));
  230:       zlog_debug ("AS-External route add: %s", buf);
  231:     }
  232: 
  233:   ospf6_route_add (route, ospf6->route_table);
  234: }
  235: 
  236: void
  237: ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
  238: {
  239:   struct ospf6_as_external_lsa *external;
  240:   struct prefix prefix;
  241:   struct ospf6_route *route;
  242:   char buf[64];
  243: 
  244:   external = (struct ospf6_as_external_lsa *)
  245:     OSPF6_LSA_HEADER_END (lsa->header);
  246: 
  247:   if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  248:     zlog_debug ("Withdraw AS-External route for %s", lsa->name);
  249: 
  250:   if (lsa->header->adv_router == ospf6->router_id)
  251:     {
  252:       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  253:         zlog_debug ("Ignore self-originated AS-External-LSA");
  254:       return;
  255:     }
  256: 
  257:   memset (&prefix, 0, sizeof (struct prefix));
  258:   prefix.family = AF_INET6;
  259:   prefix.prefixlen = external->prefix.prefix_length;
  260:   ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
  261: 
  262:   route = ospf6_route_lookup (&prefix, ospf6->route_table);
  263:   if (route == NULL)
  264:     {
  265:       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  266:         {
  267:           prefix2str (&prefix, buf, sizeof (buf));
  268:           zlog_debug ("AS-External route %s not found", buf);
  269:         }
  270:       return;
  271:     }
  272: 
  273:   for (ospf6_route_lock (route);
  274:        route && ospf6_route_is_prefix (&prefix, route);
  275:        route = ospf6_route_next (route))
  276:     {
  277:       if (route->type != OSPF6_DEST_TYPE_NETWORK)
  278:         continue;
  279:       if (route->path.origin.type != lsa->header->type)
  280:         continue;
  281:       if (route->path.origin.id != lsa->header->id)
  282:         continue;
  283:       if (route->path.origin.adv_router != lsa->header->adv_router)
  284:         continue;
  285: 
  286:       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  287:         {
  288:           prefix2str (&route->prefix, buf, sizeof (buf));
  289:           zlog_debug ("AS-External route remove: %s", buf);
  290:         }
  291:       ospf6_route_remove (route, ospf6->route_table);
  292:     }
  293: }
  294: 
  295: void
  296: ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
  297: {
  298:   struct ospf6_lsa *lsa;
  299:   u_int16_t type;
  300:   u_int32_t router;
  301: 
  302:   if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST))
  303:     {
  304:       char buf[16];
  305:       inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&asbr_entry->prefix),
  306:                  buf, sizeof (buf));
  307:        zlog_info ("ignore non-best path: lsentry %s add", buf);
  308:       return;
  309:     }
  310: 
  311:   type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
  312:   router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
  313:   for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa;
  314:        lsa = ospf6_lsdb_type_router_next (type, router, lsa))
  315:     {
  316:       if (! OSPF6_LSA_IS_MAXAGE (lsa))
  317:         ospf6_asbr_lsa_add (lsa);
  318:     }
  319: }
  320: 
  321: void
  322: ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
  323: {
  324:   struct ospf6_lsa *lsa;
  325:   u_int16_t type;
  326:   u_int32_t router;
  327: 
  328:   type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
  329:   router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
  330:   for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
  331:        lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
  332:     ospf6_asbr_lsa_remove (lsa);
  333: }
  334: 
  335: 
  336: 
  337: /* redistribute function */
  338: 
  339: static void
  340: ospf6_asbr_routemap_set (int type, const char *mapname)
  341: {
  342:   if (ospf6->rmap[type].name)
  343:     free (ospf6->rmap[type].name);
  344:   ospf6->rmap[type].name = strdup (mapname);
  345:   ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
  346: }
  347: 
  348: static void
  349: ospf6_asbr_routemap_unset (int type)
  350: {
  351:   if (ospf6->rmap[type].name)
  352:     free (ospf6->rmap[type].name);
  353:   ospf6->rmap[type].name = NULL;
  354:   ospf6->rmap[type].map = NULL;
  355: }
  356: 
  357: static void
  358: ospf6_asbr_routemap_update (const char *mapname)
  359: {
  360:   int type;
  361: 
  362:   if (ospf6 == NULL)
  363:     return;
  364: 
  365:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  366:     {
  367:       if (ospf6->rmap[type].name)
  368:         ospf6->rmap[type].map =
  369:           route_map_lookup_by_name (ospf6->rmap[type].name);
  370:       else
  371:         ospf6->rmap[type].map = NULL;
  372:     }
  373: }
  374: 
  375: int
  376: ospf6_asbr_is_asbr (struct ospf6 *o)
  377: {
  378:   return o->external_table->count;
  379: }
  380: 
  381: static void
  382: ospf6_asbr_redistribute_set (int type)
  383: {
  384:   ospf6_zebra_redistribute (type);
  385: }
  386: 
  387: static void
  388: ospf6_asbr_redistribute_unset (int type)
  389: {
  390:   struct ospf6_route *route;
  391:   struct ospf6_external_info *info;
  392: 
  393:   ospf6_zebra_no_redistribute (type);
  394: 
  395:   for (route = ospf6_route_head (ospf6->external_table); route;
  396:        route = ospf6_route_next (route))
  397:     {
  398:       info = route->route_option;
  399:       if (info->type != type)
  400:         continue;
  401: 
  402:       ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
  403:                                       &route->prefix);
  404:     }
  405: }
  406: 
  407: void
  408: ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
  409:                              u_int nexthop_num, struct in6_addr *nexthop)
  410: {
  411:   int ret;
  412:   struct ospf6_route troute;
  413:   struct ospf6_external_info tinfo;
  414:   struct ospf6_route *route, *match;
  415:   struct ospf6_external_info *info;
  416:   struct prefix prefix_id;
  417:   struct route_node *node;
  418:   char pbuf[64], ibuf[16];
  419:   struct listnode *lnode, *lnnode;
  420:   struct ospf6_area *oa;
  421: 
  422:   if (! ospf6_zebra_is_redistribute (type))
  423:     return;
  424: 
  425:   if (IS_OSPF6_DEBUG_ASBR)
  426:     {
  427:       prefix2str (prefix, pbuf, sizeof (pbuf));
  428:       zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
  429:     }
  430: 
  431:   /* if route-map was specified but not found, do not advertise */
  432:   if (ospf6->rmap[type].name)
  433:     {
  434:       if (ospf6->rmap[type].map == NULL)
  435:         ospf6_asbr_routemap_update (NULL);
  436:       if (ospf6->rmap[type].map == NULL)
  437:         {
  438:           zlog_warn ("route-map \"%s\" not found, suppress redistributing",
  439:                      ospf6->rmap[type].name);
  440:           return;
  441:         }
  442:     }
  443: 
  444:   /* apply route-map */
  445:   if (ospf6->rmap[type].map)
  446:     {
  447:       memset (&troute, 0, sizeof (troute));
  448:       memset (&tinfo, 0, sizeof (tinfo));
  449:       troute.route_option = &tinfo;
  450: 
  451:       ret = route_map_apply (ospf6->rmap[type].map, prefix,
  452:                              RMAP_OSPF6, &troute);
  453:       if (ret == RMAP_DENYMATCH)
  454:         {
  455:           if (IS_OSPF6_DEBUG_ASBR)
  456:             zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
  457:           return;
  458:         }
  459:     }
  460: 
  461:   match = ospf6_route_lookup (prefix, ospf6->external_table);
  462:   if (match)
  463:     {
  464:       info = match->route_option;
  465: 
  466:       /* copy result of route-map */
  467:       if (ospf6->rmap[type].map)
  468:         {
  469:           if (troute.path.metric_type)
  470:             match->path.metric_type = troute.path.metric_type;
  471:           if (troute.path.cost)
  472:             match->path.cost = troute.path.cost;
  473:           if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
  474:             memcpy (&info->forwarding, &tinfo.forwarding,
  475:                     sizeof (struct in6_addr));
  476:         }
  477: 
  478:       info->type = type;
  479:       match->nexthop[0].ifindex = ifindex;
  480:       if (nexthop_num && nexthop)
  481:         memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
  482: 
  483:       /* create/update binding in external_id_table */
  484:       prefix_id.family = AF_INET;
  485:       prefix_id.prefixlen = 32;
  486:       prefix_id.u.prefix4.s_addr = htonl (info->id);
  487:       node = route_node_get (ospf6->external_id_table, &prefix_id);
  488:       node->info = match;
  489: 
  490:       if (IS_OSPF6_DEBUG_ASBR)
  491:         {
  492:           inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
  493:           zlog_debug ("Advertise as AS-External Id:%s", ibuf);
  494:         }
  495: 
  496:       match->path.origin.id = htonl (info->id);
  497:       ospf6_as_external_lsa_originate (match);
  498:       return;
  499:     }
  500: 
  501:   /* create new entry */
  502:   route = ospf6_route_create ();
  503:   route->type = OSPF6_DEST_TYPE_NETWORK;
  504:   memcpy (&route->prefix, prefix, sizeof (struct prefix));
  505: 
  506:   info = (struct ospf6_external_info *)
  507:     XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
  508:   route->route_option = info;
  509:   info->id = ospf6->external_id++;
  510: 
  511:   /* copy result of route-map */
  512:   if (ospf6->rmap[type].map)
  513:     {
  514:       if (troute.path.metric_type)
  515:         route->path.metric_type = troute.path.metric_type;
  516:       if (troute.path.cost)
  517:         route->path.cost = troute.path.cost;
  518:       if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
  519:         memcpy (&info->forwarding, &tinfo.forwarding,
  520:                 sizeof (struct in6_addr));
  521:     }
  522: 
  523:   info->type = type;
  524:   route->nexthop[0].ifindex = ifindex;
  525:   if (nexthop_num && nexthop)
  526:     memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
  527: 
  528:   /* create/update binding in external_id_table */
  529:   prefix_id.family = AF_INET;
  530:   prefix_id.prefixlen = 32;
  531:   prefix_id.u.prefix4.s_addr = htonl (info->id);
  532:   node = route_node_get (ospf6->external_id_table, &prefix_id);
  533:   node->info = route;
  534: 
  535:   route = ospf6_route_add (route, ospf6->external_table);
  536:   route->route_option = info;
  537: 
  538:   if (IS_OSPF6_DEBUG_ASBR)
  539:     {
  540:       inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
  541:       zlog_debug ("Advertise as AS-External Id:%s", ibuf);
  542:     }
  543: 
  544:   route->path.origin.id = htonl (info->id);
  545:   ospf6_as_external_lsa_originate (route);
  546: 
  547:   /* Router-Bit (ASBR Flag) may have to be updated */
  548:   for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
  549:     OSPF6_ROUTER_LSA_SCHEDULE (oa);
  550: }
  551: 
  552: void
  553: ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
  554: {
  555:   struct ospf6_route *match;
  556:   struct ospf6_external_info *info = NULL;
  557:   struct route_node *node;
  558:   struct ospf6_lsa *lsa;
  559:   struct prefix prefix_id;
  560:   char pbuf[64], ibuf[16];
  561:   struct listnode *lnode, *lnnode;
  562:   struct ospf6_area *oa;
  563: 
  564:   match = ospf6_route_lookup (prefix, ospf6->external_table);
  565:   if (match == NULL)
  566:     {
  567:       if (IS_OSPF6_DEBUG_ASBR)
  568:         {
  569:           prefix2str (prefix, pbuf, sizeof (pbuf));
  570:           zlog_debug ("No such route %s to withdraw", pbuf);
  571:         }
  572:       return;
  573:     }
  574: 
  575:   info = match->route_option;
  576:   assert (info);
  577: 
  578:   if (info->type != type)
  579:     {
  580:       if (IS_OSPF6_DEBUG_ASBR)
  581:         {
  582:           prefix2str (prefix, pbuf, sizeof (pbuf));
  583:           zlog_debug ("Original protocol mismatch: %s", pbuf);
  584:         }
  585:       return;
  586:     }
  587: 
  588:   if (IS_OSPF6_DEBUG_ASBR)
  589:     {
  590:       prefix2str (prefix, pbuf, sizeof (pbuf));
  591:       inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
  592:       zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
  593:     }
  594: 
  595:   lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
  596:                            htonl (info->id), ospf6->router_id, ospf6->lsdb);
  597:   if (lsa)
  598:     ospf6_lsa_purge (lsa);
  599: 
  600:   /* remove binding in external_id_table */
  601:   prefix_id.family = AF_INET;
  602:   prefix_id.prefixlen = 32;
  603:   prefix_id.u.prefix4.s_addr = htonl (info->id);
  604:   node = route_node_lookup (ospf6->external_id_table, &prefix_id);
  605:   assert (node);
  606:   node->info = NULL;
  607:   route_unlock_node (node);
  608: 
  609:   ospf6_route_remove (match, ospf6->external_table);
  610:   XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
  611: 
  612:   /* Router-Bit (ASBR Flag) may have to be updated */
  613:   for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
  614:     OSPF6_ROUTER_LSA_SCHEDULE (oa);
  615: }
  616: 
  617: DEFUN (ospf6_redistribute,
  618:        ospf6_redistribute_cmd,
  619:        "redistribute (static|kernel|connected|ripng|bgp)",
  620:        "Redistribute\n"
  621:        "Static route\n"
  622:        "Kernel route\n"
  623:        "Connected route\n"
  624:        "RIPng route\n"
  625:        "BGP route\n"
  626:       )
  627: {
  628:   int type = 0;
  629: 
  630:   if (strncmp (argv[0], "sta", 3) == 0)
  631:     type = ZEBRA_ROUTE_STATIC;
  632:   else if (strncmp (argv[0], "ker", 3) == 0)
  633:     type = ZEBRA_ROUTE_KERNEL;
  634:   else if (strncmp (argv[0], "con", 3) == 0)
  635:     type = ZEBRA_ROUTE_CONNECT;
  636:   else if (strncmp (argv[0], "rip", 3) == 0)
  637:     type = ZEBRA_ROUTE_RIPNG;
  638:   else if (strncmp (argv[0], "bgp", 3) == 0)
  639:     type = ZEBRA_ROUTE_BGP;
  640: 
  641:   ospf6_asbr_redistribute_unset (type);
  642:   ospf6_asbr_routemap_unset (type);
  643:   ospf6_asbr_redistribute_set (type);
  644:   return CMD_SUCCESS;
  645: }
  646: 
  647: DEFUN (ospf6_redistribute_routemap,
  648:        ospf6_redistribute_routemap_cmd,
  649:        "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
  650:        "Redistribute\n"
  651:        "Static routes\n"
  652:        "Kernel route\n"
  653:        "Connected route\n"
  654:        "RIPng route\n"
  655:        "BGP route\n"
  656:        "Route map reference\n"
  657:        "Route map name\n"
  658:       )
  659: {
  660:   int type = 0;
  661: 
  662:   if (strncmp (argv[0], "sta", 3) == 0)
  663:     type = ZEBRA_ROUTE_STATIC;
  664:   else if (strncmp (argv[0], "ker", 3) == 0)
  665:     type = ZEBRA_ROUTE_KERNEL;
  666:   else if (strncmp (argv[0], "con", 3) == 0)
  667:     type = ZEBRA_ROUTE_CONNECT;
  668:   else if (strncmp (argv[0], "rip", 3) == 0)
  669:     type = ZEBRA_ROUTE_RIPNG;
  670:   else if (strncmp (argv[0], "bgp", 3) == 0)
  671:     type = ZEBRA_ROUTE_BGP;
  672: 
  673:   ospf6_asbr_redistribute_unset (type);
  674:   ospf6_asbr_routemap_set (type, argv[1]);
  675:   ospf6_asbr_redistribute_set (type);
  676:   return CMD_SUCCESS;
  677: }
  678: 
  679: DEFUN (no_ospf6_redistribute,
  680:        no_ospf6_redistribute_cmd,
  681:        "no redistribute (static|kernel|connected|ripng|bgp)",
  682:        NO_STR
  683:        "Redistribute\n"
  684:        "Static route\n"
  685:        "Kernel route\n"
  686:        "Connected route\n"
  687:        "RIPng route\n"
  688:        "BGP route\n"
  689:       )
  690: {
  691:   int type = 0;
  692: 
  693:   if (strncmp (argv[0], "sta", 3) == 0)
  694:     type = ZEBRA_ROUTE_STATIC;
  695:   else if (strncmp (argv[0], "ker", 3) == 0)
  696:     type = ZEBRA_ROUTE_KERNEL;
  697:   else if (strncmp (argv[0], "con", 3) == 0)
  698:     type = ZEBRA_ROUTE_CONNECT;
  699:   else if (strncmp (argv[0], "rip", 3) == 0)
  700:     type = ZEBRA_ROUTE_RIPNG;
  701:   else if (strncmp (argv[0], "bgp", 3) == 0)
  702:     type = ZEBRA_ROUTE_BGP;
  703: 
  704:   ospf6_asbr_redistribute_unset (type);
  705:   ospf6_asbr_routemap_unset (type);
  706: 
  707:   return CMD_SUCCESS;
  708: }
  709: 
  710: int
  711: ospf6_redistribute_config_write (struct vty *vty)
  712: {
  713:   int type;
  714: 
  715:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  716:     {
  717:       if (type == ZEBRA_ROUTE_OSPF6)
  718:         continue;
  719:       if (! ospf6_zebra_is_redistribute (type))
  720:         continue;
  721: 
  722:       if (ospf6->rmap[type].name)
  723:         vty_out (vty, " redistribute %s route-map %s%s",
  724:                  ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
  725:       else
  726:         vty_out (vty, " redistribute %s%s",
  727:                  ZROUTE_NAME (type), VNL);
  728:     }
  729: 
  730:   return 0;
  731: }
  732: 
  733: static void
  734: ospf6_redistribute_show_config (struct vty *vty)
  735: {
  736:   int type;
  737:   int nroute[ZEBRA_ROUTE_MAX];
  738:   int total;
  739:   struct ospf6_route *route;
  740:   struct ospf6_external_info *info;
  741: 
  742:   total = 0;
  743:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  744:     nroute[type] = 0;
  745:   for (route = ospf6_route_head (ospf6->external_table); route;
  746:        route = ospf6_route_next (route))
  747:     {
  748:       info = route->route_option;
  749:       nroute[info->type]++;
  750:       total++;
  751:     }
  752: 
  753:   vty_out (vty, "Redistributing External Routes from:%s", VNL);
  754:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  755:     {
  756:       if (type == ZEBRA_ROUTE_OSPF6)
  757:         continue;
  758:       if (! ospf6_zebra_is_redistribute (type))
  759:         continue;
  760: 
  761:       if (ospf6->rmap[type].name)
  762:         vty_out (vty, "    %d: %s with route-map \"%s\"%s%s", nroute[type],
  763:                  ZROUTE_NAME (type), ospf6->rmap[type].name,
  764:                  (ospf6->rmap[type].map ? "" : " (not found !)"),
  765:                  VNL);
  766:       else
  767:         vty_out (vty, "    %d: %s%s", nroute[type],
  768:                  ZROUTE_NAME (type), VNL);
  769:     }
  770:   vty_out (vty, "Total %d routes%s", total, VNL);
  771: }
  772: 
  773: 
  774: 
  775: /* Routemap Functions */
  776: static route_map_result_t
  777: ospf6_routemap_rule_match_address_prefixlist (void *rule,
  778:                                               struct prefix *prefix,
  779:                                               route_map_object_t type,
  780:                                               void *object)
  781: {
  782:   struct prefix_list *plist;
  783: 
  784:   if (type != RMAP_OSPF6)
  785:     return RMAP_NOMATCH;
  786: 
  787:   plist = prefix_list_lookup (AFI_IP6, (char *) rule);
  788:   if (plist == NULL)
  789:     return RMAP_NOMATCH;
  790: 
  791:   return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  792:           RMAP_NOMATCH : RMAP_MATCH);
  793: }
  794: 
  795: static void *
  796: ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
  797: {
  798:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  799: }
  800: 
  801: static void
  802: ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
  803: {
  804:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  805: }
  806: 
  807: struct route_map_rule_cmd
  808: ospf6_routemap_rule_match_address_prefixlist_cmd =
  809: {
  810:   "ipv6 address prefix-list",
  811:   ospf6_routemap_rule_match_address_prefixlist,
  812:   ospf6_routemap_rule_match_address_prefixlist_compile,
  813:   ospf6_routemap_rule_match_address_prefixlist_free,
  814: };
  815: 
  816: static route_map_result_t
  817: ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
  818:                                      route_map_object_t type, void *object)
  819: {
  820:   char *metric_type = rule;
  821:   struct ospf6_route *route = object;
  822: 
  823:   if (type != RMAP_OSPF6)
  824:     return RMAP_OKAY;
  825: 
  826:   if (strcmp (metric_type, "type-2") == 0)
  827:     route->path.metric_type = 2;
  828:   else
  829:     route->path.metric_type = 1;
  830: 
  831:   return RMAP_OKAY;
  832: }
  833: 
  834: static void *
  835: ospf6_routemap_rule_set_metric_type_compile (const char *arg)
  836: {
  837:   if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
  838:     return NULL;
  839:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  840: }
  841: 
  842: static void
  843: ospf6_routemap_rule_set_metric_type_free (void *rule)
  844: {
  845:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  846: }
  847: 
  848: struct route_map_rule_cmd
  849: ospf6_routemap_rule_set_metric_type_cmd =
  850: {
  851:   "metric-type",
  852:   ospf6_routemap_rule_set_metric_type,
  853:   ospf6_routemap_rule_set_metric_type_compile,
  854:   ospf6_routemap_rule_set_metric_type_free,
  855: };
  856: 
  857: static route_map_result_t
  858: ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
  859:                                 route_map_object_t type, void *object)
  860: {
  861:   char *metric = rule;
  862:   struct ospf6_route *route = object;
  863: 
  864:   if (type != RMAP_OSPF6)
  865:     return RMAP_OKAY;
  866: 
  867:   route->path.cost = atoi (metric);
  868:   return RMAP_OKAY;
  869: }
  870: 
  871: static void *
  872: ospf6_routemap_rule_set_metric_compile (const char *arg)
  873: {
  874:   u_int32_t metric;
  875:   char *endp;
  876:   metric = strtoul (arg, &endp, 0);
  877:   if (metric > LS_INFINITY || *endp != '\0')
  878:     return NULL;
  879:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  880: }
  881: 
  882: static void
  883: ospf6_routemap_rule_set_metric_free (void *rule)
  884: {
  885:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  886: }
  887: 
  888: struct route_map_rule_cmd
  889: ospf6_routemap_rule_set_metric_cmd =
  890: {
  891:   "metric",
  892:   ospf6_routemap_rule_set_metric,
  893:   ospf6_routemap_rule_set_metric_compile,
  894:   ospf6_routemap_rule_set_metric_free,
  895: };
  896: 
  897: static route_map_result_t
  898: ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
  899:                                     route_map_object_t type, void *object)
  900: {
  901:   char *forwarding = rule;
  902:   struct ospf6_route *route = object;
  903:   struct ospf6_external_info *info = route->route_option;
  904: 
  905:   if (type != RMAP_OSPF6)
  906:     return RMAP_OKAY;
  907: 
  908:   if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
  909:     {
  910:       memset (&info->forwarding, 0, sizeof (struct in6_addr));
  911:       return RMAP_ERROR;
  912:     }
  913: 
  914:   return RMAP_OKAY;
  915: }
  916: 
  917: static void *
  918: ospf6_routemap_rule_set_forwarding_compile (const char *arg)
  919: {
  920:   struct in6_addr a;
  921:   if (inet_pton (AF_INET6, arg, &a) != 1)
  922:     return NULL;
  923:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  924: }
  925: 
  926: static void
  927: ospf6_routemap_rule_set_forwarding_free (void *rule)
  928: {
  929:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  930: }
  931: 
  932: struct route_map_rule_cmd
  933: ospf6_routemap_rule_set_forwarding_cmd =
  934: {
  935:   "forwarding-address",
  936:   ospf6_routemap_rule_set_forwarding,
  937:   ospf6_routemap_rule_set_forwarding_compile,
  938:   ospf6_routemap_rule_set_forwarding_free,
  939: };
  940: 
  941: static int
  942: route_map_command_status (struct vty *vty, int ret)
  943: {
  944:   if (! ret)
  945:     return CMD_SUCCESS;
  946: 
  947:   switch (ret)
  948:     {
  949:     case RMAP_RULE_MISSING:
  950:       vty_out (vty, "Can't find rule.%s", VNL);
  951:       break;
  952:     case RMAP_COMPILE_ERROR:
  953:       vty_out (vty, "Argument is malformed.%s", VNL);
  954:       break;
  955:     default:
  956:       vty_out (vty, "route-map add set failed.%s", VNL);
  957:       break;
  958:     }
  959:   return CMD_WARNING;
  960: }
  961: 
  962: /* add "match address" */
  963: DEFUN (ospf6_routemap_match_address_prefixlist,
  964:        ospf6_routemap_match_address_prefixlist_cmd,
  965:        "match ipv6 address prefix-list WORD",
  966:        "Match values\n"
  967:        IPV6_STR
  968:        "Match address of route\n"
  969:        "Match entries of prefix-lists\n"
  970:        "IPv6 prefix-list name\n")
  971: {
  972:   int ret = route_map_add_match ((struct route_map_index *) vty->index,
  973:                                  "ipv6 address prefix-list", argv[0]);
  974:   return route_map_command_status (vty, ret);
  975: }
  976: 
  977: /* delete "match address" */
  978: DEFUN (ospf6_routemap_no_match_address_prefixlist,
  979:        ospf6_routemap_no_match_address_prefixlist_cmd,
  980:        "no match ipv6 address prefix-list WORD",
  981:        NO_STR
  982:        "Match values\n"
  983:        IPV6_STR
  984:        "Match address of route\n"
  985:        "Match entries of prefix-lists\n"
  986:        "IPv6 prefix-list name\n")
  987: {
  988:   int ret = route_map_delete_match ((struct route_map_index *) vty->index,
  989:                                     "ipv6 address prefix-list", argv[0]);
  990:   return route_map_command_status (vty, ret);
  991: }
  992: 
  993: /* add "set metric-type" */
  994: DEFUN (ospf6_routemap_set_metric_type,
  995:        ospf6_routemap_set_metric_type_cmd,
  996:        "set metric-type (type-1|type-2)",
  997:        "Set value\n"
  998:        "Type of metric\n"
  999:        "OSPF6 external type 1 metric\n"
 1000:        "OSPF6 external type 2 metric\n")
 1001: {
 1002:   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 1003:                                "metric-type", argv[0]);
 1004:   return route_map_command_status (vty, ret);
 1005: }
 1006: 
 1007: /* delete "set metric-type" */
 1008: DEFUN (ospf6_routemap_no_set_metric_type,
 1009:        ospf6_routemap_no_set_metric_type_cmd,
 1010:        "no set metric-type (type-1|type-2)",
 1011:        NO_STR
 1012:        "Set value\n"
 1013:        "Type of metric\n"
 1014:        "OSPF6 external type 1 metric\n"
 1015:        "OSPF6 external type 2 metric\n")
 1016: {
 1017:   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 1018:                                   "metric-type", argv[0]);
 1019:   return route_map_command_status (vty, ret);
 1020: }
 1021: 
 1022: /* add "set metric" */
 1023: DEFUN (set_metric,
 1024:        set_metric_cmd,
 1025:        "set metric <0-4294967295>",
 1026:        "Set value\n"
 1027:        "Metric value\n"
 1028:        "Metric value\n")
 1029: {
 1030:   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 1031:                                "metric", argv[0]);
 1032:   return route_map_command_status (vty, ret);
 1033: }
 1034: 
 1035: /* delete "set metric" */
 1036: DEFUN (no_set_metric,
 1037:        no_set_metric_cmd,
 1038:        "no set metric <0-4294967295>",
 1039:        NO_STR
 1040:        "Set value\n"
 1041:        "Metric\n"
 1042:        "METRIC value\n")
 1043: {
 1044:   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 1045:                                   "metric", argv[0]);
 1046:   return route_map_command_status (vty, ret);
 1047: }
 1048: 
 1049: /* add "set forwarding-address" */
 1050: DEFUN (ospf6_routemap_set_forwarding,
 1051:        ospf6_routemap_set_forwarding_cmd,
 1052:        "set forwarding-address X:X::X:X",
 1053:        "Set value\n"
 1054:        "Forwarding Address\n"
 1055:        "IPv6 Address\n")
 1056: {
 1057:   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 1058:                                "forwarding-address", argv[0]);
 1059:   return route_map_command_status (vty, ret);
 1060: }
 1061: 
 1062: /* delete "set forwarding-address" */
 1063: DEFUN (ospf6_routemap_no_set_forwarding,
 1064:        ospf6_routemap_no_set_forwarding_cmd,
 1065:        "no set forwarding-address X:X::X:X",
 1066:        NO_STR
 1067:        "Set value\n"
 1068:        "Forwarding Address\n"
 1069:        "IPv6 Address\n")
 1070: {
 1071:   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 1072:                                   "forwarding-address", argv[0]);
 1073:   return route_map_command_status (vty, ret);
 1074: }
 1075: 
 1076: static void
 1077: ospf6_routemap_init (void)
 1078: {
 1079:   route_map_init ();
 1080:   route_map_init_vty ();
 1081:   route_map_add_hook (ospf6_asbr_routemap_update);
 1082:   route_map_delete_hook (ospf6_asbr_routemap_update);
 1083: 
 1084:   route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
 1085:   route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
 1086:   route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
 1087:   route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
 1088: 
 1089:   /* Match address prefix-list */
 1090:   install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
 1091:   install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
 1092: 
 1093:   /* ASE Metric Type (e.g. Type-1/Type-2) */
 1094:   install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
 1095:   install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
 1096: 
 1097:   /* ASE Metric */
 1098:   install_element (RMAP_NODE, &set_metric_cmd);
 1099:   install_element (RMAP_NODE, &no_set_metric_cmd);
 1100: 
 1101:   /* ASE Metric */
 1102:   install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
 1103:   install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
 1104: }
 1105: 
 1106: 
 1107: /* Display functions */
 1108: static int
 1109: ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
 1110: {
 1111:   struct ospf6_as_external_lsa *external;
 1112:   char buf[64];
 1113:   struct in6_addr in6, *forwarding;
 1114: 
 1115:   assert (lsa->header);
 1116:   external = (struct ospf6_as_external_lsa *)
 1117:     OSPF6_LSA_HEADER_END (lsa->header);
 1118:   
 1119:   /* bits */
 1120:   snprintf (buf, sizeof (buf), "%c%c%c",
 1121:     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
 1122:     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
 1123:     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
 1124: 
 1125:   vty_out (vty, "     Bits: %s%s", buf, VNL);
 1126:   vty_out (vty, "     Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
 1127:            VNL);
 1128: 
 1129:   ospf6_prefix_options_printbuf (external->prefix.prefix_options,
 1130:                                  buf, sizeof (buf));
 1131:   vty_out (vty, "     Prefix Options: %s%s", buf,
 1132:            VNL);
 1133: 
 1134:   vty_out (vty, "     Referenced LSType: %d%s",
 1135:            ntohs (external->prefix.prefix_refer_lstype),
 1136:            VNL);
 1137: 
 1138:   ospf6_prefix_in6_addr (&in6, &external->prefix);
 1139:   inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
 1140:   vty_out (vty, "     Prefix: %s/%d%s", buf,
 1141:            external->prefix.prefix_length, VNL);
 1142: 
 1143:   /* Forwarding-Address */
 1144:   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
 1145:     {
 1146:       forwarding = (struct in6_addr *)
 1147:         ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
 1148:          OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
 1149:       inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
 1150:       vty_out (vty, "     Forwarding-Address: %s%s", buf, VNL);
 1151:     }
 1152: 
 1153:   return 0;
 1154: }
 1155: 
 1156: static void
 1157: ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
 1158: {
 1159:   struct ospf6_external_info *info = route->route_option;
 1160:   char prefix[64], id[16], forwarding[64];
 1161:   u_int32_t tmp_id;
 1162: 
 1163:   prefix2str (&route->prefix, prefix, sizeof (prefix));
 1164:   tmp_id = ntohl (info->id);
 1165:   inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
 1166:   if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
 1167:     inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
 1168:   else
 1169:     snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
 1170:               route->nexthop[0].ifindex);
 1171: 
 1172:   vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
 1173:            zebra_route_char(info->type),
 1174:            prefix, id, route->path.metric_type,
 1175:            (u_long) (route->path.metric_type == 2 ?
 1176:                      route->path.cost_e2 : route->path.cost),
 1177:            forwarding, VNL);
 1178: }
 1179: 
 1180: DEFUN (show_ipv6_ospf6_redistribute,
 1181:        show_ipv6_ospf6_redistribute_cmd,
 1182:        "show ipv6 ospf6 redistribute",
 1183:        SHOW_STR
 1184:        IP6_STR
 1185:        OSPF6_STR
 1186:        "redistributing External information\n"
 1187:        )
 1188: {
 1189:   struct ospf6_route *route;
 1190: 
 1191:   ospf6_redistribute_show_config (vty);
 1192: 
 1193:   for (route = ospf6_route_head (ospf6->external_table); route;
 1194:        route = ospf6_route_next (route))
 1195:     ospf6_asbr_external_route_show (vty, route);
 1196: 
 1197:   return CMD_SUCCESS;
 1198: }
 1199: 
 1200: struct ospf6_lsa_handler as_external_handler =
 1201: {
 1202:   OSPF6_LSTYPE_AS_EXTERNAL,
 1203:   "AS-External",
 1204:   ospf6_as_external_lsa_show
 1205: };
 1206: 
 1207: void
 1208: ospf6_asbr_init (void)
 1209: {
 1210:   ospf6_routemap_init ();
 1211: 
 1212:   ospf6_install_lsa_handler (&as_external_handler);
 1213: 
 1214:   install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
 1215:   install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
 1216: 
 1217:   install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
 1218:   install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
 1219:   install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
 1220: }
 1221: 
 1222: void
 1223: ospf6_asbr_terminate (void)
 1224: {
 1225:   route_map_finish ();
 1226: }
 1227: 
 1228: DEFUN (debug_ospf6_asbr,
 1229:        debug_ospf6_asbr_cmd,
 1230:        "debug ospf6 asbr",
 1231:        DEBUG_STR
 1232:        OSPF6_STR
 1233:        "Debug OSPFv3 ASBR function\n"
 1234:       )
 1235: {
 1236:   OSPF6_DEBUG_ASBR_ON ();
 1237:   return CMD_SUCCESS;
 1238: }
 1239: 
 1240: DEFUN (no_debug_ospf6_asbr,
 1241:        no_debug_ospf6_asbr_cmd,
 1242:        "no debug ospf6 asbr",
 1243:        NO_STR
 1244:        DEBUG_STR
 1245:        OSPF6_STR
 1246:        "Debug OSPFv3 ASBR function\n"
 1247:       )
 1248: {
 1249:   OSPF6_DEBUG_ASBR_OFF ();
 1250:   return CMD_SUCCESS;
 1251: }
 1252: 
 1253: int
 1254: config_write_ospf6_debug_asbr (struct vty *vty)
 1255: {
 1256:   if (IS_OSPF6_DEBUG_ASBR)
 1257:     vty_out (vty, "debug ospf6 asbr%s", VNL);
 1258:   return 0;
 1259: }
 1260: 
 1261: void
 1262: install_element_ospf6_debug_asbr ()
 1263: {
 1264:   install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
 1265:   install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
 1266:   install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
 1267:   install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
 1268: }
 1269: 
 1270: 

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