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

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

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