Annotation of embedaddon/quagga/ripngd/ripng_routemap.c, revision 1.1

1.1     ! misho       1: /* RIPng routemap.
        !             2:  * Copyright (C) 1999 Kunihiro Ishiguro
        !             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 Free
        !            18:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
        !            19:  * 02111-1307, USA.  
        !            20:  */
        !            21: 
        !            22: #include <zebra.h>
        !            23: 
        !            24: #include "if.h"
        !            25: #include "memory.h"
        !            26: #include "prefix.h"
        !            27: #include "routemap.h"
        !            28: #include "command.h"
        !            29: #include "sockunion.h"
        !            30: 
        !            31: #include "ripngd/ripngd.h"
        !            32: 
        !            33: struct rip_metric_modifier
        !            34: {
        !            35:   enum 
        !            36:   {
        !            37:     metric_increment,
        !            38:     metric_decrement,
        !            39:     metric_absolute
        !            40:   } type;
        !            41: 
        !            42:   u_char metric;
        !            43: };
        !            44: 
        !            45: 
        !            46: static int
        !            47: ripng_route_match_add (struct vty *vty, struct route_map_index *index,
        !            48:                       const char *command, const char *arg)
        !            49: {
        !            50:   int ret;
        !            51: 
        !            52:   ret = route_map_add_match (index, command, arg);
        !            53:   if (ret)
        !            54:     {
        !            55:       switch (ret)
        !            56:        {
        !            57:        case RMAP_RULE_MISSING:
        !            58:          vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
        !            59:          return CMD_WARNING;
        !            60:        case RMAP_COMPILE_ERROR:
        !            61:          vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
        !            62:          return CMD_WARNING;
        !            63:        }
        !            64:     }
        !            65:   return CMD_SUCCESS;
        !            66: }
        !            67: 
        !            68: static int
        !            69: ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
        !            70:                          const char *command, const char *arg)
        !            71: {
        !            72:   int ret;
        !            73: 
        !            74:   ret = route_map_delete_match (index, command, arg);
        !            75:   if (ret)
        !            76:     {
        !            77:       switch (ret)
        !            78:        {
        !            79:        case RMAP_RULE_MISSING:
        !            80:          vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
        !            81:          return CMD_WARNING;
        !            82:        case RMAP_COMPILE_ERROR:
        !            83:          vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
        !            84:          return CMD_WARNING;
        !            85:        }
        !            86:     }
        !            87:   return CMD_SUCCESS;
        !            88: }
        !            89: 
        !            90: static int
        !            91: ripng_route_set_add (struct vty *vty, struct route_map_index *index,
        !            92:                     const char *command, const char *arg)
        !            93: {
        !            94:   int ret;
        !            95: 
        !            96:   ret = route_map_add_set (index, command, arg);
        !            97:   if (ret)
        !            98:     {
        !            99:       switch (ret)
        !           100:        {
        !           101:        case RMAP_RULE_MISSING:
        !           102:          vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
        !           103:          return CMD_WARNING;
        !           104:        case RMAP_COMPILE_ERROR:
        !           105:          vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
        !           106:          return CMD_WARNING;
        !           107:        }
        !           108:     }
        !           109:   return CMD_SUCCESS;
        !           110: }
        !           111: 
        !           112: static int
        !           113: ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
        !           114:                        const char *command, const char *arg)
        !           115: {
        !           116:   int ret;
        !           117: 
        !           118:   ret = route_map_delete_set (index, command, arg);
        !           119:   if (ret)
        !           120:     {
        !           121:       switch (ret)
        !           122:        {
        !           123:        case RMAP_RULE_MISSING:
        !           124:          vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
        !           125:          return CMD_WARNING;
        !           126:        case RMAP_COMPILE_ERROR:
        !           127:          vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
        !           128:          return CMD_WARNING;
        !           129:        }
        !           130:     }
        !           131:   return CMD_SUCCESS;
        !           132: }
        !           133: 
        !           134: /* `match metric METRIC' */
        !           135: /* Match function return 1 if match is success else return zero. */
        !           136: static route_map_result_t
        !           137: route_match_metric (void *rule, struct prefix *prefix, 
        !           138:                    route_map_object_t type, void *object)
        !           139: {
        !           140:   u_int32_t *metric;
        !           141:   struct ripng_info *rinfo;
        !           142: 
        !           143:   if (type == RMAP_RIPNG)
        !           144:     {
        !           145:       metric = rule;
        !           146:       rinfo = object;
        !           147:     
        !           148:       if (rinfo->metric == *metric)
        !           149:        return RMAP_MATCH;
        !           150:       else
        !           151:        return RMAP_NOMATCH;
        !           152:     }
        !           153:   return RMAP_NOMATCH;
        !           154: }
        !           155: 
        !           156: /* Route map `match metric' match statement. `arg' is METRIC value */
        !           157: static void *
        !           158: route_match_metric_compile (const char *arg)
        !           159: {
        !           160:   u_int32_t *metric;
        !           161: 
        !           162:   metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
        !           163:   *metric = atoi (arg);
        !           164: 
        !           165:   if(*metric > 0)
        !           166:     return metric;
        !           167: 
        !           168:   XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
        !           169:   return NULL;
        !           170: }
        !           171: 
        !           172: /* Free route map's compiled `match metric' value. */
        !           173: static void
        !           174: route_match_metric_free (void *rule)
        !           175: {
        !           176:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           177: }
        !           178: 
        !           179: /* Route map commands for metric matching. */
        !           180: static struct route_map_rule_cmd route_match_metric_cmd =
        !           181: {
        !           182:   "metric",
        !           183:   route_match_metric,
        !           184:   route_match_metric_compile,
        !           185:   route_match_metric_free
        !           186: };
        !           187: 
        !           188: /* `match interface IFNAME' */
        !           189: /* Match function return 1 if match is success else return zero. */
        !           190: static route_map_result_t
        !           191: route_match_interface (void *rule, struct prefix *prefix,
        !           192:                       route_map_object_t type, void *object)
        !           193: {
        !           194:   struct ripng_info *rinfo;
        !           195:   struct interface *ifp;
        !           196:   char *ifname;
        !           197: 
        !           198:   if (type == RMAP_RIPNG)
        !           199:     {
        !           200:       ifname = rule;
        !           201:       ifp = if_lookup_by_name(ifname);
        !           202: 
        !           203:       if (!ifp)
        !           204:        return RMAP_NOMATCH;
        !           205: 
        !           206:       rinfo = object;
        !           207: 
        !           208:       if (rinfo->ifindex == ifp->ifindex)
        !           209:        return RMAP_MATCH;
        !           210:       else
        !           211:        return RMAP_NOMATCH;
        !           212:     }
        !           213:   return RMAP_NOMATCH;
        !           214: }
        !           215: 
        !           216: /* Route map `match interface' match statement. `arg' is IFNAME value */
        !           217: static void *
        !           218: route_match_interface_compile (const char *arg)
        !           219: {
        !           220:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
        !           221: }
        !           222: 
        !           223: static void
        !           224: route_match_interface_free (void *rule)
        !           225: {
        !           226:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           227: }
        !           228: 
        !           229: static struct route_map_rule_cmd route_match_interface_cmd =
        !           230: {
        !           231:   "interface",
        !           232:   route_match_interface,
        !           233:   route_match_interface_compile,
        !           234:   route_match_interface_free
        !           235: };
        !           236: 
        !           237: /* `match tag TAG' */
        !           238: /* Match function return 1 if match is success else return zero. */
        !           239: static route_map_result_t
        !           240: route_match_tag (void *rule, struct prefix *prefix, 
        !           241:                    route_map_object_t type, void *object)
        !           242: {
        !           243:   u_short *tag;
        !           244:   struct ripng_info *rinfo;
        !           245: 
        !           246:   if (type == RMAP_RIPNG)
        !           247:     {
        !           248:       tag = rule;
        !           249:       rinfo = object;
        !           250: 
        !           251:       /* The information stored by rinfo is host ordered. */
        !           252:       if (rinfo->tag == *tag)
        !           253:        return RMAP_MATCH;
        !           254:       else
        !           255:        return RMAP_NOMATCH;
        !           256:     }
        !           257:   return RMAP_NOMATCH;
        !           258: }
        !           259: 
        !           260: /* Route map `match tag' match statement. `arg' is TAG value */
        !           261: static void *
        !           262: route_match_tag_compile (const char *arg)
        !           263: {
        !           264:   u_short *tag;
        !           265: 
        !           266:   tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
        !           267:   *tag = atoi (arg);
        !           268: 
        !           269:   return tag;
        !           270: }
        !           271: 
        !           272: /* Free route map's compiled `match tag' value. */
        !           273: static void
        !           274: route_match_tag_free (void *rule)
        !           275: {
        !           276:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           277: }
        !           278: 
        !           279: /* Route map commands for tag matching. */
        !           280: static struct route_map_rule_cmd route_match_tag_cmd =
        !           281: {
        !           282:   "tag",
        !           283:   route_match_tag,
        !           284:   route_match_tag_compile,
        !           285:   route_match_tag_free
        !           286: };
        !           287: 
        !           288: /* `set metric METRIC' */
        !           289: 
        !           290: /* Set metric to attribute. */
        !           291: static route_map_result_t
        !           292: route_set_metric (void *rule, struct prefix *prefix, 
        !           293:                  route_map_object_t type, void *object)
        !           294: {
        !           295:   if (type == RMAP_RIPNG)
        !           296:     {
        !           297:       struct rip_metric_modifier *mod;
        !           298:       struct ripng_info *rinfo;
        !           299: 
        !           300:       mod = rule;
        !           301:       rinfo = object;
        !           302: 
        !           303:       if (mod->type == metric_increment)
        !           304:        rinfo->metric_out += mod->metric;
        !           305:       else if (mod->type == metric_decrement)
        !           306:        rinfo->metric_out-= mod->metric;
        !           307:       else if (mod->type == metric_absolute)
        !           308:        rinfo->metric_out = mod->metric;
        !           309: 
        !           310:       if (rinfo->metric_out < 1)
        !           311:        rinfo->metric_out = 1;
        !           312:       if (rinfo->metric_out > RIPNG_METRIC_INFINITY)
        !           313:        rinfo->metric_out = RIPNG_METRIC_INFINITY;
        !           314: 
        !           315:       rinfo->metric_set = 1;
        !           316:     }
        !           317:   return RMAP_OKAY;
        !           318: }
        !           319: 
        !           320: /* set metric compilation. */
        !           321: static void *
        !           322: route_set_metric_compile (const char *arg)
        !           323: {
        !           324:   int len;
        !           325:   const char *pnt;
        !           326:   int type;
        !           327:   long metric;
        !           328:   char *endptr = NULL;
        !           329:   struct rip_metric_modifier *mod;
        !           330: 
        !           331:   len = strlen (arg);
        !           332:   pnt = arg;
        !           333: 
        !           334:   if (len == 0)
        !           335:     return NULL;
        !           336: 
        !           337:   /* Examine first character. */
        !           338:   if (arg[0] == '+')
        !           339:     {
        !           340:       type = metric_increment;
        !           341:       pnt++;
        !           342:     }
        !           343:   else if (arg[0] == '-')
        !           344:     {
        !           345:       type = metric_decrement;
        !           346:       pnt++;
        !           347:     }
        !           348:   else
        !           349:     type = metric_absolute;
        !           350: 
        !           351:   /* Check beginning with digit string. */
        !           352:   if (*pnt < '0' || *pnt > '9')
        !           353:     return NULL;
        !           354: 
        !           355:   /* Convert string to integer. */
        !           356:   metric = strtol (pnt, &endptr, 10);
        !           357: 
        !           358:   if (metric == LONG_MAX || *endptr != '\0')
        !           359:     return NULL;
        !           360:   /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
        !           361:   /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
        !           362:   if (metric < 0)
        !           363:     return NULL;
        !           364: 
        !           365:   mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, 
        !           366:                 sizeof (struct rip_metric_modifier));
        !           367:   mod->type = type;
        !           368:   mod->metric = metric;
        !           369: 
        !           370:   return mod;
        !           371: }
        !           372: 
        !           373: /* Free route map's compiled `set metric' value. */
        !           374: static void
        !           375: route_set_metric_free (void *rule)
        !           376: {
        !           377:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           378: }
        !           379: 
        !           380: static struct route_map_rule_cmd route_set_metric_cmd = 
        !           381: {
        !           382:   "metric",
        !           383:   route_set_metric,
        !           384:   route_set_metric_compile,
        !           385:   route_set_metric_free,
        !           386: };
        !           387: 
        !           388: /* `set ipv6 next-hop local IP_ADDRESS' */
        !           389: 
        !           390: /* Set nexthop to object.  ojbect must be pointer to struct attr. */
        !           391: static route_map_result_t
        !           392: route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
        !           393:                      route_map_object_t type, void *object)
        !           394: {
        !           395:   struct in6_addr *address;
        !           396:   struct ripng_info *rinfo;
        !           397: 
        !           398:   if(type == RMAP_RIPNG)
        !           399:     {
        !           400:       /* Fetch routemap's rule information. */
        !           401:       address = rule;
        !           402:       rinfo = object;
        !           403:     
        !           404:       /* Set next hop value. */ 
        !           405:       rinfo->nexthop_out = *address;
        !           406:     }
        !           407: 
        !           408:   return RMAP_OKAY;
        !           409: }
        !           410: 
        !           411: /* Route map `ipv6 nexthop local' compile function.  Given string is converted
        !           412:    to struct in6_addr structure. */
        !           413: static void *
        !           414: route_set_ipv6_nexthop_local_compile (const char *arg)
        !           415: {
        !           416:   int ret;
        !           417:   struct in6_addr *address;
        !           418: 
        !           419:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
        !           420: 
        !           421:   ret = inet_pton (AF_INET6, arg, address);
        !           422: 
        !           423:   if (ret == 0)
        !           424:     {
        !           425:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
        !           426:       return NULL;
        !           427:     }
        !           428: 
        !           429:   return address;
        !           430: }
        !           431: 
        !           432: /* Free route map's compiled `ipv6 nexthop local' value. */
        !           433: static void
        !           434: route_set_ipv6_nexthop_local_free (void *rule)
        !           435: {
        !           436:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           437: }
        !           438: 
        !           439: /* Route map commands for ipv6 nexthop local set. */
        !           440: static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
        !           441: {
        !           442:   "ipv6 next-hop local",
        !           443:   route_set_ipv6_nexthop_local,
        !           444:   route_set_ipv6_nexthop_local_compile,
        !           445:   route_set_ipv6_nexthop_local_free
        !           446: };
        !           447: 
        !           448: /* `set tag TAG' */
        !           449: 
        !           450: /* Set tag to object.  ojbect must be pointer to struct attr. */
        !           451: static route_map_result_t
        !           452: route_set_tag (void *rule, struct prefix *prefix, 
        !           453:                      route_map_object_t type, void *object)
        !           454: {
        !           455:   u_short *tag;
        !           456:   struct ripng_info *rinfo;
        !           457: 
        !           458:   if(type == RMAP_RIPNG)
        !           459:     {
        !           460:       /* Fetch routemap's rule information. */
        !           461:       tag = rule;
        !           462:       rinfo = object;
        !           463:     
        !           464:       /* Set next hop value. */ 
        !           465:       rinfo->tag_out = *tag;
        !           466:     }
        !           467: 
        !           468:   return RMAP_OKAY;
        !           469: }
        !           470: 
        !           471: /* Route map `tag' compile function.  Given string is converted
        !           472:    to u_short. */
        !           473: static void *
        !           474: route_set_tag_compile (const char *arg)
        !           475: {
        !           476:   u_short *tag;
        !           477: 
        !           478:   tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
        !           479:   *tag = atoi (arg);
        !           480: 
        !           481:   return tag;
        !           482: }
        !           483: 
        !           484: /* Free route map's compiled `ip nexthop' value. */
        !           485: static void
        !           486: route_set_tag_free (void *rule)
        !           487: {
        !           488:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           489: }
        !           490: 
        !           491: /* Route map commands for tag set. */
        !           492: static struct route_map_rule_cmd route_set_tag_cmd =
        !           493: {
        !           494:   "tag",
        !           495:   route_set_tag,
        !           496:   route_set_tag_compile,
        !           497:   route_set_tag_free
        !           498: };
        !           499: 
        !           500: #define MATCH_STR "Match values from routing table\n"
        !           501: #define SET_STR "Set values in destination routing protocol\n"
        !           502: 
        !           503: DEFUN (match_metric, 
        !           504:        match_metric_cmd,
        !           505:        "match metric <0-4294967295>",
        !           506:        MATCH_STR
        !           507:        "Match metric of route\n"
        !           508:        "Metric value\n")
        !           509: {
        !           510:   return ripng_route_match_add (vty, vty->index, "metric", argv[0]);
        !           511: }
        !           512: 
        !           513: DEFUN (no_match_metric,
        !           514:        no_match_metric_cmd,
        !           515:        "no match metric",
        !           516:        NO_STR
        !           517:        MATCH_STR
        !           518:        "Match metric of route\n")
        !           519: {
        !           520:   if (argc == 0)
        !           521:     return ripng_route_match_delete (vty, vty->index, "metric", NULL);
        !           522: 
        !           523:   return ripng_route_match_delete (vty, vty->index, "metric", argv[0]);
        !           524: }
        !           525: 
        !           526: ALIAS (no_match_metric,
        !           527:        no_match_metric_val_cmd,
        !           528:        "no match metric <0-4294967295>",
        !           529:        NO_STR
        !           530:        MATCH_STR
        !           531:        "Match metric of route\n"
        !           532:        "Metric value\n")
        !           533: 
        !           534: DEFUN (match_interface,
        !           535:        match_interface_cmd,
        !           536:        "match interface WORD",
        !           537:        MATCH_STR
        !           538:        "Match first hop interface of route\n"
        !           539:        "Interface name\n")
        !           540: {
        !           541:   return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
        !           542: }
        !           543: 
        !           544: DEFUN (no_match_interface,
        !           545:        no_match_interface_cmd,
        !           546:        "no match interface",
        !           547:        NO_STR
        !           548:        MATCH_STR
        !           549:        "Match first hop interface of route\n")
        !           550: {
        !           551:   if (argc == 0)
        !           552:     return ripng_route_match_delete (vty, vty->index, "interface", NULL);
        !           553: 
        !           554:   return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
        !           555: }
        !           556: 
        !           557: ALIAS (no_match_interface,
        !           558:        no_match_interface_val_cmd,
        !           559:        "no match interface WORD",
        !           560:        NO_STR
        !           561:        MATCH_STR
        !           562:        "Match first hop interface of route\n"
        !           563:        "Interface name\n")
        !           564: 
        !           565: DEFUN (match_tag,
        !           566:        match_tag_cmd,
        !           567:        "match tag <0-65535>",
        !           568:        MATCH_STR
        !           569:        "Match tag of route\n"
        !           570:        "Metric value\n")
        !           571: {
        !           572:   return ripng_route_match_add (vty, vty->index, "tag", argv[0]);
        !           573: }
        !           574: 
        !           575: DEFUN (no_match_tag,
        !           576:        no_match_tag_cmd,
        !           577:        "no match tag",
        !           578:        NO_STR
        !           579:        MATCH_STR
        !           580:        "Match tag of route\n")
        !           581: {
        !           582:   if (argc == 0)
        !           583:     return ripng_route_match_delete (vty, vty->index, "tag", NULL);
        !           584: 
        !           585:   return ripng_route_match_delete (vty, vty->index, "tag", argv[0]);
        !           586: }
        !           587: 
        !           588: ALIAS (no_match_tag,
        !           589:        no_match_tag_val_cmd,
        !           590:        "no match tag <0-65535>",
        !           591:        NO_STR
        !           592:        MATCH_STR
        !           593:        "Match tag of route\n"
        !           594:        "Metric value\n")
        !           595: 
        !           596: /* set functions */
        !           597: 
        !           598: DEFUN (set_metric,
        !           599:        set_metric_cmd,
        !           600:        "set metric <0-4294967295>",
        !           601:        "Set value\n"
        !           602:        "Metric value for destination routing protocol\n"
        !           603:        "Metric value\n")
        !           604: {
        !           605:   return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
        !           606: }
        !           607: 
        !           608: DEFUN (no_set_metric,
        !           609:        no_set_metric_cmd,
        !           610:        "no set metric",
        !           611:        NO_STR
        !           612:        SET_STR
        !           613:        "Metric value for destination routing protocol\n")
        !           614: {
        !           615:   if (argc == 0)
        !           616:     return ripng_route_set_delete (vty, vty->index, "metric", NULL);
        !           617: 
        !           618:   return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
        !           619: }
        !           620: 
        !           621: ALIAS (no_set_metric,
        !           622:        no_set_metric_val_cmd,
        !           623:        "no set metric <0-4294967295>",
        !           624:        NO_STR
        !           625:        SET_STR
        !           626:        "Metric value for destination routing protocol\n"
        !           627:        "Metric value\n")
        !           628: 
        !           629: DEFUN (set_ipv6_nexthop_local,
        !           630:        set_ipv6_nexthop_local_cmd,
        !           631:        "set ipv6 next-hop local X:X::X:X",
        !           632:        SET_STR
        !           633:        IPV6_STR
        !           634:        "IPv6 next-hop address\n"
        !           635:        "IPv6 local address\n"
        !           636:        "IPv6 address of next hop\n")
        !           637: {
        !           638:   union sockunion su;
        !           639:   int ret;
        !           640: 
        !           641:   ret = str2sockunion (argv[0], &su);
        !           642:   if (ret < 0)
        !           643:     {
        !           644:       vty_out (vty, "%% Malformed next-hop local address%s", VTY_NEWLINE);
        !           645:       return CMD_WARNING;
        !           646:     }
        !           647: 
        !           648:   return ripng_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
        !           649: }
        !           650: 
        !           651: DEFUN (no_set_ipv6_nexthop_local,
        !           652:        no_set_ipv6_nexthop_local_cmd,
        !           653:        "no set ipv6 next-hop local",
        !           654:        NO_STR
        !           655:        SET_STR
        !           656:        IPV6_STR
        !           657:        "IPv6 next-hop address\n"
        !           658:        "IPv6 local address\n")
        !           659: {
        !           660:   if (argc == 0)
        !           661:     return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
        !           662: 
        !           663:   return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
        !           664: }
        !           665: 
        !           666: ALIAS (no_set_ipv6_nexthop_local,
        !           667:        no_set_ipv6_nexthop_local_val_cmd,
        !           668:        "no set ipv6 next-hop local X:X::X:X",
        !           669:        NO_STR
        !           670:        SET_STR
        !           671:        IPV6_STR
        !           672:        "IPv6 next-hop address\n"
        !           673:        "IPv6 local address\n"
        !           674:        "IPv6 address of next hop\n")
        !           675: 
        !           676: DEFUN (set_tag,
        !           677:        set_tag_cmd,
        !           678:        "set tag <0-65535>",
        !           679:        SET_STR
        !           680:        "Tag value for routing protocol\n"
        !           681:        "Tag value\n")
        !           682: {
        !           683:   return ripng_route_set_add (vty, vty->index, "tag", argv[0]);
        !           684: }
        !           685: 
        !           686: DEFUN (no_set_tag,
        !           687:        no_set_tag_cmd,
        !           688:        "no set tag",
        !           689:        NO_STR
        !           690:        SET_STR
        !           691:        "Tag value for routing protocol\n")
        !           692: {
        !           693:   if (argc == 0)
        !           694:     return ripng_route_set_delete (vty, vty->index, "tag", NULL);
        !           695: 
        !           696:   return ripng_route_set_delete (vty, vty->index, "tag", argv[0]);
        !           697: }
        !           698: 
        !           699: ALIAS (no_set_tag,
        !           700:        no_set_tag_val_cmd,
        !           701:        "no set tag <0-65535>",
        !           702:        NO_STR
        !           703:        SET_STR
        !           704:        "Tag value for routing protocol\n"
        !           705:        "Tag value\n")
        !           706: 
        !           707: void
        !           708: ripng_route_map_reset ()
        !           709: {
        !           710:   /* XXX ??? */
        !           711:   ;
        !           712: }
        !           713: 
        !           714: void
        !           715: ripng_route_map_init ()
        !           716: {
        !           717:   route_map_init ();
        !           718:   route_map_init_vty ();
        !           719: 
        !           720:   route_map_install_match (&route_match_metric_cmd);
        !           721:   route_map_install_match (&route_match_interface_cmd);
        !           722:   route_map_install_match (&route_match_tag_cmd);
        !           723: 
        !           724:   route_map_install_set (&route_set_metric_cmd);
        !           725:   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
        !           726:   route_map_install_set (&route_set_tag_cmd);
        !           727: 
        !           728:   install_element (RMAP_NODE, &match_metric_cmd);
        !           729:   install_element (RMAP_NODE, &no_match_metric_cmd);
        !           730:   install_element (RMAP_NODE, &no_match_metric_val_cmd);
        !           731:   install_element (RMAP_NODE, &match_interface_cmd);
        !           732:   install_element (RMAP_NODE, &no_match_interface_cmd);
        !           733:   install_element (RMAP_NODE, &no_match_interface_val_cmd);
        !           734:   install_element (RMAP_NODE, &match_tag_cmd);
        !           735:   install_element (RMAP_NODE, &no_match_tag_cmd);
        !           736:   install_element (RMAP_NODE, &no_match_tag_val_cmd);
        !           737: 
        !           738:   install_element (RMAP_NODE, &set_metric_cmd);
        !           739:   install_element (RMAP_NODE, &no_set_metric_cmd);
        !           740:   install_element (RMAP_NODE, &no_set_metric_val_cmd);
        !           741:   install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
        !           742:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
        !           743:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
        !           744:   install_element (RMAP_NODE, &set_tag_cmd);
        !           745:   install_element (RMAP_NODE, &no_set_tag_cmd);
        !           746:   install_element (RMAP_NODE, &no_set_tag_val_cmd);
        !           747: }

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