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

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;
1.1.1.2 ! misho     450:       tinfo.ifindex = ifindex;
1.1       misho     451: 
                    452:       ret = route_map_apply (ospf6->rmap[type].map, prefix,
                    453:                              RMAP_OSPF6, &troute);
                    454:       if (ret == RMAP_DENYMATCH)
                    455:         {
                    456:           if (IS_OSPF6_DEBUG_ASBR)
                    457:             zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
                    458:           return;
                    459:         }
                    460:     }
                    461: 
                    462:   match = ospf6_route_lookup (prefix, ospf6->external_table);
                    463:   if (match)
                    464:     {
                    465:       info = match->route_option;
                    466: 
                    467:       /* copy result of route-map */
                    468:       if (ospf6->rmap[type].map)
                    469:         {
                    470:           if (troute.path.metric_type)
                    471:             match->path.metric_type = troute.path.metric_type;
                    472:           if (troute.path.cost)
                    473:             match->path.cost = troute.path.cost;
                    474:           if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
                    475:             memcpy (&info->forwarding, &tinfo.forwarding,
                    476:                     sizeof (struct in6_addr));
                    477:         }
                    478: 
                    479:       info->type = type;
                    480:       match->nexthop[0].ifindex = ifindex;
                    481:       if (nexthop_num && nexthop)
                    482:         memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
                    483: 
                    484:       /* create/update binding in external_id_table */
                    485:       prefix_id.family = AF_INET;
                    486:       prefix_id.prefixlen = 32;
                    487:       prefix_id.u.prefix4.s_addr = htonl (info->id);
                    488:       node = route_node_get (ospf6->external_id_table, &prefix_id);
                    489:       node->info = match;
                    490: 
                    491:       if (IS_OSPF6_DEBUG_ASBR)
                    492:         {
                    493:           inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
                    494:           zlog_debug ("Advertise as AS-External Id:%s", ibuf);
                    495:         }
                    496: 
                    497:       match->path.origin.id = htonl (info->id);
                    498:       ospf6_as_external_lsa_originate (match);
                    499:       return;
                    500:     }
                    501: 
                    502:   /* create new entry */
                    503:   route = ospf6_route_create ();
                    504:   route->type = OSPF6_DEST_TYPE_NETWORK;
                    505:   memcpy (&route->prefix, prefix, sizeof (struct prefix));
                    506: 
                    507:   info = (struct ospf6_external_info *)
                    508:     XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
                    509:   route->route_option = info;
                    510:   info->id = ospf6->external_id++;
                    511: 
                    512:   /* copy result of route-map */
                    513:   if (ospf6->rmap[type].map)
                    514:     {
                    515:       if (troute.path.metric_type)
                    516:         route->path.metric_type = troute.path.metric_type;
                    517:       if (troute.path.cost)
                    518:         route->path.cost = troute.path.cost;
                    519:       if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
                    520:         memcpy (&info->forwarding, &tinfo.forwarding,
                    521:                 sizeof (struct in6_addr));
                    522:     }
                    523: 
                    524:   info->type = type;
                    525:   route->nexthop[0].ifindex = ifindex;
                    526:   if (nexthop_num && nexthop)
                    527:     memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
                    528: 
                    529:   /* create/update binding in external_id_table */
                    530:   prefix_id.family = AF_INET;
                    531:   prefix_id.prefixlen = 32;
                    532:   prefix_id.u.prefix4.s_addr = htonl (info->id);
                    533:   node = route_node_get (ospf6->external_id_table, &prefix_id);
                    534:   node->info = route;
                    535: 
                    536:   route = ospf6_route_add (route, ospf6->external_table);
                    537:   route->route_option = info;
                    538: 
                    539:   if (IS_OSPF6_DEBUG_ASBR)
                    540:     {
                    541:       inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
                    542:       zlog_debug ("Advertise as AS-External Id:%s", ibuf);
                    543:     }
                    544: 
                    545:   route->path.origin.id = htonl (info->id);
                    546:   ospf6_as_external_lsa_originate (route);
                    547: 
                    548:   /* Router-Bit (ASBR Flag) may have to be updated */
                    549:   for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
                    550:     OSPF6_ROUTER_LSA_SCHEDULE (oa);
                    551: }
                    552: 
                    553: void
                    554: ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
                    555: {
                    556:   struct ospf6_route *match;
                    557:   struct ospf6_external_info *info = NULL;
                    558:   struct route_node *node;
                    559:   struct ospf6_lsa *lsa;
                    560:   struct prefix prefix_id;
                    561:   char pbuf[64], ibuf[16];
                    562:   struct listnode *lnode, *lnnode;
                    563:   struct ospf6_area *oa;
                    564: 
                    565:   match = ospf6_route_lookup (prefix, ospf6->external_table);
                    566:   if (match == NULL)
                    567:     {
                    568:       if (IS_OSPF6_DEBUG_ASBR)
                    569:         {
                    570:           prefix2str (prefix, pbuf, sizeof (pbuf));
                    571:           zlog_debug ("No such route %s to withdraw", pbuf);
                    572:         }
                    573:       return;
                    574:     }
                    575: 
                    576:   info = match->route_option;
                    577:   assert (info);
                    578: 
                    579:   if (info->type != type)
                    580:     {
                    581:       if (IS_OSPF6_DEBUG_ASBR)
                    582:         {
                    583:           prefix2str (prefix, pbuf, sizeof (pbuf));
                    584:           zlog_debug ("Original protocol mismatch: %s", pbuf);
                    585:         }
                    586:       return;
                    587:     }
                    588: 
                    589:   if (IS_OSPF6_DEBUG_ASBR)
                    590:     {
                    591:       prefix2str (prefix, pbuf, sizeof (pbuf));
                    592:       inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
                    593:       zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
                    594:     }
                    595: 
                    596:   lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
                    597:                            htonl (info->id), ospf6->router_id, ospf6->lsdb);
                    598:   if (lsa)
                    599:     ospf6_lsa_purge (lsa);
                    600: 
                    601:   /* remove binding in external_id_table */
                    602:   prefix_id.family = AF_INET;
                    603:   prefix_id.prefixlen = 32;
                    604:   prefix_id.u.prefix4.s_addr = htonl (info->id);
                    605:   node = route_node_lookup (ospf6->external_id_table, &prefix_id);
                    606:   assert (node);
                    607:   node->info = NULL;
                    608:   route_unlock_node (node);
                    609: 
                    610:   ospf6_route_remove (match, ospf6->external_table);
                    611:   XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
                    612: 
                    613:   /* Router-Bit (ASBR Flag) may have to be updated */
                    614:   for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
                    615:     OSPF6_ROUTER_LSA_SCHEDULE (oa);
                    616: }
                    617: 
                    618: DEFUN (ospf6_redistribute,
                    619:        ospf6_redistribute_cmd,
1.1.1.2 ! misho     620:        "redistribute " QUAGGA_REDIST_STR_OSPF6D,
1.1       misho     621:        "Redistribute\n"
1.1.1.2 ! misho     622:        QUAGGA_REDIST_HELP_STR_OSPF6D
1.1       misho     623:       )
                    624: {
1.1.1.2 ! misho     625:   int type;
1.1       misho     626: 
1.1.1.2 ! misho     627:   type = proto_redistnum(AFI_IP6, argv[0]);
        !           628:   if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
        !           629:     return CMD_WARNING;
1.1       misho     630: 
                    631:   ospf6_asbr_redistribute_unset (type);
                    632:   ospf6_asbr_routemap_unset (type);
                    633:   ospf6_asbr_redistribute_set (type);
                    634:   return CMD_SUCCESS;
                    635: }
                    636: 
                    637: DEFUN (ospf6_redistribute_routemap,
                    638:        ospf6_redistribute_routemap_cmd,
1.1.1.2 ! misho     639:        "redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD",
1.1       misho     640:        "Redistribute\n"
1.1.1.2 ! misho     641:        QUAGGA_REDIST_HELP_STR_OSPF6D
1.1       misho     642:        "Route map reference\n"
                    643:        "Route map name\n"
                    644:       )
                    645: {
1.1.1.2 ! misho     646:   int type;
1.1       misho     647: 
1.1.1.2 ! misho     648:   type = proto_redistnum(AFI_IP6, argv[0]);
        !           649:   if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
        !           650:     return CMD_WARNING;
1.1       misho     651: 
                    652:   ospf6_asbr_redistribute_unset (type);
                    653:   ospf6_asbr_routemap_set (type, argv[1]);
                    654:   ospf6_asbr_redistribute_set (type);
                    655:   return CMD_SUCCESS;
                    656: }
                    657: 
                    658: DEFUN (no_ospf6_redistribute,
                    659:        no_ospf6_redistribute_cmd,
1.1.1.2 ! misho     660:        "no redistribute " QUAGGA_REDIST_STR_OSPF6D,
1.1       misho     661:        NO_STR
                    662:        "Redistribute\n"
1.1.1.2 ! misho     663:        QUAGGA_REDIST_HELP_STR_OSPF6D
1.1       misho     664:       )
                    665: {
1.1.1.2 ! misho     666:   int type;
1.1       misho     667: 
1.1.1.2 ! misho     668:   type = proto_redistnum(AFI_IP6, argv[0]);
        !           669:   if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
        !           670:     return CMD_WARNING;
1.1       misho     671: 
                    672:   ospf6_asbr_redistribute_unset (type);
                    673:   ospf6_asbr_routemap_unset (type);
                    674: 
                    675:   return CMD_SUCCESS;
                    676: }
                    677: 
                    678: int
                    679: ospf6_redistribute_config_write (struct vty *vty)
                    680: {
                    681:   int type;
                    682: 
                    683:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
                    684:     {
                    685:       if (type == ZEBRA_ROUTE_OSPF6)
                    686:         continue;
                    687:       if (! ospf6_zebra_is_redistribute (type))
                    688:         continue;
                    689: 
                    690:       if (ospf6->rmap[type].name)
                    691:         vty_out (vty, " redistribute %s route-map %s%s",
                    692:                  ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
                    693:       else
                    694:         vty_out (vty, " redistribute %s%s",
                    695:                  ZROUTE_NAME (type), VNL);
                    696:     }
                    697: 
                    698:   return 0;
                    699: }
                    700: 
                    701: static void
                    702: ospf6_redistribute_show_config (struct vty *vty)
                    703: {
                    704:   int type;
                    705:   int nroute[ZEBRA_ROUTE_MAX];
                    706:   int total;
                    707:   struct ospf6_route *route;
                    708:   struct ospf6_external_info *info;
                    709: 
                    710:   total = 0;
                    711:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
                    712:     nroute[type] = 0;
                    713:   for (route = ospf6_route_head (ospf6->external_table); route;
                    714:        route = ospf6_route_next (route))
                    715:     {
                    716:       info = route->route_option;
                    717:       nroute[info->type]++;
                    718:       total++;
                    719:     }
                    720: 
                    721:   vty_out (vty, "Redistributing External Routes from:%s", VNL);
                    722:   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
                    723:     {
                    724:       if (type == ZEBRA_ROUTE_OSPF6)
                    725:         continue;
                    726:       if (! ospf6_zebra_is_redistribute (type))
                    727:         continue;
                    728: 
                    729:       if (ospf6->rmap[type].name)
                    730:         vty_out (vty, "    %d: %s with route-map \"%s\"%s%s", nroute[type],
                    731:                  ZROUTE_NAME (type), ospf6->rmap[type].name,
                    732:                  (ospf6->rmap[type].map ? "" : " (not found !)"),
                    733:                  VNL);
                    734:       else
                    735:         vty_out (vty, "    %d: %s%s", nroute[type],
                    736:                  ZROUTE_NAME (type), VNL);
                    737:     }
                    738:   vty_out (vty, "Total %d routes%s", total, VNL);
                    739: }
                    740: 
                    741: 
                    742: 
                    743: /* Routemap Functions */
                    744: static route_map_result_t
                    745: ospf6_routemap_rule_match_address_prefixlist (void *rule,
                    746:                                               struct prefix *prefix,
                    747:                                               route_map_object_t type,
                    748:                                               void *object)
                    749: {
                    750:   struct prefix_list *plist;
                    751: 
                    752:   if (type != RMAP_OSPF6)
                    753:     return RMAP_NOMATCH;
                    754: 
                    755:   plist = prefix_list_lookup (AFI_IP6, (char *) rule);
                    756:   if (plist == NULL)
                    757:     return RMAP_NOMATCH;
                    758: 
                    759:   return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
                    760:           RMAP_NOMATCH : RMAP_MATCH);
                    761: }
                    762: 
                    763: static void *
                    764: ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
                    765: {
                    766:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    767: }
                    768: 
                    769: static void
                    770: ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
                    771: {
                    772:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    773: }
                    774: 
                    775: struct route_map_rule_cmd
                    776: ospf6_routemap_rule_match_address_prefixlist_cmd =
                    777: {
                    778:   "ipv6 address prefix-list",
                    779:   ospf6_routemap_rule_match_address_prefixlist,
                    780:   ospf6_routemap_rule_match_address_prefixlist_compile,
                    781:   ospf6_routemap_rule_match_address_prefixlist_free,
                    782: };
                    783: 
1.1.1.2 ! misho     784: /* `match interface IFNAME' */
        !           785: /* Match function should return 1 if match is success else return
        !           786:    zero. */
        !           787: static route_map_result_t
        !           788: ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix,
        !           789:                       route_map_object_t type, void *object)
        !           790: {
        !           791:   struct interface   *ifp;
        !           792:   struct ospf6_external_info *ei;
        !           793: 
        !           794:   if (type == RMAP_OSPF6)
        !           795:     {
        !           796:       ei = ((struct ospf6_route *) object)->route_option;
        !           797:       ifp = if_lookup_by_name ((char *)rule);
        !           798: 
        !           799:       if (ifp != NULL
        !           800:       &&  ei->ifindex == ifp->ifindex)
        !           801:           return RMAP_MATCH;
        !           802:     }
        !           803: 
        !           804:   return RMAP_NOMATCH;
        !           805: }
        !           806: 
        !           807: /* Route map `interface' match statement.  `arg' should be
        !           808:    interface name. */
        !           809: static void *
        !           810: ospf6_routemap_rule_match_interface_compile (const char *arg)
        !           811: {
        !           812:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
        !           813: }
        !           814: 
        !           815: /* Free route map's compiled `interface' value. */
        !           816: static void
        !           817: ospf6_routemap_rule_match_interface_free (void *rule)
        !           818: {
        !           819:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           820: }
        !           821: 
        !           822: /* Route map commands for interface matching. */
        !           823: struct route_map_rule_cmd
        !           824: ospf6_routemap_rule_match_interface_cmd =
        !           825: {
        !           826:   "interface",
        !           827:   ospf6_routemap_rule_match_interface,
        !           828:   ospf6_routemap_rule_match_interface_compile,
        !           829:   ospf6_routemap_rule_match_interface_free
        !           830: };
        !           831: 
1.1       misho     832: static route_map_result_t
                    833: ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
                    834:                                      route_map_object_t type, void *object)
                    835: {
                    836:   char *metric_type = rule;
                    837:   struct ospf6_route *route = object;
                    838: 
                    839:   if (type != RMAP_OSPF6)
                    840:     return RMAP_OKAY;
                    841: 
                    842:   if (strcmp (metric_type, "type-2") == 0)
                    843:     route->path.metric_type = 2;
                    844:   else
                    845:     route->path.metric_type = 1;
                    846: 
                    847:   return RMAP_OKAY;
                    848: }
                    849: 
                    850: static void *
                    851: ospf6_routemap_rule_set_metric_type_compile (const char *arg)
                    852: {
                    853:   if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
                    854:     return NULL;
                    855:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    856: }
                    857: 
                    858: static void
                    859: ospf6_routemap_rule_set_metric_type_free (void *rule)
                    860: {
                    861:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    862: }
                    863: 
                    864: struct route_map_rule_cmd
                    865: ospf6_routemap_rule_set_metric_type_cmd =
                    866: {
                    867:   "metric-type",
                    868:   ospf6_routemap_rule_set_metric_type,
                    869:   ospf6_routemap_rule_set_metric_type_compile,
                    870:   ospf6_routemap_rule_set_metric_type_free,
                    871: };
                    872: 
                    873: static route_map_result_t
                    874: ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
                    875:                                 route_map_object_t type, void *object)
                    876: {
                    877:   char *metric = rule;
                    878:   struct ospf6_route *route = object;
                    879: 
                    880:   if (type != RMAP_OSPF6)
                    881:     return RMAP_OKAY;
                    882: 
                    883:   route->path.cost = atoi (metric);
                    884:   return RMAP_OKAY;
                    885: }
                    886: 
                    887: static void *
                    888: ospf6_routemap_rule_set_metric_compile (const char *arg)
                    889: {
                    890:   u_int32_t metric;
                    891:   char *endp;
                    892:   metric = strtoul (arg, &endp, 0);
                    893:   if (metric > LS_INFINITY || *endp != '\0')
                    894:     return NULL;
                    895:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    896: }
                    897: 
                    898: static void
                    899: ospf6_routemap_rule_set_metric_free (void *rule)
                    900: {
                    901:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    902: }
                    903: 
                    904: struct route_map_rule_cmd
                    905: ospf6_routemap_rule_set_metric_cmd =
                    906: {
                    907:   "metric",
                    908:   ospf6_routemap_rule_set_metric,
                    909:   ospf6_routemap_rule_set_metric_compile,
                    910:   ospf6_routemap_rule_set_metric_free,
                    911: };
                    912: 
                    913: static route_map_result_t
                    914: ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
                    915:                                     route_map_object_t type, void *object)
                    916: {
                    917:   char *forwarding = rule;
                    918:   struct ospf6_route *route = object;
                    919:   struct ospf6_external_info *info = route->route_option;
                    920: 
                    921:   if (type != RMAP_OSPF6)
                    922:     return RMAP_OKAY;
                    923: 
                    924:   if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
                    925:     {
                    926:       memset (&info->forwarding, 0, sizeof (struct in6_addr));
                    927:       return RMAP_ERROR;
                    928:     }
                    929: 
                    930:   return RMAP_OKAY;
                    931: }
                    932: 
                    933: static void *
                    934: ospf6_routemap_rule_set_forwarding_compile (const char *arg)
                    935: {
                    936:   struct in6_addr a;
                    937:   if (inet_pton (AF_INET6, arg, &a) != 1)
                    938:     return NULL;
                    939:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    940: }
                    941: 
                    942: static void
                    943: ospf6_routemap_rule_set_forwarding_free (void *rule)
                    944: {
                    945:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    946: }
                    947: 
                    948: struct route_map_rule_cmd
                    949: ospf6_routemap_rule_set_forwarding_cmd =
                    950: {
                    951:   "forwarding-address",
                    952:   ospf6_routemap_rule_set_forwarding,
                    953:   ospf6_routemap_rule_set_forwarding_compile,
                    954:   ospf6_routemap_rule_set_forwarding_free,
                    955: };
                    956: 
                    957: static int
                    958: route_map_command_status (struct vty *vty, int ret)
                    959: {
                    960:   if (! ret)
                    961:     return CMD_SUCCESS;
                    962: 
                    963:   switch (ret)
                    964:     {
                    965:     case RMAP_RULE_MISSING:
                    966:       vty_out (vty, "Can't find rule.%s", VNL);
                    967:       break;
                    968:     case RMAP_COMPILE_ERROR:
                    969:       vty_out (vty, "Argument is malformed.%s", VNL);
                    970:       break;
                    971:     default:
                    972:       vty_out (vty, "route-map add set failed.%s", VNL);
                    973:       break;
                    974:     }
                    975:   return CMD_WARNING;
                    976: }
                    977: 
                    978: /* add "match address" */
                    979: DEFUN (ospf6_routemap_match_address_prefixlist,
                    980:        ospf6_routemap_match_address_prefixlist_cmd,
                    981:        "match ipv6 address prefix-list WORD",
                    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_add_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: /* delete "match address" */
                    994: DEFUN (ospf6_routemap_no_match_address_prefixlist,
                    995:        ospf6_routemap_no_match_address_prefixlist_cmd,
                    996:        "no match ipv6 address prefix-list WORD",
                    997:        NO_STR
                    998:        "Match values\n"
                    999:        IPV6_STR
                   1000:        "Match address of route\n"
                   1001:        "Match entries of prefix-lists\n"
                   1002:        "IPv6 prefix-list name\n")
                   1003: {
                   1004:   int ret = route_map_delete_match ((struct route_map_index *) vty->index,
                   1005:                                     "ipv6 address prefix-list", argv[0]);
                   1006:   return route_map_command_status (vty, ret);
                   1007: }
                   1008: 
1.1.1.2 ! misho    1009: /* "match interface" */
        !          1010: DEFUN (ospf6_routemap_match_interface,
        !          1011:        ospf6_routemap_match_interface_cmd,
        !          1012:        "match interface WORD",
        !          1013:        MATCH_STR
        !          1014:        "Match first hop interface of route\n"
        !          1015:        "Interface name\n")
        !          1016: {
        !          1017:   return route_map_add_match ((struct route_map_index *) vty->index,
        !          1018:                               "interface", argv[0]);
        !          1019: }
        !          1020: 
        !          1021: /* "no match interface WORD" */
        !          1022: DEFUN (ospf6_routemap_no_match_interface,
        !          1023:        ospf6_routemap_no_match_interface_cmd,
        !          1024:        "no match interface",
        !          1025:        MATCH_STR
        !          1026:        NO_STR
        !          1027:        "Match first hop interface of route\n")
        !          1028: {
        !          1029:   int ret = route_map_delete_match ((struct route_map_index *) vty->index,
        !          1030:                                     "interface", (argc == 0) ? NULL : argv[0]);
        !          1031:   return route_map_command_status (vty, ret);
        !          1032: }
        !          1033: 
        !          1034: ALIAS (ospf6_routemap_no_match_interface,
        !          1035:        ospf6_routemap_no_match_interface_val_cmd,
        !          1036:        "no match interface WORD",
        !          1037:        MATCH_STR
        !          1038:        NO_STR
        !          1039:        "Match first hop interface of route\n"
        !          1040:        "Interface name\n")
        !          1041: 
1.1       misho    1042: /* add "set metric-type" */
                   1043: DEFUN (ospf6_routemap_set_metric_type,
                   1044:        ospf6_routemap_set_metric_type_cmd,
                   1045:        "set metric-type (type-1|type-2)",
                   1046:        "Set value\n"
                   1047:        "Type of metric\n"
                   1048:        "OSPF6 external type 1 metric\n"
                   1049:        "OSPF6 external type 2 metric\n")
                   1050: {
                   1051:   int ret = route_map_add_set ((struct route_map_index *) vty->index,
                   1052:                                "metric-type", argv[0]);
                   1053:   return route_map_command_status (vty, ret);
                   1054: }
                   1055: 
                   1056: /* delete "set metric-type" */
                   1057: DEFUN (ospf6_routemap_no_set_metric_type,
                   1058:        ospf6_routemap_no_set_metric_type_cmd,
                   1059:        "no set metric-type (type-1|type-2)",
                   1060:        NO_STR
                   1061:        "Set value\n"
                   1062:        "Type of metric\n"
                   1063:        "OSPF6 external type 1 metric\n"
                   1064:        "OSPF6 external type 2 metric\n")
                   1065: {
                   1066:   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
                   1067:                                   "metric-type", argv[0]);
                   1068:   return route_map_command_status (vty, ret);
                   1069: }
                   1070: 
                   1071: /* add "set metric" */
                   1072: DEFUN (set_metric,
                   1073:        set_metric_cmd,
                   1074:        "set metric <0-4294967295>",
                   1075:        "Set value\n"
                   1076:        "Metric value\n"
                   1077:        "Metric value\n")
                   1078: {
                   1079:   int ret = route_map_add_set ((struct route_map_index *) vty->index,
                   1080:                                "metric", argv[0]);
                   1081:   return route_map_command_status (vty, ret);
                   1082: }
                   1083: 
                   1084: /* delete "set metric" */
                   1085: DEFUN (no_set_metric,
                   1086:        no_set_metric_cmd,
                   1087:        "no set metric <0-4294967295>",
                   1088:        NO_STR
                   1089:        "Set value\n"
                   1090:        "Metric\n"
                   1091:        "METRIC value\n")
                   1092: {
                   1093:   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
                   1094:                                   "metric", argv[0]);
                   1095:   return route_map_command_status (vty, ret);
                   1096: }
                   1097: 
                   1098: /* add "set forwarding-address" */
                   1099: DEFUN (ospf6_routemap_set_forwarding,
                   1100:        ospf6_routemap_set_forwarding_cmd,
                   1101:        "set forwarding-address X:X::X:X",
                   1102:        "Set value\n"
                   1103:        "Forwarding Address\n"
                   1104:        "IPv6 Address\n")
                   1105: {
                   1106:   int ret = route_map_add_set ((struct route_map_index *) vty->index,
                   1107:                                "forwarding-address", argv[0]);
                   1108:   return route_map_command_status (vty, ret);
                   1109: }
                   1110: 
                   1111: /* delete "set forwarding-address" */
                   1112: DEFUN (ospf6_routemap_no_set_forwarding,
                   1113:        ospf6_routemap_no_set_forwarding_cmd,
                   1114:        "no set forwarding-address X:X::X:X",
                   1115:        NO_STR
                   1116:        "Set value\n"
                   1117:        "Forwarding Address\n"
                   1118:        "IPv6 Address\n")
                   1119: {
                   1120:   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
                   1121:                                   "forwarding-address", argv[0]);
                   1122:   return route_map_command_status (vty, ret);
                   1123: }
                   1124: 
                   1125: static void
                   1126: ospf6_routemap_init (void)
                   1127: {
                   1128:   route_map_init ();
                   1129:   route_map_init_vty ();
                   1130:   route_map_add_hook (ospf6_asbr_routemap_update);
                   1131:   route_map_delete_hook (ospf6_asbr_routemap_update);
                   1132: 
                   1133:   route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1.1.1.2 ! misho    1134:   route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
        !          1135: 
1.1       misho    1136:   route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
                   1137:   route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
                   1138:   route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
                   1139: 
                   1140:   /* Match address prefix-list */
                   1141:   install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
                   1142:   install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
                   1143: 
1.1.1.2 ! misho    1144:   /* Match interface */
        !          1145:   install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd);
        !          1146:   install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd);
        !          1147:   install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd);
        !          1148: 
1.1       misho    1149:   /* ASE Metric Type (e.g. Type-1/Type-2) */
                   1150:   install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
                   1151:   install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
                   1152: 
                   1153:   /* ASE Metric */
                   1154:   install_element (RMAP_NODE, &set_metric_cmd);
                   1155:   install_element (RMAP_NODE, &no_set_metric_cmd);
                   1156: 
                   1157:   /* ASE Metric */
                   1158:   install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
                   1159:   install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
                   1160: }
                   1161: 
                   1162: 
                   1163: /* Display functions */
                   1164: static int
                   1165: ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
                   1166: {
                   1167:   struct ospf6_as_external_lsa *external;
                   1168:   char buf[64];
                   1169:   struct in6_addr in6, *forwarding;
                   1170: 
                   1171:   assert (lsa->header);
                   1172:   external = (struct ospf6_as_external_lsa *)
                   1173:     OSPF6_LSA_HEADER_END (lsa->header);
                   1174:   
                   1175:   /* bits */
                   1176:   snprintf (buf, sizeof (buf), "%c%c%c",
                   1177:     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
                   1178:     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
                   1179:     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
                   1180: 
                   1181:   vty_out (vty, "     Bits: %s%s", buf, VNL);
                   1182:   vty_out (vty, "     Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
                   1183:            VNL);
                   1184: 
                   1185:   ospf6_prefix_options_printbuf (external->prefix.prefix_options,
                   1186:                                  buf, sizeof (buf));
                   1187:   vty_out (vty, "     Prefix Options: %s%s", buf,
                   1188:            VNL);
                   1189: 
                   1190:   vty_out (vty, "     Referenced LSType: %d%s",
                   1191:            ntohs (external->prefix.prefix_refer_lstype),
                   1192:            VNL);
                   1193: 
                   1194:   ospf6_prefix_in6_addr (&in6, &external->prefix);
                   1195:   inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
                   1196:   vty_out (vty, "     Prefix: %s/%d%s", buf,
                   1197:            external->prefix.prefix_length, VNL);
                   1198: 
                   1199:   /* Forwarding-Address */
                   1200:   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
                   1201:     {
                   1202:       forwarding = (struct in6_addr *)
                   1203:         ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
                   1204:          OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
                   1205:       inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
                   1206:       vty_out (vty, "     Forwarding-Address: %s%s", buf, VNL);
                   1207:     }
                   1208: 
                   1209:   return 0;
                   1210: }
                   1211: 
                   1212: static void
                   1213: ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
                   1214: {
                   1215:   struct ospf6_external_info *info = route->route_option;
                   1216:   char prefix[64], id[16], forwarding[64];
                   1217:   u_int32_t tmp_id;
                   1218: 
                   1219:   prefix2str (&route->prefix, prefix, sizeof (prefix));
                   1220:   tmp_id = ntohl (info->id);
                   1221:   inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
                   1222:   if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
                   1223:     inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
                   1224:   else
                   1225:     snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
                   1226:               route->nexthop[0].ifindex);
                   1227: 
                   1228:   vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
                   1229:            zebra_route_char(info->type),
                   1230:            prefix, id, route->path.metric_type,
                   1231:            (u_long) (route->path.metric_type == 2 ?
                   1232:                      route->path.cost_e2 : route->path.cost),
                   1233:            forwarding, VNL);
                   1234: }
                   1235: 
                   1236: DEFUN (show_ipv6_ospf6_redistribute,
                   1237:        show_ipv6_ospf6_redistribute_cmd,
                   1238:        "show ipv6 ospf6 redistribute",
                   1239:        SHOW_STR
                   1240:        IP6_STR
                   1241:        OSPF6_STR
                   1242:        "redistributing External information\n"
                   1243:        )
                   1244: {
                   1245:   struct ospf6_route *route;
                   1246: 
                   1247:   ospf6_redistribute_show_config (vty);
                   1248: 
                   1249:   for (route = ospf6_route_head (ospf6->external_table); route;
                   1250:        route = ospf6_route_next (route))
                   1251:     ospf6_asbr_external_route_show (vty, route);
                   1252: 
                   1253:   return CMD_SUCCESS;
                   1254: }
                   1255: 
                   1256: struct ospf6_lsa_handler as_external_handler =
                   1257: {
                   1258:   OSPF6_LSTYPE_AS_EXTERNAL,
                   1259:   "AS-External",
                   1260:   ospf6_as_external_lsa_show
                   1261: };
                   1262: 
                   1263: void
                   1264: ospf6_asbr_init (void)
                   1265: {
                   1266:   ospf6_routemap_init ();
                   1267: 
                   1268:   ospf6_install_lsa_handler (&as_external_handler);
                   1269: 
                   1270:   install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
                   1271:   install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
                   1272: 
                   1273:   install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
                   1274:   install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
                   1275:   install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
                   1276: }
                   1277: 
                   1278: void
                   1279: ospf6_asbr_terminate (void)
                   1280: {
                   1281:   route_map_finish ();
                   1282: }
                   1283: 
                   1284: DEFUN (debug_ospf6_asbr,
                   1285:        debug_ospf6_asbr_cmd,
                   1286:        "debug ospf6 asbr",
                   1287:        DEBUG_STR
                   1288:        OSPF6_STR
                   1289:        "Debug OSPFv3 ASBR function\n"
                   1290:       )
                   1291: {
                   1292:   OSPF6_DEBUG_ASBR_ON ();
                   1293:   return CMD_SUCCESS;
                   1294: }
                   1295: 
                   1296: DEFUN (no_debug_ospf6_asbr,
                   1297:        no_debug_ospf6_asbr_cmd,
                   1298:        "no debug ospf6 asbr",
                   1299:        NO_STR
                   1300:        DEBUG_STR
                   1301:        OSPF6_STR
                   1302:        "Debug OSPFv3 ASBR function\n"
                   1303:       )
                   1304: {
                   1305:   OSPF6_DEBUG_ASBR_OFF ();
                   1306:   return CMD_SUCCESS;
                   1307: }
                   1308: 
                   1309: int
                   1310: config_write_ospf6_debug_asbr (struct vty *vty)
                   1311: {
                   1312:   if (IS_OSPF6_DEBUG_ASBR)
                   1313:     vty_out (vty, "debug ospf6 asbr%s", VNL);
                   1314:   return 0;
                   1315: }
                   1316: 
                   1317: void
                   1318: install_element_ospf6_debug_asbr ()
                   1319: {
                   1320:   install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
                   1321:   install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
                   1322:   install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
                   1323:   install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
                   1324: }
                   1325: 
                   1326: 

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