Annotation of embedaddon/quagga/ospf6d/ospf6_asbr.c, revision 1.1.1.1

1.1       misho       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>