Annotation of embedaddon/quagga/bgpd/bgp_routemap.c, revision 1.1.1.4

1.1       misho       1: /* Route map function of bgpd.
                      2:    Copyright (C) 1998, 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: #include <zebra.h>
                     22: 
                     23: #include "prefix.h"
                     24: #include "filter.h"
                     25: #include "routemap.h"
                     26: #include "command.h"
                     27: #include "linklist.h"
                     28: #include "plist.h"
                     29: #include "memory.h"
                     30: #include "log.h"
                     31: #ifdef HAVE_LIBPCREPOSIX
                     32: # include <pcreposix.h>
                     33: #else
                     34: # ifdef HAVE_GNU_REGEX
                     35: #  include <regex.h>
                     36: # else
                     37: #  include "regex-gnu.h"
                     38: # endif /* HAVE_GNU_REGEX */
                     39: #endif /* HAVE_LIBPCREPOSIX */
                     40: #include "buffer.h"
                     41: #include "sockunion.h"
                     42: 
                     43: #include "bgpd/bgpd.h"
                     44: #include "bgpd/bgp_table.h"
                     45: #include "bgpd/bgp_attr.h"
                     46: #include "bgpd/bgp_aspath.h"
                     47: #include "bgpd/bgp_route.h"
                     48: #include "bgpd/bgp_regex.h"
                     49: #include "bgpd/bgp_community.h"
                     50: #include "bgpd/bgp_clist.h"
                     51: #include "bgpd/bgp_filter.h"
                     52: #include "bgpd/bgp_mplsvpn.h"
                     53: #include "bgpd/bgp_ecommunity.h"
                     54: #include "bgpd/bgp_vty.h"
                     55: 
                     56: /* Memo of route-map commands.
                     57: 
                     58: o Cisco route-map
                     59: 
                     60:  match as-path          :  Done
                     61:        community        :  Done
                     62:        interface        :  Not yet
                     63:        ip address       :  Done
                     64:        ip next-hop      :  Done
                     65:        ip route-source  :  Done
                     66:        ip prefix-list   :  Done
                     67:        ipv6 address     :  Done
                     68:        ipv6 next-hop    :  Done
                     69:        ipv6 route-source:  (This will not be implemented by bgpd)
                     70:        ipv6 prefix-list :  Done
                     71:        length           :  (This will not be implemented by bgpd)
                     72:        metric           :  Done
                     73:        route-type       :  (This will not be implemented by bgpd)
                     74:        tag              :  (This will not be implemented by bgpd)
                     75: 
                     76:  set  as-path prepend   :  Done
                     77:       as-path tag       :  Not yet
                     78:       automatic-tag     :  (This will not be implemented by bgpd)
                     79:       community         :  Done
                     80:       comm-list         :  Not yet
                     81:       dampning          :  Not yet
                     82:       default           :  (This will not be implemented by bgpd)
                     83:       interface         :  (This will not be implemented by bgpd)
                     84:       ip default        :  (This will not be implemented by bgpd)
                     85:       ip next-hop       :  Done
                     86:       ip precedence     :  (This will not be implemented by bgpd)
                     87:       ip tos            :  (This will not be implemented by bgpd)
                     88:       level             :  (This will not be implemented by bgpd)
                     89:       local-preference  :  Done
                     90:       metric            :  Done
                     91:       metric-type       :  Not yet
                     92:       origin            :  Done
                     93:       tag               :  (This will not be implemented by bgpd)
                     94:       weight            :  Done
                     95: 
1.1.1.4 ! misho      96: o Local extensions
1.1       misho      97: 
                     98:   set ipv6 next-hop global: Done
                     99:   set ipv6 next-hop local : Done
                    100:   set as-path exclude     : Done
                    101: 
                    102: */ 
1.1.1.4 ! misho     103: 
        !           104:  /* generic value manipulation to be shared in multiple rules */
        !           105: 
        !           106: #define RMAP_VALUE_SET 0
        !           107: #define RMAP_VALUE_ADD 1
        !           108: #define RMAP_VALUE_SUB 2
        !           109: 
        !           110: struct rmap_value
        !           111: {
        !           112:   u_int8_t action;
        !           113:   u_int8_t variable;
        !           114:   u_int32_t value;
        !           115: };
        !           116: 
        !           117: static int
        !           118: route_value_match (struct rmap_value *rv, u_int32_t value)
        !           119: {
        !           120:   if (rv->variable == 0 && value == rv->value)
        !           121:     return RMAP_MATCH;
        !           122: 
        !           123:   return RMAP_NOMATCH;
        !           124: }
        !           125: 
        !           126: static u_int32_t
        !           127: route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
        !           128: {
        !           129:   u_int32_t value;
        !           130: 
        !           131:   switch (rv->variable)
        !           132:     {
        !           133:     case 1:
        !           134:       value = peer->rtt;
        !           135:       break;
        !           136:     default:
        !           137:       value = rv->value;
        !           138:       break;
        !           139:     }
        !           140: 
        !           141:   switch (rv->action)
        !           142:     {
        !           143:     case RMAP_VALUE_ADD:
        !           144:       if (current > UINT32_MAX-value)
        !           145:         return UINT32_MAX;
        !           146:       return current + value;
        !           147:     case RMAP_VALUE_SUB:
        !           148:       if (current <= value)
        !           149:         return 0;
        !           150:       return current - value;
        !           151:     default:
        !           152:       return value;
        !           153:     }
        !           154: }
        !           155: 
        !           156: static void *
        !           157: route_value_compile (const char *arg)
        !           158: {
        !           159:   u_int8_t action = RMAP_VALUE_SET, var = 0;
        !           160:   unsigned long larg = 0;
        !           161:   char *endptr = NULL;
        !           162:   struct rmap_value *rv;
        !           163: 
        !           164:   if (arg[0] == '+')
        !           165:     {
        !           166:       action = RMAP_VALUE_ADD;
        !           167:       arg++;
        !           168:     }
        !           169:   else if (arg[0] == '-')
        !           170:     {
        !           171:       action = RMAP_VALUE_SUB;
        !           172:       arg++;
        !           173:     }
        !           174: 
        !           175:   if (all_digit(arg))
        !           176:     {
        !           177:       errno = 0;
        !           178:       larg = strtoul (arg, &endptr, 10);
        !           179:       if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
        !           180:         return NULL;
        !           181:     }
        !           182:   else
        !           183:     {
        !           184:       if (strcmp(arg, "rtt") == 0)
        !           185:         var = 1;
        !           186:       else
        !           187:         return NULL;
        !           188:     }
        !           189: 
        !           190:   rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
        !           191:   if (!rv)
        !           192:     return NULL;
        !           193: 
        !           194:   rv->action = action;
        !           195:   rv->variable = var;
        !           196:   rv->value = larg;
        !           197:   return rv;
        !           198: }
        !           199: 
        !           200: static void
        !           201: route_value_free (void *rule)
        !           202: {
        !           203:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !           204: }
        !           205: 
        !           206:  /* generic as path object to be shared in multiple rules */
        !           207: 
        !           208: static void *
        !           209: route_aspath_compile (const char *arg)
        !           210: {
        !           211:   struct aspath *aspath;
        !           212: 
        !           213:   aspath = aspath_str2aspath (arg);
        !           214:   if (! aspath)
        !           215:     return NULL;
        !           216:   return aspath;
        !           217: }
        !           218: 
        !           219: static void
        !           220: route_aspath_free (void *rule)
        !           221: {
        !           222:   struct aspath *aspath = rule;
        !           223:   aspath_free (aspath);
        !           224: }
        !           225: 
1.1       misho     226:  /* 'match peer (A.B.C.D|X:X::X:X)' */
                    227: 
                    228: /* Compares the peer specified in the 'match peer' clause with the peer
                    229:     received in bgp_info->peer. If it is the same, or if the peer structure
                    230:     received is a peer_group containing it, returns RMAP_MATCH. */
                    231: static route_map_result_t
                    232: route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
                    233:       void *object)
                    234: {
                    235:   union sockunion *su;
1.1.1.4 ! misho     236:   union sockunion su_def = { .sin = { .sin_family = AF_INET,
        !           237:                                       .sin_addr.s_addr = INADDR_ANY } };
1.1       misho     238:   struct peer_group *group;
                    239:   struct peer *peer;
                    240:   struct listnode *node, *nnode;
                    241: 
                    242:   if (type == RMAP_BGP)
                    243:     {
                    244:       su = rule;
                    245:       peer = ((struct bgp_info *) object)->peer;
                    246: 
                    247:       if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
                    248:            ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
                    249:         return RMAP_NOMATCH;
                    250: 
                    251:       /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
                    252:           REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
1.1.1.3   misho     253:       if (sockunion_same (su, &su_def))
1.1       misho     254:         {
                    255:           int ret;
                    256:           if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
                    257:                CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
                    258:                CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
                    259:             ret = RMAP_MATCH;
                    260:           else
                    261:             ret = RMAP_NOMATCH;
                    262:           return ret;
                    263:         }
1.1.1.3   misho     264: 
1.1       misho     265:       if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
                    266:         {
                    267:           if (sockunion_same (su, &peer->su))
                    268:             return RMAP_MATCH;
                    269: 
                    270:           return RMAP_NOMATCH;
                    271:         }
                    272:       else
                    273:         {
                    274:           group = peer->group;
                    275:           for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
                    276:             {
                    277:               if (sockunion_same (su, &peer->su))
                    278:                 return RMAP_MATCH;
                    279:             }
                    280:           return RMAP_NOMATCH;
                    281:         }
                    282:     }
                    283:   return RMAP_NOMATCH;
                    284: }
                    285: 
                    286: static void *
                    287: route_match_peer_compile (const char *arg)
                    288: {
                    289:   union sockunion *su;
                    290:   int ret;
                    291: 
                    292:   su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
                    293: 
1.1.1.3   misho     294:   ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
1.1       misho     295:   if (ret < 0) {
                    296:     XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
                    297:     return NULL;
                    298:   }
                    299: 
                    300:   return su;
                    301: }
                    302: 
                    303: /* Free route map's compiled `ip address' value. */
                    304: static void
                    305: route_match_peer_free (void *rule)
                    306: {
                    307:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    308: }
                    309: 
                    310: /* Route map commands for ip address matching. */
                    311: struct route_map_rule_cmd route_match_peer_cmd =
                    312: {
                    313:   "peer",
                    314:   route_match_peer,
                    315:   route_match_peer_compile,
                    316:   route_match_peer_free
                    317: };
                    318: 
                    319: /* `match ip address IP_ACCESS_LIST' */
                    320: 
                    321: /* Match function should return 1 if match is success else return
                    322:    zero. */
                    323: static route_map_result_t
                    324: route_match_ip_address (void *rule, struct prefix *prefix, 
                    325:                        route_map_object_t type, void *object)
                    326: {
                    327:   struct access_list *alist;
                    328:   /* struct prefix_ipv4 match; */
                    329: 
                    330:   if (type == RMAP_BGP)
                    331:     {
                    332:       alist = access_list_lookup (AFI_IP, (char *) rule);
                    333:       if (alist == NULL)
                    334:        return RMAP_NOMATCH;
                    335:     
                    336:       return (access_list_apply (alist, prefix) == FILTER_DENY ?
                    337:              RMAP_NOMATCH : RMAP_MATCH);
                    338:     }
                    339:   return RMAP_NOMATCH;
                    340: }
                    341: 
                    342: /* Route map `ip address' match statement.  `arg' should be
                    343:    access-list name. */
                    344: static void *
                    345: route_match_ip_address_compile (const char *arg)
                    346: {
                    347:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    348: }
                    349: 
                    350: /* Free route map's compiled `ip address' value. */
                    351: static void
                    352: route_match_ip_address_free (void *rule)
                    353: {
                    354:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    355: }
                    356: 
                    357: /* Route map commands for ip address matching. */
                    358: struct route_map_rule_cmd route_match_ip_address_cmd =
                    359: {
                    360:   "ip address",
                    361:   route_match_ip_address,
                    362:   route_match_ip_address_compile,
                    363:   route_match_ip_address_free
                    364: };
1.1.1.4 ! misho     365: 
1.1       misho     366: /* `match ip next-hop IP_ADDRESS' */
                    367: 
                    368: /* Match function return 1 if match is success else return zero. */
                    369: static route_map_result_t
                    370: route_match_ip_next_hop (void *rule, struct prefix *prefix, 
                    371:                         route_map_object_t type, void *object)
                    372: {
                    373:   struct access_list *alist;
                    374:   struct bgp_info *bgp_info;
                    375:   struct prefix_ipv4 p;
                    376: 
                    377:   if (type == RMAP_BGP)
                    378:     {
                    379:       bgp_info = object;
                    380:       p.family = AF_INET;
                    381:       p.prefix = bgp_info->attr->nexthop;
                    382:       p.prefixlen = IPV4_MAX_BITLEN;
                    383: 
                    384:       alist = access_list_lookup (AFI_IP, (char *) rule);
                    385:       if (alist == NULL)
                    386:        return RMAP_NOMATCH;
                    387: 
                    388:       return (access_list_apply (alist, &p) == FILTER_DENY ?
                    389:               RMAP_NOMATCH : RMAP_MATCH);
                    390:     }
                    391:   return RMAP_NOMATCH;
                    392: }
                    393: 
                    394: /* Route map `ip next-hop' match statement. `arg' is
                    395:    access-list name. */
                    396: static void *
                    397: route_match_ip_next_hop_compile (const char *arg)
                    398: {
                    399:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    400: }
                    401: 
                    402: /* Free route map's compiled `ip address' value. */
                    403: static void
                    404: route_match_ip_next_hop_free (void *rule)
                    405: {
                    406:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    407: }
                    408: 
                    409: /* Route map commands for ip next-hop matching. */
                    410: struct route_map_rule_cmd route_match_ip_next_hop_cmd =
                    411: {
                    412:   "ip next-hop",
                    413:   route_match_ip_next_hop,
                    414:   route_match_ip_next_hop_compile,
                    415:   route_match_ip_next_hop_free
                    416: };
1.1.1.4 ! misho     417: 
1.1       misho     418: /* `match ip route-source ACCESS-LIST' */
                    419: 
                    420: /* Match function return 1 if match is success else return zero. */
                    421: static route_map_result_t
                    422: route_match_ip_route_source (void *rule, struct prefix *prefix, 
                    423:                             route_map_object_t type, void *object)
                    424: {
                    425:   struct access_list *alist;
                    426:   struct bgp_info *bgp_info;
                    427:   struct peer *peer;
                    428:   struct prefix_ipv4 p;
                    429: 
                    430:   if (type == RMAP_BGP)
                    431:     {
                    432:       bgp_info = object;
                    433:       peer = bgp_info->peer;
                    434: 
                    435:       if (! peer || sockunion_family (&peer->su) != AF_INET)
                    436:        return RMAP_NOMATCH;
                    437: 
                    438:       p.family = AF_INET;
                    439:       p.prefix = peer->su.sin.sin_addr;
                    440:       p.prefixlen = IPV4_MAX_BITLEN;
                    441: 
                    442:       alist = access_list_lookup (AFI_IP, (char *) rule);
                    443:       if (alist == NULL)
                    444:        return RMAP_NOMATCH;
                    445: 
                    446:       return (access_list_apply (alist, &p) == FILTER_DENY ?
                    447:               RMAP_NOMATCH : RMAP_MATCH);
                    448:     }
                    449:   return RMAP_NOMATCH;
                    450: }
                    451: 
                    452: /* Route map `ip route-source' match statement. `arg' is
                    453:    access-list name. */
                    454: static void *
                    455: route_match_ip_route_source_compile (const char *arg)
                    456: {
                    457:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    458: }
                    459: 
                    460: /* Free route map's compiled `ip address' value. */
                    461: static void
                    462: route_match_ip_route_source_free (void *rule)
                    463: {
                    464:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    465: }
                    466: 
                    467: /* Route map commands for ip route-source matching. */
                    468: struct route_map_rule_cmd route_match_ip_route_source_cmd =
                    469: {
                    470:   "ip route-source",
                    471:   route_match_ip_route_source,
                    472:   route_match_ip_route_source_compile,
                    473:   route_match_ip_route_source_free
                    474: };
1.1.1.4 ! misho     475: 
1.1       misho     476: /* `match ip address prefix-list PREFIX_LIST' */
                    477: 
                    478: static route_map_result_t
                    479: route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, 
                    480:                                    route_map_object_t type, void *object)
                    481: {
                    482:   struct prefix_list *plist;
                    483: 
                    484:   if (type == RMAP_BGP)
                    485:     {
                    486:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
                    487:       if (plist == NULL)
                    488:        return RMAP_NOMATCH;
                    489:     
                    490:       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
                    491:              RMAP_NOMATCH : RMAP_MATCH);
                    492:     }
                    493:   return RMAP_NOMATCH;
                    494: }
                    495: 
                    496: static void *
                    497: route_match_ip_address_prefix_list_compile (const char *arg)
                    498: {
                    499:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    500: }
                    501: 
                    502: static void
                    503: route_match_ip_address_prefix_list_free (void *rule)
                    504: {
                    505:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    506: }
                    507: 
                    508: struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
                    509: {
                    510:   "ip address prefix-list",
                    511:   route_match_ip_address_prefix_list,
                    512:   route_match_ip_address_prefix_list_compile,
                    513:   route_match_ip_address_prefix_list_free
                    514: };
1.1.1.4 ! misho     515: 
1.1       misho     516: /* `match ip next-hop prefix-list PREFIX_LIST' */
                    517: 
                    518: static route_map_result_t
                    519: route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
                    520:                                     route_map_object_t type, void *object)
                    521: {
                    522:   struct prefix_list *plist;
                    523:   struct bgp_info *bgp_info;
                    524:   struct prefix_ipv4 p;
                    525: 
                    526:   if (type == RMAP_BGP)
                    527:     {
                    528:       bgp_info = object;
                    529:       p.family = AF_INET;
                    530:       p.prefix = bgp_info->attr->nexthop;
                    531:       p.prefixlen = IPV4_MAX_BITLEN;
                    532: 
                    533:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
                    534:       if (plist == NULL)
                    535:         return RMAP_NOMATCH;
                    536: 
                    537:       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
                    538:               RMAP_NOMATCH : RMAP_MATCH);
                    539:     }
                    540:   return RMAP_NOMATCH;
                    541: }
                    542: 
                    543: static void *
                    544: route_match_ip_next_hop_prefix_list_compile (const char *arg)
                    545: {
                    546:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    547: }
                    548: 
                    549: static void
                    550: route_match_ip_next_hop_prefix_list_free (void *rule)
                    551: {
                    552:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    553: }
                    554: 
                    555: struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
                    556: {
                    557:   "ip next-hop prefix-list",
                    558:   route_match_ip_next_hop_prefix_list,
                    559:   route_match_ip_next_hop_prefix_list_compile,
                    560:   route_match_ip_next_hop_prefix_list_free
                    561: };
1.1.1.4 ! misho     562: 
1.1       misho     563: /* `match ip route-source prefix-list PREFIX_LIST' */
                    564: 
                    565: static route_map_result_t
                    566: route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
                    567:                                         route_map_object_t type, void *object)
                    568: {
                    569:   struct prefix_list *plist;
                    570:   struct bgp_info *bgp_info;
                    571:   struct peer *peer;
                    572:   struct prefix_ipv4 p;
                    573: 
                    574:   if (type == RMAP_BGP)
                    575:     {
                    576:       bgp_info = object;
                    577:       peer = bgp_info->peer;
                    578: 
                    579:       if (! peer || sockunion_family (&peer->su) != AF_INET)
                    580:        return RMAP_NOMATCH;
                    581: 
                    582:       p.family = AF_INET;
                    583:       p.prefix = peer->su.sin.sin_addr;
                    584:       p.prefixlen = IPV4_MAX_BITLEN;
                    585: 
                    586:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
                    587:       if (plist == NULL)
                    588:         return RMAP_NOMATCH;
                    589: 
                    590:       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
                    591:               RMAP_NOMATCH : RMAP_MATCH);
                    592:     }
                    593:   return RMAP_NOMATCH;
                    594: }
                    595: 
                    596: static void *
                    597: route_match_ip_route_source_prefix_list_compile (const char *arg)
                    598: {
                    599:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    600: }
                    601: 
                    602: static void
                    603: route_match_ip_route_source_prefix_list_free (void *rule)
                    604: {
                    605:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    606: }
                    607: 
                    608: struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
                    609: {
                    610:   "ip route-source prefix-list",
                    611:   route_match_ip_route_source_prefix_list,
                    612:   route_match_ip_route_source_prefix_list_compile,
                    613:   route_match_ip_route_source_prefix_list_free
                    614: };
1.1.1.4 ! misho     615: 
1.1       misho     616: /* `match metric METRIC' */
                    617: 
                    618: /* Match function return 1 if match is success else return zero. */
                    619: static route_map_result_t
                    620: route_match_metric (void *rule, struct prefix *prefix, 
                    621:                    route_map_object_t type, void *object)
                    622: {
1.1.1.4 ! misho     623:   struct rmap_value *rv;
1.1       misho     624:   struct bgp_info *bgp_info;
                    625: 
                    626:   if (type == RMAP_BGP)
                    627:     {
1.1.1.4 ! misho     628:       rv = rule;
1.1       misho     629:       bgp_info = object;
1.1.1.4 ! misho     630:       return route_value_match(rv, bgp_info->attr->med);
1.1       misho     631:     }
                    632:   return RMAP_NOMATCH;
                    633: }
                    634: 
                    635: /* Route map commands for metric matching. */
                    636: struct route_map_rule_cmd route_match_metric_cmd =
                    637: {
                    638:   "metric",
                    639:   route_match_metric,
1.1.1.4 ! misho     640:   route_value_compile,
        !           641:   route_value_free,
1.1       misho     642: };
1.1.1.4 ! misho     643: 
1.1       misho     644: /* `match as-path ASPATH' */
                    645: 
                    646: /* Match function for as-path match.  I assume given object is */
                    647: static route_map_result_t
                    648: route_match_aspath (void *rule, struct prefix *prefix, 
                    649:                    route_map_object_t type, void *object)
                    650: {
                    651:   
                    652:   struct as_list *as_list;
                    653:   struct bgp_info *bgp_info;
                    654: 
                    655:   if (type == RMAP_BGP)
                    656:     {
                    657:       as_list = as_list_lookup ((char *) rule);
                    658:       if (as_list == NULL)
                    659:        return RMAP_NOMATCH;
                    660:     
                    661:       bgp_info = object;
                    662:     
                    663:       /* Perform match. */
                    664:       return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
                    665:     }
                    666:   return RMAP_NOMATCH;
                    667: }
                    668: 
                    669: /* Compile function for as-path match. */
                    670: static void *
                    671: route_match_aspath_compile (const char *arg)
                    672: {
                    673:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    674: }
                    675: 
                    676: /* Compile function for as-path match. */
                    677: static void
                    678: route_match_aspath_free (void *rule)
                    679: {
                    680:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    681: }
                    682: 
                    683: /* Route map commands for aspath matching. */
                    684: struct route_map_rule_cmd route_match_aspath_cmd = 
                    685: {
                    686:   "as-path",
                    687:   route_match_aspath,
                    688:   route_match_aspath_compile,
                    689:   route_match_aspath_free
                    690: };
1.1.1.4 ! misho     691: 
1.1       misho     692: /* `match community COMMUNIY' */
                    693: struct rmap_community
                    694: {
                    695:   char *name;
                    696:   int exact;
                    697: };
                    698: 
                    699: /* Match function for community match. */
                    700: static route_map_result_t
                    701: route_match_community (void *rule, struct prefix *prefix, 
                    702:                       route_map_object_t type, void *object)
                    703: {
                    704:   struct community_list *list;
                    705:   struct bgp_info *bgp_info;
                    706:   struct rmap_community *rcom;
                    707: 
                    708:   if (type == RMAP_BGP) 
                    709:     {
                    710:       bgp_info = object;
                    711:       rcom = rule;
                    712: 
                    713:       list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
                    714:       if (! list)
                    715:        return RMAP_NOMATCH;
                    716: 
                    717:       if (rcom->exact)
                    718:        {
                    719:          if (community_list_exact_match (bgp_info->attr->community, list))
                    720:            return RMAP_MATCH;
                    721:        }
                    722:       else
                    723:        {
                    724:          if (community_list_match (bgp_info->attr->community, list))
                    725:            return RMAP_MATCH;
                    726:        }
                    727:     }
                    728:   return RMAP_NOMATCH;
                    729: }
                    730: 
                    731: /* Compile function for community match. */
                    732: static void *
                    733: route_match_community_compile (const char *arg)
                    734: {
                    735:   struct rmap_community *rcom;
                    736:   int len;
                    737:   char *p;
                    738: 
                    739:   rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
                    740: 
                    741:   p = strchr (arg, ' ');
                    742:   if (p)
                    743:     {
                    744:       len = p - arg;
                    745:       rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
                    746:       memcpy (rcom->name, arg, len);
                    747:       rcom->exact = 1;
                    748:     }
                    749:   else
                    750:     {
                    751:       rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    752:       rcom->exact = 0;
                    753:     }
                    754:   return rcom;
                    755: }
                    756: 
                    757: /* Compile function for community match. */
                    758: static void
                    759: route_match_community_free (void *rule)
                    760: {
                    761:   struct rmap_community *rcom = rule;
                    762: 
                    763:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); 
                    764:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
                    765: }
                    766: 
                    767: /* Route map commands for community matching. */
                    768: struct route_map_rule_cmd route_match_community_cmd = 
                    769: {
                    770:   "community",
                    771:   route_match_community,
                    772:   route_match_community_compile,
                    773:   route_match_community_free
                    774: };
1.1.1.4 ! misho     775: 
1.1       misho     776: /* Match function for extcommunity match. */
                    777: static route_map_result_t
                    778: route_match_ecommunity (void *rule, struct prefix *prefix, 
                    779:                        route_map_object_t type, void *object)
                    780: {
                    781:   struct community_list *list;
                    782:   struct bgp_info *bgp_info;
                    783: 
                    784:   if (type == RMAP_BGP) 
                    785:     {
                    786:       bgp_info = object;
                    787:       
                    788:       if (!bgp_info->attr->extra)
                    789:         return RMAP_NOMATCH;
                    790:       
                    791:       list = community_list_lookup (bgp_clist, (char *) rule,
                    792:                                    EXTCOMMUNITY_LIST_MASTER);
                    793:       if (! list)
                    794:        return RMAP_NOMATCH;
                    795: 
                    796:       if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
                    797:        return RMAP_MATCH;
                    798:     }
                    799:   return RMAP_NOMATCH;
                    800: }
                    801: 
                    802: /* Compile function for extcommunity match. */
                    803: static void *
                    804: route_match_ecommunity_compile (const char *arg)
                    805: {
                    806:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                    807: }
                    808: 
                    809: /* Compile function for extcommunity match. */
                    810: static void
                    811: route_match_ecommunity_free (void *rule)
                    812: {
                    813:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    814: }
                    815: 
                    816: /* Route map commands for community matching. */
                    817: struct route_map_rule_cmd route_match_ecommunity_cmd = 
                    818: {
                    819:   "extcommunity",
                    820:   route_match_ecommunity,
                    821:   route_match_ecommunity_compile,
                    822:   route_match_ecommunity_free
                    823: };
1.1.1.4 ! misho     824: 
1.1       misho     825: /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
                    826:    and `address-family vpnv4'.  */
1.1.1.4 ! misho     827: 
1.1       misho     828: /* `match origin' */
                    829: static route_map_result_t
                    830: route_match_origin (void *rule, struct prefix *prefix, 
                    831:                    route_map_object_t type, void *object)
                    832: {
                    833:   u_char *origin;
                    834:   struct bgp_info *bgp_info;
                    835: 
                    836:   if (type == RMAP_BGP)
                    837:     {
                    838:       origin = rule;
                    839:       bgp_info = object;
                    840:     
                    841:       if (bgp_info->attr->origin == *origin)
                    842:        return RMAP_MATCH;
                    843:     }
                    844: 
                    845:   return RMAP_NOMATCH;
                    846: }
                    847: 
                    848: static void *
                    849: route_match_origin_compile (const char *arg)
                    850: {
                    851:   u_char *origin;
                    852: 
                    853:   origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
                    854: 
                    855:   if (strcmp (arg, "igp") == 0)
                    856:     *origin = 0;
                    857:   else if (strcmp (arg, "egp") == 0)
                    858:     *origin = 1;
                    859:   else
                    860:     *origin = 2;
                    861: 
                    862:   return origin;
                    863: }
                    864: 
                    865: /* Free route map's compiled `ip address' value. */
                    866: static void
                    867: route_match_origin_free (void *rule)
                    868: {
                    869:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    870: }
                    871: 
                    872: /* Route map commands for origin matching. */
                    873: struct route_map_rule_cmd route_match_origin_cmd =
                    874: {
                    875:   "origin",
                    876:   route_match_origin,
                    877:   route_match_origin_compile,
                    878:   route_match_origin_free
                    879: };
1.1.1.2   misho     880: 
                    881: /* match probability  { */
                    882: 
                    883: static route_map_result_t
                    884: route_match_probability (void *rule, struct prefix *prefix,
                    885:                    route_map_object_t type, void *object)
                    886: {
1.1.1.4 ! misho     887:   long r = random();
1.1.1.2   misho     888: 
1.1.1.4 ! misho     889:   switch (*(long *) rule)
1.1.1.2   misho     890:   {
                    891:     case 0: break;
                    892:     case RAND_MAX: return RMAP_MATCH;
                    893:     default:
1.1.1.4 ! misho     894:       if (r < *(long *) rule)
1.1.1.2   misho     895:         {
                    896:           return RMAP_MATCH;
                    897:         }
                    898:   }
                    899: 
                    900:   return RMAP_NOMATCH;
                    901: }
                    902: 
                    903: static void *
                    904: route_match_probability_compile (const char *arg)
                    905: {
1.1.1.4 ! misho     906:   long *lobule;
1.1.1.2   misho     907:   unsigned  perc;
                    908: 
                    909:   perc    = atoi (arg);
1.1.1.4 ! misho     910:   lobule  = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
1.1.1.2   misho     911: 
                    912:   switch (perc)
                    913:     {
                    914:       case 0:   *lobule = 0; break;
                    915:       case 100: *lobule = RAND_MAX; break;
                    916:       default:  *lobule = RAND_MAX / 100 * perc;
                    917:     }
                    918: 
                    919:   return lobule;
                    920: }
                    921: 
                    922: static void
                    923: route_match_probability_free (void *rule)
                    924: {
                    925:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                    926: }
                    927: 
                    928: struct route_map_rule_cmd route_match_probability_cmd =
                    929: {
                    930:   "probability",
                    931:   route_match_probability,
                    932:   route_match_probability_compile,
                    933:   route_match_probability_free
                    934: };
                    935: 
                    936: /* } */
                    937: 
1.1       misho     938: /* `set ip next-hop IP_ADDRESS' */
                    939: 
                    940: /* Set nexthop to object.  ojbect must be pointer to struct attr. */
                    941: struct rmap_ip_nexthop_set
                    942: {
                    943:   struct in_addr *address;
                    944:   int peer_address;
                    945: };
                    946: 
                    947: static route_map_result_t
                    948: route_set_ip_nexthop (void *rule, struct prefix *prefix,
                    949:                      route_map_object_t type, void *object)
                    950: {
                    951:   struct rmap_ip_nexthop_set *rins = rule;
                    952:   struct bgp_info *bgp_info;
                    953:   struct peer *peer;
                    954: 
                    955:   if (type == RMAP_BGP)
                    956:     {
                    957:       bgp_info = object;
                    958:       peer = bgp_info->peer;
                    959: 
                    960:       if (rins->peer_address)
                    961:        {
                    962:          if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
                    963:            CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
                    964:              && peer->su_remote 
                    965:              && sockunion_family (peer->su_remote) == AF_INET)
                    966:            {
1.1.1.3   misho     967:              bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
1.1       misho     968:              bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
                    969:            }
                    970:          else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
                    971:                   && peer->su_local
                    972:                   && sockunion_family (peer->su_local) == AF_INET)
                    973:            {
1.1.1.3   misho     974:              bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
1.1       misho     975:              bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
                    976:            }
                    977:        }
                    978:       else
                    979:        {
                    980:          /* Set next hop value. */ 
                    981:          bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
                    982:          bgp_info->attr->nexthop = *rins->address;
                    983:        }
                    984:     }
                    985: 
                    986:   return RMAP_OKAY;
                    987: }
                    988: 
                    989: /* Route map `ip nexthop' compile function.  Given string is converted
                    990:    to struct in_addr structure. */
                    991: static void *
                    992: route_set_ip_nexthop_compile (const char *arg)
                    993: {
                    994:   struct rmap_ip_nexthop_set *rins;
                    995:   struct in_addr *address = NULL;
                    996:   int peer_address = 0;
                    997:   int ret;
                    998: 
                    999:   if (strcmp (arg, "peer-address") == 0)
                   1000:     peer_address = 1;
                   1001:   else
                   1002:     {
                   1003:       address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
                   1004:       ret = inet_aton (arg, address);
                   1005: 
                   1006:       if (ret == 0)
                   1007:        {
                   1008:          XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
                   1009:          return NULL;
                   1010:        }
                   1011:     }
                   1012: 
                   1013:   rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
                   1014: 
                   1015:   rins->address = address;
                   1016:   rins->peer_address = peer_address;
                   1017: 
                   1018:   return rins;
                   1019: }
                   1020: 
                   1021: /* Free route map's compiled `ip nexthop' value. */
                   1022: static void
                   1023: route_set_ip_nexthop_free (void *rule)
                   1024: {
                   1025:   struct rmap_ip_nexthop_set *rins = rule;
                   1026: 
                   1027:   if (rins->address)
                   1028:     XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
                   1029:     
                   1030:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
                   1031: }
                   1032: 
                   1033: /* Route map commands for ip nexthop set. */
                   1034: struct route_map_rule_cmd route_set_ip_nexthop_cmd =
                   1035: {
                   1036:   "ip next-hop",
                   1037:   route_set_ip_nexthop,
                   1038:   route_set_ip_nexthop_compile,
                   1039:   route_set_ip_nexthop_free
                   1040: };
1.1.1.4 ! misho    1041: 
1.1       misho    1042: /* `set local-preference LOCAL_PREF' */
                   1043: 
                   1044: /* Set local preference. */
                   1045: static route_map_result_t
                   1046: route_set_local_pref (void *rule, struct prefix *prefix,
                   1047:                      route_map_object_t type, void *object)
                   1048: {
1.1.1.4 ! misho    1049:   struct rmap_value *rv;
1.1       misho    1050:   struct bgp_info *bgp_info;
1.1.1.4 ! misho    1051:   u_int32_t locpref = 0;
1.1       misho    1052: 
                   1053:   if (type == RMAP_BGP)
                   1054:     {
                   1055:       /* Fetch routemap's rule information. */
1.1.1.4 ! misho    1056:       rv = rule;
1.1       misho    1057:       bgp_info = object;
                   1058:     
                   1059:       /* Set local preference value. */ 
1.1.1.4 ! misho    1060:       if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
        !          1061:        locpref = bgp_info->attr->local_pref;
        !          1062: 
1.1       misho    1063:       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1.1.1.4 ! misho    1064:       bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
1.1       misho    1065:     }
                   1066: 
                   1067:   return RMAP_OKAY;
                   1068: }
                   1069: 
                   1070: /* Set local preference rule structure. */
                   1071: struct route_map_rule_cmd route_set_local_pref_cmd = 
                   1072: {
                   1073:   "local-preference",
                   1074:   route_set_local_pref,
1.1.1.4 ! misho    1075:   route_value_compile,
        !          1076:   route_value_free,
1.1       misho    1077: };
1.1.1.4 ! misho    1078: 
1.1       misho    1079: /* `set weight WEIGHT' */
                   1080: 
                   1081: /* Set weight. */
                   1082: static route_map_result_t
                   1083: route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
                   1084:                  void *object)
                   1085: {
1.1.1.4 ! misho    1086:   struct rmap_value *rv;
1.1       misho    1087:   struct bgp_info *bgp_info;
1.1.1.4 ! misho    1088:   u_int32_t weight;
1.1       misho    1089: 
                   1090:   if (type == RMAP_BGP)
                   1091:     {
                   1092:       /* Fetch routemap's rule information. */
1.1.1.4 ! misho    1093:       rv = rule;
1.1       misho    1094:       bgp_info = object;
                   1095:     
                   1096:       /* Set weight value. */ 
1.1.1.4 ! misho    1097:       weight = route_value_adjust(rv, 0, bgp_info->peer);
        !          1098:       if (weight)
        !          1099:         (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
1.1       misho    1100:       else if (bgp_info->attr->extra)
                   1101:         bgp_info->attr->extra->weight = 0;
                   1102:     }
                   1103: 
                   1104:   return RMAP_OKAY;
                   1105: }
                   1106: 
                   1107: /* Set local preference rule structure. */
                   1108: struct route_map_rule_cmd route_set_weight_cmd = 
                   1109: {
                   1110:   "weight",
                   1111:   route_set_weight,
1.1.1.4 ! misho    1112:   route_value_compile,
        !          1113:   route_value_free,
1.1       misho    1114: };
1.1.1.4 ! misho    1115: 
1.1       misho    1116: /* `set metric METRIC' */
                   1117: 
                   1118: /* Set metric to attribute. */
                   1119: static route_map_result_t
                   1120: route_set_metric (void *rule, struct prefix *prefix, 
                   1121:                  route_map_object_t type, void *object)
                   1122: {
1.1.1.4 ! misho    1123:   struct rmap_value *rv;
1.1       misho    1124:   struct bgp_info *bgp_info;
1.1.1.4 ! misho    1125:   u_int32_t med = 0;
1.1       misho    1126: 
                   1127:   if (type == RMAP_BGP)
                   1128:     {
                   1129:       /* Fetch routemap's rule information. */
1.1.1.4 ! misho    1130:       rv = rule;
1.1       misho    1131:       bgp_info = object;
                   1132: 
1.1.1.4 ! misho    1133:       if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
        !          1134:        med = bgp_info->attr->med;
1.1       misho    1135: 
1.1.1.4 ! misho    1136:       bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
        !          1137:       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1.1       misho    1138:     }
                   1139:   return RMAP_OKAY;
                   1140: }
                   1141: 
                   1142: /* Set metric rule structure. */
                   1143: struct route_map_rule_cmd route_set_metric_cmd = 
                   1144: {
                   1145:   "metric",
                   1146:   route_set_metric,
1.1.1.4 ! misho    1147:   route_value_compile,
        !          1148:   route_value_free,
1.1       misho    1149: };
1.1.1.4 ! misho    1150: 
1.1       misho    1151: /* `set as-path prepend ASPATH' */
                   1152: 
                   1153: /* For AS path prepend mechanism. */
                   1154: static route_map_result_t
                   1155: route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
                   1156: {
                   1157:   struct aspath *aspath;
                   1158:   struct aspath *new;
                   1159:   struct bgp_info *binfo;
                   1160: 
                   1161:   if (type == RMAP_BGP)
                   1162:     {
                   1163:       binfo = object;
                   1164:     
                   1165:       if (binfo->attr->aspath->refcnt)
                   1166:        new = aspath_dup (binfo->attr->aspath);
                   1167:       else
                   1168:        new = binfo->attr->aspath;
                   1169: 
1.1.1.4 ! misho    1170:       if ((uintptr_t)rule > 10)
        !          1171:       {
        !          1172:        aspath = rule;
        !          1173:        aspath_prepend (aspath, new);
        !          1174:       }
        !          1175:       else
        !          1176:       {
        !          1177:        as_t as = aspath_leftmost(new);
        !          1178:        if (!as) as = binfo->peer->as;
        !          1179:        new = aspath_add_seq_n (new, as, (uintptr_t) rule);
        !          1180:       }
        !          1181: 
1.1       misho    1182:       binfo->attr->aspath = new;
                   1183:     }
                   1184: 
                   1185:   return RMAP_OKAY;
                   1186: }
                   1187: 
                   1188: static void *
                   1189: route_set_aspath_prepend_compile (const char *arg)
                   1190: {
1.1.1.4 ! misho    1191:   unsigned int num;
1.1       misho    1192: 
1.1.1.4 ! misho    1193:   if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
        !          1194:     return (void*)(uintptr_t)num;
        !          1195: 
        !          1196:   return route_aspath_compile(arg);
1.1       misho    1197: }
                   1198: 
                   1199: static void
                   1200: route_set_aspath_prepend_free (void *rule)
                   1201: {
1.1.1.4 ! misho    1202:   if ((uintptr_t)rule > 10)
        !          1203:     route_aspath_free(rule);
1.1       misho    1204: }
                   1205: 
1.1.1.4 ! misho    1206: 
        !          1207: /* Set as-path prepend rule structure. */
1.1       misho    1208: struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
                   1209: {
                   1210:   "as-path prepend",
                   1211:   route_set_aspath_prepend,
                   1212:   route_set_aspath_prepend_compile,
                   1213:   route_set_aspath_prepend_free,
                   1214: };
1.1.1.4 ! misho    1215: 
1.1       misho    1216: /* `set as-path exclude ASn' */
                   1217: 
                   1218: /* For ASN exclude mechanism.
                   1219:  * Iterate over ASns requested and filter them from the given AS_PATH one by one.
                   1220:  * Make a deep copy of existing AS_PATH, but for the first ASn only.
                   1221:  */
                   1222: static route_map_result_t
                   1223: route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
                   1224: {
                   1225:   struct aspath * new_path, * exclude_path;
                   1226:   struct bgp_info *binfo;
                   1227: 
                   1228:   if (type == RMAP_BGP)
                   1229:   {
                   1230:     exclude_path = rule;
                   1231:     binfo = object;
                   1232:     if (binfo->attr->aspath->refcnt)
                   1233:       new_path = aspath_dup (binfo->attr->aspath);
                   1234:     else
                   1235:       new_path = binfo->attr->aspath;
                   1236:     binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
                   1237:   }
                   1238:   return RMAP_OKAY;
                   1239: }
                   1240: 
                   1241: /* Set ASn exlude rule structure. */
                   1242: struct route_map_rule_cmd route_set_aspath_exclude_cmd = 
                   1243: {
                   1244:   "as-path exclude",
                   1245:   route_set_aspath_exclude,
1.1.1.4 ! misho    1246:   route_aspath_compile,
        !          1247:   route_aspath_free,
1.1       misho    1248: };
1.1.1.4 ! misho    1249: 
1.1       misho    1250: /* `set community COMMUNITY' */
                   1251: struct rmap_com_set
                   1252: {
                   1253:   struct community *com;
                   1254:   int additive;
                   1255:   int none;
                   1256: };
                   1257: 
                   1258: /* For community set mechanism. */
                   1259: static route_map_result_t
                   1260: route_set_community (void *rule, struct prefix *prefix,
                   1261:                     route_map_object_t type, void *object)
                   1262: {
                   1263:   struct rmap_com_set *rcs;
                   1264:   struct bgp_info *binfo;
                   1265:   struct attr *attr;
                   1266:   struct community *new = NULL;
                   1267:   struct community *old;
                   1268:   struct community *merge;
                   1269:   
                   1270:   if (type == RMAP_BGP)
                   1271:     {
                   1272:       rcs = rule;
                   1273:       binfo = object;
                   1274:       attr = binfo->attr;
                   1275:       old = attr->community;
                   1276: 
                   1277:       /* "none" case.  */
                   1278:       if (rcs->none)
                   1279:        {
                   1280:          attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
                   1281:          attr->community = NULL;
1.1.1.3   misho    1282:          /* See the longer comment down below. */
                   1283:          if (old && old->refcnt == 0)
                   1284:            community_free(old);
1.1       misho    1285:          return RMAP_OKAY;
                   1286:        }
                   1287: 
                   1288:       /* "additive" case.  */
                   1289:       if (rcs->additive && old)
                   1290:        {
                   1291:          merge = community_merge (community_dup (old), rcs->com);
                   1292:          
                   1293:          /* HACK: if the old community is not intern'd, 
                   1294:            * we should free it here, or all reference to it may be lost.
                   1295:            * Really need to cleanup attribute caching sometime.
                   1296:            */
                   1297:          if (old->refcnt == 0)
                   1298:            community_free (old);
                   1299:          new = community_uniq_sort (merge);
                   1300:          community_free (merge);
                   1301:        }
                   1302:       else
                   1303:        new = community_dup (rcs->com);
                   1304:       
                   1305:       /* will be interned by caller if required */
                   1306:       attr->community = new;
                   1307: 
                   1308:       attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
                   1309:     }
                   1310: 
                   1311:   return RMAP_OKAY;
                   1312: }
                   1313: 
                   1314: /* Compile function for set community. */
                   1315: static void *
                   1316: route_set_community_compile (const char *arg)
                   1317: {
                   1318:   struct rmap_com_set *rcs;
                   1319:   struct community *com = NULL;
                   1320:   char *sp;
                   1321:   int additive = 0;
                   1322:   int none = 0;
                   1323:   
                   1324:   if (strcmp (arg, "none") == 0)
                   1325:     none = 1;
                   1326:   else
                   1327:     {
                   1328:       sp = strstr (arg, "additive");
                   1329: 
                   1330:       if (sp && sp > arg)
                   1331:        {
                   1332:          /* "additive" keyworkd is included.  */
                   1333:          additive = 1;
                   1334:          *(sp - 1) = '\0';
                   1335:        }
                   1336: 
                   1337:       com = community_str2com (arg);
                   1338: 
                   1339:       if (additive)
                   1340:        *(sp - 1) = ' ';
                   1341: 
                   1342:       if (! com)
                   1343:        return NULL;
                   1344:     }
                   1345:   
                   1346:   rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
                   1347:   rcs->com = com;
                   1348:   rcs->additive = additive;
                   1349:   rcs->none = none;
                   1350:   
                   1351:   return rcs;
                   1352: }
                   1353: 
                   1354: /* Free function for set community. */
                   1355: static void
                   1356: route_set_community_free (void *rule)
                   1357: {
                   1358:   struct rmap_com_set *rcs = rule;
                   1359: 
                   1360:   if (rcs->com)
                   1361:     community_free (rcs->com);
                   1362:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
                   1363: }
                   1364: 
                   1365: /* Set community rule structure. */
                   1366: struct route_map_rule_cmd route_set_community_cmd = 
                   1367: {
                   1368:   "community",
                   1369:   route_set_community,
                   1370:   route_set_community_compile,
                   1371:   route_set_community_free,
                   1372: };
1.1.1.4 ! misho    1373: 
1.1       misho    1374: /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
                   1375: 
                   1376: /* For community set mechanism. */
                   1377: static route_map_result_t
                   1378: route_set_community_delete (void *rule, struct prefix *prefix,
                   1379:                            route_map_object_t type, void *object)
                   1380: {
                   1381:   struct community_list *list;
                   1382:   struct community *merge;
                   1383:   struct community *new;
                   1384:   struct community *old;
                   1385:   struct bgp_info *binfo;
                   1386: 
                   1387:   if (type == RMAP_BGP)
                   1388:     {
                   1389:       if (! rule)
                   1390:        return RMAP_OKAY;
                   1391: 
                   1392:       binfo = object;
                   1393:       list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
                   1394:       old = binfo->attr->community;
                   1395: 
                   1396:       if (list && old)
                   1397:        {
                   1398:          merge = community_list_match_delete (community_dup (old), list);
                   1399:          new = community_uniq_sort (merge);
                   1400:          community_free (merge);
                   1401: 
                   1402:          /* HACK: if the old community is not intern'd,
                   1403:           * we should free it here, or all reference to it may be lost.
                   1404:           * Really need to cleanup attribute caching sometime.
                   1405:           */
                   1406:          if (old->refcnt == 0)
                   1407:            community_free (old);
                   1408: 
                   1409:          if (new->size == 0)
                   1410:            {
                   1411:              binfo->attr->community = NULL;
                   1412:              binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
                   1413:              community_free (new);
                   1414:            }
                   1415:          else
                   1416:            {
                   1417:              binfo->attr->community = new;
                   1418:              binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
                   1419:            }
                   1420:        }
                   1421:     }
                   1422: 
                   1423:   return RMAP_OKAY;
                   1424: }
                   1425: 
                   1426: /* Compile function for set community. */
                   1427: static void *
                   1428: route_set_community_delete_compile (const char *arg)
                   1429: {
                   1430:   char *p;
                   1431:   char *str;
                   1432:   int len;
                   1433: 
                   1434:   p = strchr (arg, ' ');
                   1435:   if (p)
                   1436:     {
                   1437:       len = p - arg;
                   1438:       str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
                   1439:       memcpy (str, arg, len);
                   1440:     }
                   1441:   else
                   1442:     str = NULL;
                   1443: 
                   1444:   return str;
                   1445: }
                   1446: 
                   1447: /* Free function for set community. */
                   1448: static void
                   1449: route_set_community_delete_free (void *rule)
                   1450: {
                   1451:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1452: }
                   1453: 
                   1454: /* Set community rule structure. */
                   1455: struct route_map_rule_cmd route_set_community_delete_cmd =
                   1456: {
                   1457:   "comm-list",
                   1458:   route_set_community_delete,
                   1459:   route_set_community_delete_compile,
                   1460:   route_set_community_delete_free,
                   1461: };
1.1.1.4 ! misho    1462: 
1.1       misho    1463: /* `set extcommunity rt COMMUNITY' */
                   1464: 
1.1.1.4 ! misho    1465: /* For community set mechanism.  Used by _rt and _soo. */
1.1       misho    1466: static route_map_result_t
1.1.1.4 ! misho    1467: route_set_ecommunity (void *rule, struct prefix *prefix,
        !          1468:                      route_map_object_t type, void *object)
1.1       misho    1469: {
                   1470:   struct ecommunity *ecom;
                   1471:   struct ecommunity *new_ecom;
                   1472:   struct ecommunity *old_ecom;
                   1473:   struct bgp_info *bgp_info;
                   1474: 
                   1475:   if (type == RMAP_BGP)
                   1476:     {
                   1477:       ecom = rule;
                   1478:       bgp_info = object;
                   1479:     
                   1480:       if (! ecom)
                   1481:        return RMAP_OKAY;
                   1482:     
                   1483:       /* We assume additive for Extended Community. */
                   1484:       old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
                   1485: 
                   1486:       if (old_ecom)
1.1.1.4 ! misho    1487:        {
        !          1488:          new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
        !          1489: 
        !          1490:          /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
        !          1491:           *         ->refcnt = 0 => set by a previous route-map statement */
        !          1492:          if (!old_ecom->refcnt)
        !          1493:            ecommunity_free (&old_ecom);
        !          1494:        }
1.1       misho    1495:       else
                   1496:        new_ecom = ecommunity_dup (ecom);
                   1497: 
1.1.1.4 ! misho    1498:       /* will be intern()'d or attr_flush()'d by bgp_update_main() */
        !          1499:       bgp_info->attr->extra->ecommunity = new_ecom;
1.1       misho    1500: 
                   1501:       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
                   1502:     }
                   1503:   return RMAP_OKAY;
                   1504: }
                   1505: 
                   1506: /* Compile function for set community. */
                   1507: static void *
                   1508: route_set_ecommunity_rt_compile (const char *arg)
                   1509: {
                   1510:   struct ecommunity *ecom;
                   1511: 
                   1512:   ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
                   1513:   if (! ecom)
                   1514:     return NULL;
                   1515:   return ecommunity_intern (ecom);
                   1516: }
                   1517: 
1.1.1.4 ! misho    1518: /* Free function for set community.  Used by _rt and _soo */
1.1       misho    1519: static void
1.1.1.4 ! misho    1520: route_set_ecommunity_free (void *rule)
1.1       misho    1521: {
                   1522:   struct ecommunity *ecom = rule;
                   1523:   ecommunity_unintern (&ecom);
                   1524: }
                   1525: 
                   1526: /* Set community rule structure. */
                   1527: struct route_map_rule_cmd route_set_ecommunity_rt_cmd = 
                   1528: {
                   1529:   "extcommunity rt",
1.1.1.4 ! misho    1530:   route_set_ecommunity,
1.1       misho    1531:   route_set_ecommunity_rt_compile,
1.1.1.4 ! misho    1532:   route_set_ecommunity_free,
1.1       misho    1533: };
                   1534: 
                   1535: /* `set extcommunity soo COMMUNITY' */
                   1536: 
                   1537: /* Compile function for set community. */
                   1538: static void *
                   1539: route_set_ecommunity_soo_compile (const char *arg)
                   1540: {
                   1541:   struct ecommunity *ecom;
                   1542: 
                   1543:   ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
                   1544:   if (! ecom)
                   1545:     return NULL;
                   1546:   
                   1547:   return ecommunity_intern (ecom);
                   1548: }
                   1549: 
                   1550: /* Set community rule structure. */
                   1551: struct route_map_rule_cmd route_set_ecommunity_soo_cmd = 
                   1552: {
                   1553:   "extcommunity soo",
1.1.1.4 ! misho    1554:   route_set_ecommunity,
1.1       misho    1555:   route_set_ecommunity_soo_compile,
1.1.1.4 ! misho    1556:   route_set_ecommunity_free,
1.1       misho    1557: };
1.1.1.4 ! misho    1558: 
1.1       misho    1559: /* `set origin ORIGIN' */
                   1560: 
                   1561: /* For origin set. */
                   1562: static route_map_result_t
                   1563: route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
                   1564: {
                   1565:   u_char *origin;
                   1566:   struct bgp_info *bgp_info;
                   1567: 
                   1568:   if (type == RMAP_BGP)
                   1569:     {
                   1570:       origin = rule;
                   1571:       bgp_info = object;
                   1572:     
                   1573:       bgp_info->attr->origin = *origin;
                   1574:     }
                   1575: 
                   1576:   return RMAP_OKAY;
                   1577: }
                   1578: 
                   1579: /* Compile function for origin set. */
                   1580: static void *
                   1581: route_set_origin_compile (const char *arg)
                   1582: {
                   1583:   u_char *origin;
                   1584: 
                   1585:   origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
                   1586: 
                   1587:   if (strcmp (arg, "igp") == 0)
                   1588:     *origin = 0;
                   1589:   else if (strcmp (arg, "egp") == 0)
                   1590:     *origin = 1;
                   1591:   else
                   1592:     *origin = 2;
                   1593: 
                   1594:   return origin;
                   1595: }
                   1596: 
                   1597: /* Compile function for origin set. */
                   1598: static void
                   1599: route_set_origin_free (void *rule)
                   1600: {
                   1601:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1602: }
                   1603: 
1.1.1.4 ! misho    1604: /* Set origin rule structure. */
1.1       misho    1605: struct route_map_rule_cmd route_set_origin_cmd = 
                   1606: {
                   1607:   "origin",
                   1608:   route_set_origin,
                   1609:   route_set_origin_compile,
                   1610:   route_set_origin_free,
                   1611: };
1.1.1.4 ! misho    1612: 
1.1       misho    1613: /* `set atomic-aggregate' */
                   1614: 
                   1615: /* For atomic aggregate set. */
                   1616: static route_map_result_t
                   1617: route_set_atomic_aggregate (void *rule, struct prefix *prefix,
                   1618:                            route_map_object_t type, void *object)
                   1619: {
                   1620:   struct bgp_info *bgp_info;
                   1621: 
                   1622:   if (type == RMAP_BGP)
                   1623:     {
                   1624:       bgp_info = object;
                   1625:       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
                   1626:     }
                   1627: 
                   1628:   return RMAP_OKAY;
                   1629: }
                   1630: 
                   1631: /* Compile function for atomic aggregate. */
                   1632: static void *
                   1633: route_set_atomic_aggregate_compile (const char *arg)
                   1634: {
                   1635:   return (void *)1;
                   1636: }
                   1637: 
                   1638: /* Compile function for atomic aggregate. */
                   1639: static void
                   1640: route_set_atomic_aggregate_free (void *rule)
                   1641: {
                   1642:   return;
                   1643: }
                   1644: 
                   1645: /* Set atomic aggregate rule structure. */
                   1646: struct route_map_rule_cmd route_set_atomic_aggregate_cmd = 
                   1647: {
                   1648:   "atomic-aggregate",
                   1649:   route_set_atomic_aggregate,
                   1650:   route_set_atomic_aggregate_compile,
                   1651:   route_set_atomic_aggregate_free,
                   1652: };
1.1.1.4 ! misho    1653: 
1.1       misho    1654: /* `set aggregator as AS A.B.C.D' */
                   1655: struct aggregator
                   1656: {
                   1657:   as_t as;
                   1658:   struct in_addr address;
                   1659: };
                   1660: 
                   1661: static route_map_result_t
                   1662: route_set_aggregator_as (void *rule, struct prefix *prefix, 
                   1663:                         route_map_object_t type, void *object)
                   1664: {
                   1665:   struct bgp_info *bgp_info;
                   1666:   struct aggregator *aggregator;
                   1667:   struct attr_extra *ae;
                   1668: 
                   1669:   if (type == RMAP_BGP)
                   1670:     {
                   1671:       bgp_info = object;
                   1672:       aggregator = rule;
                   1673:       ae = bgp_attr_extra_get (bgp_info->attr);
                   1674:       
                   1675:       ae->aggregator_as = aggregator->as;
                   1676:       ae->aggregator_addr = aggregator->address;
                   1677:       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
                   1678:     }
                   1679: 
                   1680:   return RMAP_OKAY;
                   1681: }
                   1682: 
                   1683: static void *
                   1684: route_set_aggregator_as_compile (const char *arg)
                   1685: {
                   1686:   struct aggregator *aggregator;
                   1687:   char as[10];
                   1688:   char address[20];
                   1689: 
                   1690:   aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
                   1691:   sscanf (arg, "%s %s", as, address);
                   1692: 
                   1693:   aggregator->as = strtoul (as, NULL, 10);
                   1694:   inet_aton (address, &aggregator->address);
                   1695: 
                   1696:   return aggregator;
                   1697: }
                   1698: 
                   1699: static void
                   1700: route_set_aggregator_as_free (void *rule)
                   1701: {
                   1702:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1703: }
                   1704: 
                   1705: struct route_map_rule_cmd route_set_aggregator_as_cmd = 
                   1706: {
                   1707:   "aggregator as",
                   1708:   route_set_aggregator_as,
                   1709:   route_set_aggregator_as_compile,
                   1710:   route_set_aggregator_as_free,
                   1711: };
1.1.1.4 ! misho    1712: 
1.1       misho    1713: /* `match ipv6 address IP_ACCESS_LIST' */
                   1714: 
                   1715: static route_map_result_t
                   1716: route_match_ipv6_address (void *rule, struct prefix *prefix, 
                   1717:                          route_map_object_t type, void *object)
                   1718: {
                   1719:   struct access_list *alist;
                   1720: 
                   1721:   if (type == RMAP_BGP)
                   1722:     {
                   1723:       alist = access_list_lookup (AFI_IP6, (char *) rule);
                   1724:       if (alist == NULL)
                   1725:        return RMAP_NOMATCH;
                   1726:     
                   1727:       return (access_list_apply (alist, prefix) == FILTER_DENY ?
                   1728:              RMAP_NOMATCH : RMAP_MATCH);
                   1729:     }
                   1730:   return RMAP_NOMATCH;
                   1731: }
                   1732: 
                   1733: static void *
                   1734: route_match_ipv6_address_compile (const char *arg)
                   1735: {
                   1736:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                   1737: }
                   1738: 
                   1739: static void
                   1740: route_match_ipv6_address_free (void *rule)
                   1741: {
                   1742:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1743: }
                   1744: 
                   1745: /* Route map commands for ip address matching. */
                   1746: struct route_map_rule_cmd route_match_ipv6_address_cmd =
                   1747: {
                   1748:   "ipv6 address",
                   1749:   route_match_ipv6_address,
                   1750:   route_match_ipv6_address_compile,
                   1751:   route_match_ipv6_address_free
                   1752: };
1.1.1.4 ! misho    1753: 
1.1       misho    1754: /* `match ipv6 next-hop IP_ADDRESS' */
                   1755: 
                   1756: static route_map_result_t
                   1757: route_match_ipv6_next_hop (void *rule, struct prefix *prefix, 
                   1758:                           route_map_object_t type, void *object)
                   1759: {
1.1.1.4 ! misho    1760:   struct in6_addr *addr = rule;
1.1       misho    1761:   struct bgp_info *bgp_info;
                   1762: 
                   1763:   if (type == RMAP_BGP)
                   1764:     {
                   1765:       bgp_info = object;
                   1766:       
                   1767:       if (!bgp_info->attr->extra)
                   1768:         return RMAP_NOMATCH;
                   1769:       
1.1.1.4 ! misho    1770:       if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
1.1       misho    1771:        return RMAP_MATCH;
                   1772: 
                   1773:       if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1.1.1.4 ! misho    1774:          IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
1.1       misho    1775:        return RMAP_MATCH;
                   1776: 
                   1777:       return RMAP_NOMATCH;
                   1778:     }
                   1779: 
                   1780:   return RMAP_NOMATCH;
                   1781: }
                   1782: 
                   1783: static void *
                   1784: route_match_ipv6_next_hop_compile (const char *arg)
                   1785: {
                   1786:   struct in6_addr *address;
                   1787:   int ret;
                   1788: 
                   1789:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
                   1790: 
                   1791:   ret = inet_pton (AF_INET6, arg, address);
                   1792:   if (!ret)
                   1793:     {
                   1794:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
                   1795:       return NULL;
                   1796:     }
                   1797: 
                   1798:   return address;
                   1799: }
                   1800: 
                   1801: static void
                   1802: route_match_ipv6_next_hop_free (void *rule)
                   1803: {
                   1804:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1805: }
                   1806: 
                   1807: struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
                   1808: {
                   1809:   "ipv6 next-hop",
                   1810:   route_match_ipv6_next_hop,
                   1811:   route_match_ipv6_next_hop_compile,
                   1812:   route_match_ipv6_next_hop_free
                   1813: };
1.1.1.4 ! misho    1814: 
1.1       misho    1815: /* `match ipv6 address prefix-list PREFIX_LIST' */
                   1816: 
                   1817: static route_map_result_t
                   1818: route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, 
                   1819:                              route_map_object_t type, void *object)
                   1820: {
                   1821:   struct prefix_list *plist;
                   1822: 
                   1823:   if (type == RMAP_BGP)
                   1824:     {
                   1825:       plist = prefix_list_lookup (AFI_IP6, (char *) rule);
                   1826:       if (plist == NULL)
                   1827:        return RMAP_NOMATCH;
                   1828:     
                   1829:       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
                   1830:              RMAP_NOMATCH : RMAP_MATCH);
                   1831:     }
                   1832:   return RMAP_NOMATCH;
                   1833: }
                   1834: 
                   1835: static void *
                   1836: route_match_ipv6_address_prefix_list_compile (const char *arg)
                   1837: {
                   1838:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
                   1839: }
                   1840: 
                   1841: static void
                   1842: route_match_ipv6_address_prefix_list_free (void *rule)
                   1843: {
                   1844:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1845: }
                   1846: 
                   1847: struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
                   1848: {
                   1849:   "ipv6 address prefix-list",
                   1850:   route_match_ipv6_address_prefix_list,
                   1851:   route_match_ipv6_address_prefix_list_compile,
                   1852:   route_match_ipv6_address_prefix_list_free
                   1853: };
1.1.1.4 ! misho    1854: 
1.1       misho    1855: /* `set ipv6 nexthop global IP_ADDRESS' */
                   1856: 
                   1857: /* Set nexthop to object.  ojbect must be pointer to struct attr. */
                   1858: static route_map_result_t
                   1859: route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, 
                   1860:                               route_map_object_t type, void *object)
                   1861: {
                   1862:   struct in6_addr *address;
                   1863:   struct bgp_info *bgp_info;
                   1864: 
                   1865:   if (type == RMAP_BGP)
                   1866:     {
                   1867:       /* Fetch routemap's rule information. */
                   1868:       address = rule;
                   1869:       bgp_info = object;
                   1870:     
                   1871:       /* Set next hop value. */ 
                   1872:       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
                   1873:     
                   1874:       /* Set nexthop length. */
                   1875:       if (bgp_info->attr->extra->mp_nexthop_len == 0)
                   1876:        bgp_info->attr->extra->mp_nexthop_len = 16;
                   1877:     }
                   1878: 
                   1879:   return RMAP_OKAY;
                   1880: }
                   1881: 
                   1882: /* Route map `ip next-hop' compile function.  Given string is converted
                   1883:    to struct in_addr structure. */
                   1884: static void *
                   1885: route_set_ipv6_nexthop_global_compile (const char *arg)
                   1886: {
                   1887:   int ret;
                   1888:   struct in6_addr *address;
                   1889: 
                   1890:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
                   1891: 
                   1892:   ret = inet_pton (AF_INET6, arg, address);
                   1893: 
                   1894:   if (ret == 0)
                   1895:     {
                   1896:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
                   1897:       return NULL;
                   1898:     }
                   1899: 
                   1900:   return address;
                   1901: }
                   1902: 
                   1903: /* Free route map's compiled `ip next-hop' value. */
                   1904: static void
                   1905: route_set_ipv6_nexthop_global_free (void *rule)
                   1906: {
                   1907:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1908: }
                   1909: 
                   1910: /* Route map commands for ip nexthop set. */
                   1911: struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
                   1912: {
                   1913:   "ipv6 next-hop global",
                   1914:   route_set_ipv6_nexthop_global,
                   1915:   route_set_ipv6_nexthop_global_compile,
                   1916:   route_set_ipv6_nexthop_global_free
                   1917: };
1.1.1.4 ! misho    1918: 
1.1       misho    1919: /* `set ipv6 nexthop local IP_ADDRESS' */
                   1920: 
                   1921: /* Set nexthop to object.  ojbect must be pointer to struct attr. */
                   1922: static route_map_result_t
                   1923: route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
                   1924:                              route_map_object_t type, void *object)
                   1925: {
                   1926:   struct in6_addr *address;
                   1927:   struct bgp_info *bgp_info;
                   1928: 
                   1929:   if (type == RMAP_BGP)
                   1930:     {
                   1931:       /* Fetch routemap's rule information. */
                   1932:       address = rule;
                   1933:       bgp_info = object;
                   1934:     
                   1935:       /* Set next hop value. */ 
                   1936:       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
                   1937:     
                   1938:       /* Set nexthop length. */
                   1939:       if (bgp_info->attr->extra->mp_nexthop_len != 32)
                   1940:        bgp_info->attr->extra->mp_nexthop_len = 32;
                   1941:     }
                   1942: 
                   1943:   return RMAP_OKAY;
                   1944: }
                   1945: 
                   1946: /* Route map `ip nexthop' compile function.  Given string is converted
                   1947:    to struct in_addr structure. */
                   1948: static void *
                   1949: route_set_ipv6_nexthop_local_compile (const char *arg)
                   1950: {
                   1951:   int ret;
                   1952:   struct in6_addr *address;
                   1953: 
                   1954:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
                   1955: 
                   1956:   ret = inet_pton (AF_INET6, arg, address);
                   1957: 
                   1958:   if (ret == 0)
                   1959:     {
                   1960:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
                   1961:       return NULL;
                   1962:     }
                   1963: 
                   1964:   return address;
                   1965: }
                   1966: 
                   1967: /* Free route map's compiled `ip nexthop' value. */
                   1968: static void
                   1969: route_set_ipv6_nexthop_local_free (void *rule)
                   1970: {
                   1971:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   1972: }
                   1973: 
                   1974: /* Route map commands for ip nexthop set. */
                   1975: struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
                   1976: {
                   1977:   "ipv6 next-hop local",
                   1978:   route_set_ipv6_nexthop_local,
                   1979:   route_set_ipv6_nexthop_local_compile,
                   1980:   route_set_ipv6_nexthop_local_free
                   1981: };
1.1.1.4 ! misho    1982: 
        !          1983: /* `set ipv6 nexthop peer-address' */
        !          1984: 
        !          1985: /* Set nexthop to object.  ojbect must be pointer to struct attr. */
        !          1986: static route_map_result_t
        !          1987: route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
        !          1988:                             route_map_object_t type, void *object)
        !          1989: {
        !          1990:   struct in6_addr peer_address;
        !          1991:   struct bgp_info *bgp_info;
        !          1992:   struct peer *peer;
        !          1993:   char peer_addr_buf[INET6_ADDRSTRLEN];
        !          1994: 
        !          1995:   if (type == RMAP_BGP)
        !          1996:     {
        !          1997:       /* Fetch routemap's rule information. */
        !          1998:       bgp_info = object;
        !          1999:       peer = bgp_info->peer;
        !          2000: 
        !          2001:       if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
        !          2002:            CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
        !          2003:          && peer->su_remote
        !          2004:          && sockunion_family (peer->su_remote) == AF_INET6)
        !          2005:        {
        !          2006:          inet_pton (AF_INET6, sockunion2str (peer->su_remote,
        !          2007:                                              peer_addr_buf,
        !          2008:                                              INET6_ADDRSTRLEN),
        !          2009:                     &peer_address);
        !          2010:        }
        !          2011:       else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
        !          2012:               && peer->su_local
        !          2013:               && sockunion_family (peer->su_local) == AF_INET6)
        !          2014:        {
        !          2015:          inet_pton (AF_INET, sockunion2str (peer->su_local,
        !          2016:                                             peer_addr_buf,
        !          2017:                                             INET6_ADDRSTRLEN),
        !          2018:                     &peer_address);
        !          2019:        }
        !          2020: 
        !          2021:       if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
        !          2022:        {
        !          2023:          /* Set next hop value. */
        !          2024:          (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
        !          2025: 
        !          2026:          /* Set nexthop length. */
        !          2027:          if (bgp_info->attr->extra->mp_nexthop_len != 32)
        !          2028:            bgp_info->attr->extra->mp_nexthop_len = 32;
        !          2029:        }
        !          2030:       else
        !          2031:        {
        !          2032:          /* Set next hop value. */
        !          2033:          (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
        !          2034: 
        !          2035:          /* Set nexthop length. */
        !          2036:          if (bgp_info->attr->extra->mp_nexthop_len == 0)
        !          2037:            bgp_info->attr->extra->mp_nexthop_len = 16;
        !          2038:        }
        !          2039:     }
        !          2040: 
        !          2041:   return RMAP_OKAY;
        !          2042: }
        !          2043: 
        !          2044: /* Route map `ip next-hop' compile function.  Given string is converted
        !          2045:    to struct in_addr structure. */
        !          2046: static void *
        !          2047: route_set_ipv6_nexthop_peer_compile (const char *arg)
        !          2048: {
        !          2049:   int *rins = NULL;
        !          2050: 
        !          2051:   rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
        !          2052:   *rins = 1;
        !          2053: 
        !          2054:   return rins;
        !          2055: }
        !          2056: 
        !          2057: /* Free route map's compiled `ip next-hop' value. */
        !          2058: static void
        !          2059: route_set_ipv6_nexthop_peer_free (void *rule)
        !          2060: {
        !          2061:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
        !          2062: }
        !          2063: 
        !          2064: /* Route map commands for ip nexthop set. */
        !          2065: struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
        !          2066: {
        !          2067:   "ipv6 next-hop peer-address",
        !          2068:   route_set_ipv6_nexthop_peer,
        !          2069:   route_set_ipv6_nexthop_peer_compile,
        !          2070:   route_set_ipv6_nexthop_peer_free
        !          2071: };
        !          2072: 
1.1       misho    2073: /* `set vpnv4 nexthop A.B.C.D' */
                   2074: 
                   2075: static route_map_result_t
                   2076: route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, 
                   2077:                         route_map_object_t type, void *object)
                   2078: {
                   2079:   struct in_addr *address;
                   2080:   struct bgp_info *bgp_info;
                   2081: 
                   2082:   if (type == RMAP_BGP)
                   2083:     {
                   2084:       /* Fetch routemap's rule information. */
                   2085:       address = rule;
                   2086:       bgp_info = object;
                   2087:     
                   2088:       /* Set next hop value. */ 
                   2089:       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
1.1.1.4 ! misho    2090:       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
1.1       misho    2091:     }
                   2092: 
                   2093:   return RMAP_OKAY;
                   2094: }
                   2095: 
                   2096: static void *
                   2097: route_set_vpnv4_nexthop_compile (const char *arg)
                   2098: {
                   2099:   int ret;
                   2100:   struct in_addr *address;
                   2101: 
                   2102:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
                   2103: 
                   2104:   ret = inet_aton (arg, address);
                   2105: 
                   2106:   if (ret == 0)
                   2107:     {
                   2108:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
                   2109:       return NULL;
                   2110:     }
                   2111: 
                   2112:   return address;
                   2113: }
                   2114: 
                   2115: static void
                   2116: route_set_vpnv4_nexthop_free (void *rule)
                   2117: {
                   2118:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   2119: }
                   2120: 
                   2121: /* Route map commands for ip nexthop set. */
                   2122: struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
                   2123: {
                   2124:   "vpnv4 next-hop",
                   2125:   route_set_vpnv4_nexthop,
                   2126:   route_set_vpnv4_nexthop_compile,
                   2127:   route_set_vpnv4_nexthop_free
                   2128: };
1.1.1.4 ! misho    2129: 
1.1       misho    2130: /* `set originator-id' */
                   2131: 
                   2132: /* For origin set. */
                   2133: static route_map_result_t
                   2134: route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
                   2135: {
                   2136:   struct in_addr *address;
                   2137:   struct bgp_info *bgp_info;
                   2138: 
                   2139:   if (type == RMAP_BGP) 
                   2140:     {
                   2141:       address = rule;
                   2142:       bgp_info = object;
                   2143:     
                   2144:       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
                   2145:       (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
                   2146:     }
                   2147: 
                   2148:   return RMAP_OKAY;
                   2149: }
                   2150: 
                   2151: /* Compile function for originator-id set. */
                   2152: static void *
                   2153: route_set_originator_id_compile (const char *arg)
                   2154: {
                   2155:   int ret;
                   2156:   struct in_addr *address;
                   2157: 
                   2158:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
                   2159: 
                   2160:   ret = inet_aton (arg, address);
                   2161: 
                   2162:   if (ret == 0)
                   2163:     {
                   2164:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
                   2165:       return NULL;
                   2166:     }
                   2167: 
                   2168:   return address;
                   2169: }
                   2170: 
                   2171: /* Compile function for originator_id set. */
                   2172: static void
                   2173: route_set_originator_id_free (void *rule)
                   2174: {
                   2175:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
                   2176: }
                   2177: 
1.1.1.4 ! misho    2178: /* Set originator-id rule structure. */
1.1       misho    2179: struct route_map_rule_cmd route_set_originator_id_cmd = 
                   2180: {
                   2181:   "originator-id",
                   2182:   route_set_originator_id,
                   2183:   route_set_originator_id_compile,
                   2184:   route_set_originator_id_free,
                   2185: };
1.1.1.4 ! misho    2186: 
1.1       misho    2187: /* Add bgp route map rule. */
                   2188: static int
                   2189: bgp_route_match_add (struct vty *vty, struct route_map_index *index,
                   2190:                     const char *command, const char *arg)
                   2191: {
                   2192:   int ret;
                   2193: 
                   2194:   ret = route_map_add_match (index, command, arg);
                   2195:   if (ret)
                   2196:     {
                   2197:       switch (ret)
                   2198:        {
                   2199:        case RMAP_RULE_MISSING:
                   2200:          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
                   2201:          return CMD_WARNING;
                   2202:        case RMAP_COMPILE_ERROR:
                   2203:          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
                   2204:          return CMD_WARNING;
                   2205:        }
                   2206:     }
                   2207:   return CMD_SUCCESS;
                   2208: }
                   2209: 
                   2210: /* Delete bgp route map rule. */
                   2211: static int
                   2212: bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
                   2213:                        const char *command, const char *arg)
                   2214: {
                   2215:   int ret;
                   2216: 
                   2217:   ret = route_map_delete_match (index, command, arg);
                   2218:   if (ret)
                   2219:     {
                   2220:       switch (ret)
                   2221:        {
                   2222:        case RMAP_RULE_MISSING:
                   2223:          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
                   2224:          return CMD_WARNING;
                   2225:        case RMAP_COMPILE_ERROR:
                   2226:          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
                   2227:          return CMD_WARNING;
                   2228:        }
                   2229:     }
                   2230:   return CMD_SUCCESS;
                   2231: }
                   2232: 
                   2233: /* Add bgp route map rule. */
                   2234: static int
                   2235: bgp_route_set_add (struct vty *vty, struct route_map_index *index,
                   2236:                   const char *command, const char *arg)
                   2237: {
                   2238:   int ret;
                   2239: 
                   2240:   ret = route_map_add_set (index, command, arg);
                   2241:   if (ret)
                   2242:     {
                   2243:       switch (ret)
                   2244:        {
                   2245:        case RMAP_RULE_MISSING:
                   2246:          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
                   2247:          return CMD_WARNING;
                   2248:        case RMAP_COMPILE_ERROR:
                   2249:          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
                   2250:          return CMD_WARNING;
                   2251:        }
                   2252:     }
                   2253:   return CMD_SUCCESS;
                   2254: }
                   2255: 
                   2256: /* Delete bgp route map rule. */
                   2257: static int
                   2258: bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
                   2259:                      const char *command, const char *arg)
                   2260: {
                   2261:   int ret;
                   2262: 
                   2263:   ret = route_map_delete_set (index, command, arg);
                   2264:   if (ret)
                   2265:     {
                   2266:       switch (ret)
                   2267:        {
                   2268:        case RMAP_RULE_MISSING:
                   2269:          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
                   2270:          return CMD_WARNING;
                   2271:        case RMAP_COMPILE_ERROR:
                   2272:          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
                   2273:          return CMD_WARNING;
                   2274:        }
                   2275:     }
                   2276:   return CMD_SUCCESS;
                   2277: }
                   2278: 
                   2279: /* Hook function for updating route_map assignment. */
                   2280: static void
                   2281: bgp_route_map_update (const char *unused)
                   2282: {
                   2283:   int i;
                   2284:   afi_t afi;
                   2285:   safi_t safi;
                   2286:   int direct;
                   2287:   struct listnode *node, *nnode;
                   2288:   struct listnode *mnode, *mnnode;
                   2289:   struct bgp *bgp;
                   2290:   struct peer *peer;
                   2291:   struct peer_group *group;
                   2292:   struct bgp_filter *filter;
                   2293:   struct bgp_node *bn;
                   2294:   struct bgp_static *bgp_static;
                   2295: 
1.1.1.4 ! misho    2296:   if (bm->bgp == NULL)          /* may be called during cleanup */
        !          2297:     return;
        !          2298: 
1.1       misho    2299:   /* For neighbor route-map updates. */
                   2300:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
                   2301:     {
                   2302:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
                   2303:        {
                   2304:          for (afi = AFI_IP; afi < AFI_MAX; afi++)
                   2305:            for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
                   2306:              {
                   2307:                filter = &peer->filter[afi][safi];
                   2308:          
                   2309:                for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
                   2310:                  {
                   2311:                    if (filter->map[direct].name)
                   2312:                      filter->map[direct].map = 
                   2313:                        route_map_lookup_by_name (filter->map[direct].name);
                   2314:                    else
                   2315:                      filter->map[direct].map = NULL;
                   2316:                  }
                   2317: 
                   2318:                if (filter->usmap.name)
                   2319:                  filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
                   2320:                else
                   2321:                  filter->usmap.map = NULL;
                   2322:              }
                   2323:        }
                   2324:       for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
                   2325:        {
                   2326:          for (afi = AFI_IP; afi < AFI_MAX; afi++)
                   2327:            for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
                   2328:              {
                   2329:                filter = &group->conf->filter[afi][safi];
                   2330:          
                   2331:                for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
                   2332:                  {
                   2333:                    if (filter->map[direct].name)
                   2334:                      filter->map[direct].map = 
                   2335:                        route_map_lookup_by_name (filter->map[direct].name);
                   2336:                    else
                   2337:                      filter->map[direct].map = NULL;
                   2338:                  }
                   2339: 
                   2340:                if (filter->usmap.name)
                   2341:                  filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
                   2342:                else
                   2343:                  filter->usmap.map = NULL;
                   2344:              }
                   2345:        }
                   2346:     }
                   2347: 
                   2348:   /* For default-originate route-map updates. */
                   2349:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
                   2350:     {
                   2351:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
                   2352:        {
                   2353:          for (afi = AFI_IP; afi < AFI_MAX; afi++)
                   2354:            for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
                   2355:              {
                   2356:                if (peer->default_rmap[afi][safi].name)
                   2357:                  peer->default_rmap[afi][safi].map =
                   2358:                    route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
                   2359:                else
                   2360:                  peer->default_rmap[afi][safi].map = NULL;
                   2361:              }
                   2362:        }
                   2363:     }
                   2364: 
                   2365:   /* For network route-map updates. */
                   2366:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
                   2367:     {
                   2368:       for (afi = AFI_IP; afi < AFI_MAX; afi++)
                   2369:        for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
                   2370:          for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
                   2371:               bn = bgp_route_next (bn))
                   2372:            if ((bgp_static = bn->info) != NULL)
                   2373:              {
                   2374:                if (bgp_static->rmap.name)
                   2375:                  bgp_static->rmap.map =
                   2376:                         route_map_lookup_by_name (bgp_static->rmap.name);
                   2377:                else
                   2378:                  bgp_static->rmap.map = NULL;
                   2379:              }
                   2380:     }
                   2381: 
                   2382:   /* For redistribute route-map updates. */
                   2383:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
                   2384:     {
                   2385:       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                   2386:        {
1.1.1.4 ! misho    2387:          if (bgp->rmap[AFI_IP][i].name)
        !          2388:            bgp->rmap[AFI_IP][i].map =
        !          2389:              route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
        !          2390:          if (bgp->rmap[AFI_IP6][i].name)
        !          2391:            bgp->rmap[AFI_IP6][i].map =
        !          2392:              route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
1.1       misho    2393:        }
                   2394:     }
                   2395: }
1.1.1.4 ! misho    2396: 
1.1       misho    2397: DEFUN (match_peer,
                   2398:        match_peer_cmd,
                   2399:        "match peer (A.B.C.D|X:X::X:X)",
                   2400:        MATCH_STR
                   2401:        "Match peer address\n"
                   2402:        "IPv6 address of peer\n"
                   2403:        "IP address of peer\n")
                   2404: {
                   2405:   return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
                   2406: }
                   2407: 
                   2408: DEFUN (match_peer_local,
                   2409:         match_peer_local_cmd,
                   2410:         "match peer local",
                   2411:         MATCH_STR
                   2412:         "Match peer address\n"
                   2413:         "Static or Redistributed routes\n")
                   2414: {
1.1.1.3   misho    2415:   return bgp_route_match_add (vty, vty->index, "peer", "local");
1.1       misho    2416: }
                   2417: 
                   2418: DEFUN (no_match_peer,
                   2419:        no_match_peer_cmd,
                   2420:        "no match peer",
                   2421:        NO_STR
                   2422:        MATCH_STR
                   2423:        "Match peer address\n")
                   2424: {
                   2425:  if (argc == 0)
                   2426:    return bgp_route_match_delete (vty, vty->index, "peer", NULL);
                   2427: 
                   2428:   return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
                   2429: }
                   2430: 
                   2431: ALIAS (no_match_peer,
                   2432:        no_match_peer_val_cmd,
                   2433:        "no match peer (A.B.C.D|X:X::X:X)",
                   2434:        NO_STR
                   2435:        MATCH_STR
                   2436:        "Match peer address\n"
                   2437:        "IPv6 address of peer\n"
                   2438:        "IP address of peer\n")
                   2439: 
                   2440: ALIAS (no_match_peer,
                   2441:        no_match_peer_local_cmd,
                   2442:        "no match peer local",
                   2443:        NO_STR
                   2444:        MATCH_STR
                   2445:        "Match peer address\n"
                   2446:        "Static or Redistributed routes\n")
                   2447: 
                   2448: DEFUN (match_ip_address, 
                   2449:        match_ip_address_cmd,
                   2450:        "match ip address (<1-199>|<1300-2699>|WORD)",
                   2451:        MATCH_STR
                   2452:        IP_STR
                   2453:        "Match address of route\n"
                   2454:        "IP access-list number\n"
                   2455:        "IP access-list number (expanded range)\n"
                   2456:        "IP Access-list name\n")
                   2457: {
                   2458:   return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
                   2459: }
                   2460: 
                   2461: DEFUN (no_match_ip_address, 
                   2462:        no_match_ip_address_cmd,
                   2463:        "no match ip address",
                   2464:        NO_STR
                   2465:        MATCH_STR
                   2466:        IP_STR
                   2467:        "Match address of route\n")
                   2468: {
                   2469:   if (argc == 0)
                   2470:     return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
                   2471: 
                   2472:   return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
                   2473: }
                   2474: 
                   2475: ALIAS (no_match_ip_address, 
                   2476:        no_match_ip_address_val_cmd,
                   2477:        "no match ip address (<1-199>|<1300-2699>|WORD)",
                   2478:        NO_STR
                   2479:        MATCH_STR
                   2480:        IP_STR
                   2481:        "Match address of route\n"
                   2482:        "IP access-list number\n"
                   2483:        "IP access-list number (expanded range)\n"
                   2484:        "IP Access-list name\n")
                   2485: 
                   2486: DEFUN (match_ip_next_hop, 
                   2487:        match_ip_next_hop_cmd,
                   2488:        "match ip next-hop (<1-199>|<1300-2699>|WORD)",
                   2489:        MATCH_STR
                   2490:        IP_STR
                   2491:        "Match next-hop address of route\n"
                   2492:        "IP access-list number\n"
                   2493:        "IP access-list number (expanded range)\n"
                   2494:        "IP Access-list name\n")
                   2495: {
                   2496:   return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
                   2497: }
                   2498: 
                   2499: DEFUN (no_match_ip_next_hop,
                   2500:        no_match_ip_next_hop_cmd,
                   2501:        "no match ip next-hop",
                   2502:        NO_STR
                   2503:        MATCH_STR
                   2504:        IP_STR
                   2505:        "Match next-hop address of route\n")
                   2506: {
                   2507:   if (argc == 0)
                   2508:     return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
                   2509: 
                   2510:   return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
                   2511: }
                   2512: 
                   2513: ALIAS (no_match_ip_next_hop,
                   2514:        no_match_ip_next_hop_val_cmd,
                   2515:        "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
                   2516:        NO_STR
                   2517:        MATCH_STR
                   2518:        IP_STR
                   2519:        "Match next-hop address of route\n"
                   2520:        "IP access-list number\n"
                   2521:        "IP access-list number (expanded range)\n"
                   2522:        "IP Access-list name\n")
                   2523: 
1.1.1.2   misho    2524: /* match probability { */
                   2525: 
                   2526: DEFUN (match_probability,
                   2527:        match_probability_cmd,
                   2528:        "match probability <0-100>",
                   2529:        MATCH_STR
                   2530:        "Match portion of routes defined by percentage value\n"
                   2531:        "Percentage of routes\n")
                   2532: {
                   2533:   return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
                   2534: }
                   2535: 
                   2536: DEFUN (no_match_probability,
                   2537:        no_match_probability_cmd,
                   2538:        "no match probability",
                   2539:        NO_STR
                   2540:        MATCH_STR
                   2541:        "Match portion of routes defined by percentage value\n")
                   2542: {
                   2543:   return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
                   2544: }
                   2545: 
                   2546: ALIAS (no_match_probability,
                   2547:        no_match_probability_val_cmd,
                   2548:        "no match probability <1-99>",
                   2549:        NO_STR
                   2550:        MATCH_STR
                   2551:        "Match portion of routes defined by percentage value\n"
                   2552:        "Percentage of routes\n")
                   2553: 
                   2554: /* } */
                   2555: 
1.1       misho    2556: DEFUN (match_ip_route_source, 
                   2557:        match_ip_route_source_cmd,
                   2558:        "match ip route-source (<1-199>|<1300-2699>|WORD)",
                   2559:        MATCH_STR
                   2560:        IP_STR
                   2561:        "Match advertising source address of route\n"
                   2562:        "IP access-list number\n"
                   2563:        "IP access-list number (expanded range)\n"
                   2564:        "IP standard access-list name\n")
                   2565: {
                   2566:   return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
                   2567: }
                   2568: 
                   2569: DEFUN (no_match_ip_route_source,
                   2570:        no_match_ip_route_source_cmd,
                   2571:        "no match ip route-source",
                   2572:        NO_STR
                   2573:        MATCH_STR
                   2574:        IP_STR
                   2575:        "Match advertising source address of route\n")
                   2576: {
                   2577:   if (argc == 0)
                   2578:     return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
                   2579: 
                   2580:   return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
                   2581: }
                   2582: 
                   2583: ALIAS (no_match_ip_route_source,
                   2584:        no_match_ip_route_source_val_cmd,
                   2585:        "no match ip route-source (<1-199>|<1300-2699>|WORD)",
                   2586:        NO_STR
                   2587:        MATCH_STR
                   2588:        IP_STR
                   2589:        "Match advertising source address of route\n"
                   2590:        "IP access-list number\n"
                   2591:        "IP access-list number (expanded range)\n"
                   2592:        "IP standard access-list name\n")
                   2593: 
                   2594: DEFUN (match_ip_address_prefix_list, 
                   2595:        match_ip_address_prefix_list_cmd,
                   2596:        "match ip address prefix-list WORD",
                   2597:        MATCH_STR
                   2598:        IP_STR
                   2599:        "Match address of route\n"
                   2600:        "Match entries of prefix-lists\n"
                   2601:        "IP prefix-list name\n")
                   2602: {
                   2603:   return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
                   2604: }
                   2605: 
                   2606: DEFUN (no_match_ip_address_prefix_list,
                   2607:        no_match_ip_address_prefix_list_cmd,
                   2608:        "no match ip address prefix-list",
                   2609:        NO_STR
                   2610:        MATCH_STR
                   2611:        IP_STR
                   2612:        "Match address of route\n"
                   2613:        "Match entries of prefix-lists\n")
                   2614: {
                   2615:   if (argc == 0)
                   2616:     return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
                   2617: 
                   2618:   return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
                   2619: }
                   2620: 
                   2621: ALIAS (no_match_ip_address_prefix_list,
                   2622:        no_match_ip_address_prefix_list_val_cmd,
                   2623:        "no match ip address prefix-list WORD",
                   2624:        NO_STR
                   2625:        MATCH_STR
                   2626:        IP_STR
                   2627:        "Match address of route\n"
                   2628:        "Match entries of prefix-lists\n"
                   2629:        "IP prefix-list name\n")
                   2630: 
                   2631: DEFUN (match_ip_next_hop_prefix_list, 
                   2632:        match_ip_next_hop_prefix_list_cmd,
                   2633:        "match ip next-hop prefix-list WORD",
                   2634:        MATCH_STR
                   2635:        IP_STR
                   2636:        "Match next-hop address of route\n"
                   2637:        "Match entries of prefix-lists\n"
                   2638:        "IP prefix-list name\n")
                   2639: {
                   2640:   return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
                   2641: }
                   2642: 
                   2643: DEFUN (no_match_ip_next_hop_prefix_list,
                   2644:        no_match_ip_next_hop_prefix_list_cmd,
                   2645:        "no match ip next-hop prefix-list",
                   2646:        NO_STR
                   2647:        MATCH_STR
                   2648:        IP_STR
                   2649:        "Match next-hop address of route\n"
                   2650:        "Match entries of prefix-lists\n")
                   2651: {
                   2652:   if (argc == 0)
                   2653:     return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
                   2654: 
                   2655:   return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
                   2656: }
                   2657: 
                   2658: ALIAS (no_match_ip_next_hop_prefix_list,
                   2659:        no_match_ip_next_hop_prefix_list_val_cmd,
                   2660:        "no match ip next-hop prefix-list WORD",
                   2661:        NO_STR
                   2662:        MATCH_STR
                   2663:        IP_STR
                   2664:        "Match next-hop address of route\n"
                   2665:        "Match entries of prefix-lists\n"
                   2666:        "IP prefix-list name\n")
                   2667: 
                   2668: DEFUN (match_ip_route_source_prefix_list, 
                   2669:        match_ip_route_source_prefix_list_cmd,
                   2670:        "match ip route-source prefix-list WORD",
                   2671:        MATCH_STR
                   2672:        IP_STR
                   2673:        "Match advertising source address of route\n"
                   2674:        "Match entries of prefix-lists\n"
                   2675:        "IP prefix-list name\n")
                   2676: {
                   2677:   return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
                   2678: }
                   2679: 
                   2680: DEFUN (no_match_ip_route_source_prefix_list,
                   2681:        no_match_ip_route_source_prefix_list_cmd,
                   2682:        "no match ip route-source prefix-list",
                   2683:        NO_STR
                   2684:        MATCH_STR
                   2685:        IP_STR
                   2686:        "Match advertising source address of route\n"
                   2687:        "Match entries of prefix-lists\n")
                   2688: {
                   2689:   if (argc == 0)
                   2690:     return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
                   2691: 
                   2692:   return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
                   2693: }
                   2694: 
                   2695: ALIAS (no_match_ip_route_source_prefix_list,
                   2696:        no_match_ip_route_source_prefix_list_val_cmd,
                   2697:        "no match ip route-source prefix-list WORD",
                   2698:        NO_STR
                   2699:        MATCH_STR
                   2700:        IP_STR
                   2701:        "Match advertising source address of route\n"
                   2702:        "Match entries of prefix-lists\n"
                   2703:        "IP prefix-list name\n")
                   2704: 
                   2705: DEFUN (match_metric, 
                   2706:        match_metric_cmd,
                   2707:        "match metric <0-4294967295>",
                   2708:        MATCH_STR
                   2709:        "Match metric of route\n"
                   2710:        "Metric value\n")
                   2711: {
                   2712:   return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
                   2713: }
                   2714: 
                   2715: DEFUN (no_match_metric,
                   2716:        no_match_metric_cmd,
                   2717:        "no match metric",
                   2718:        NO_STR
                   2719:        MATCH_STR
                   2720:        "Match metric of route\n")
                   2721: {
                   2722:   if (argc == 0)
                   2723:     return bgp_route_match_delete (vty, vty->index, "metric", NULL);
                   2724: 
                   2725:   return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
                   2726: }
                   2727: 
                   2728: ALIAS (no_match_metric,
                   2729:        no_match_metric_val_cmd,
                   2730:        "no match metric <0-4294967295>",
                   2731:        NO_STR
                   2732:        MATCH_STR
                   2733:        "Match metric of route\n"
                   2734:        "Metric value\n")
                   2735: 
                   2736: DEFUN (match_community, 
                   2737:        match_community_cmd,
                   2738:        "match community (<1-99>|<100-500>|WORD)",
                   2739:        MATCH_STR
                   2740:        "Match BGP community list\n"
                   2741:        "Community-list number (standard)\n"
                   2742:        "Community-list number (expanded)\n"
                   2743:        "Community-list name\n")
                   2744: {
                   2745:   return bgp_route_match_add (vty, vty->index, "community", argv[0]);
                   2746: }
                   2747: 
                   2748: DEFUN (match_community_exact, 
                   2749:        match_community_exact_cmd,
                   2750:        "match community (<1-99>|<100-500>|WORD) exact-match",
                   2751:        MATCH_STR
                   2752:        "Match BGP community list\n"
                   2753:        "Community-list number (standard)\n"
                   2754:        "Community-list number (expanded)\n"
                   2755:        "Community-list name\n"
                   2756:        "Do exact matching of communities\n")
                   2757: {
                   2758:   int ret;
                   2759:   char *argstr;
                   2760: 
                   2761:   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
                   2762:                    strlen (argv[0]) + strlen ("exact-match") + 2);
                   2763: 
                   2764:   sprintf (argstr, "%s exact-match", argv[0]);
                   2765: 
                   2766:   ret = bgp_route_match_add (vty, vty->index, "community", argstr);
                   2767: 
                   2768:   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
                   2769: 
                   2770:   return ret;
                   2771: }
                   2772: 
                   2773: DEFUN (no_match_community,
                   2774:        no_match_community_cmd,
                   2775:        "no match community",
                   2776:        NO_STR
                   2777:        MATCH_STR
                   2778:        "Match BGP community list\n")
                   2779: {
                   2780:   return bgp_route_match_delete (vty, vty->index, "community", NULL);
                   2781: }
                   2782: 
                   2783: ALIAS (no_match_community,
                   2784:        no_match_community_val_cmd,
                   2785:        "no match community (<1-99>|<100-500>|WORD)",
                   2786:        NO_STR
                   2787:        MATCH_STR
                   2788:        "Match BGP community list\n"
                   2789:        "Community-list number (standard)\n"
                   2790:        "Community-list number (expanded)\n"
                   2791:        "Community-list name\n")
                   2792: 
                   2793: ALIAS (no_match_community,
                   2794:        no_match_community_exact_cmd,
                   2795:        "no match community (<1-99>|<100-500>|WORD) exact-match",
                   2796:        NO_STR
                   2797:        MATCH_STR
                   2798:        "Match BGP community list\n"
                   2799:        "Community-list number (standard)\n"
                   2800:        "Community-list number (expanded)\n"
                   2801:        "Community-list name\n"
                   2802:        "Do exact matching of communities\n")
                   2803: 
                   2804: DEFUN (match_ecommunity, 
                   2805:        match_ecommunity_cmd,
                   2806:        "match extcommunity (<1-99>|<100-500>|WORD)",
                   2807:        MATCH_STR
                   2808:        "Match BGP/VPN extended community list\n"
                   2809:        "Extended community-list number (standard)\n"
                   2810:        "Extended community-list number (expanded)\n"
                   2811:        "Extended community-list name\n")
                   2812: {
                   2813:   return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
                   2814: }
                   2815: 
                   2816: DEFUN (no_match_ecommunity,
                   2817:        no_match_ecommunity_cmd,
                   2818:        "no match extcommunity",
                   2819:        NO_STR
                   2820:        MATCH_STR
                   2821:        "Match BGP/VPN extended community list\n")
                   2822: {
                   2823:   return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
                   2824: }
                   2825: 
                   2826: ALIAS (no_match_ecommunity,
                   2827:        no_match_ecommunity_val_cmd,
                   2828:        "no match extcommunity (<1-99>|<100-500>|WORD)",
                   2829:        NO_STR
                   2830:        MATCH_STR
                   2831:        "Match BGP/VPN extended community list\n"
                   2832:        "Extended community-list number (standard)\n"
                   2833:        "Extended community-list number (expanded)\n"
                   2834:        "Extended community-list name\n")
                   2835: 
                   2836: DEFUN (match_aspath,
                   2837:        match_aspath_cmd,
                   2838:        "match as-path WORD",
                   2839:        MATCH_STR
                   2840:        "Match BGP AS path list\n"
                   2841:        "AS path access-list name\n")
                   2842: {
                   2843:   return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
                   2844: }
                   2845: 
                   2846: DEFUN (no_match_aspath,
                   2847:        no_match_aspath_cmd,
                   2848:        "no match as-path",
                   2849:        NO_STR
                   2850:        MATCH_STR
                   2851:        "Match BGP AS path list\n")
                   2852: {
                   2853:   return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
                   2854: }
                   2855: 
                   2856: ALIAS (no_match_aspath,
                   2857:        no_match_aspath_val_cmd,
                   2858:        "no match as-path WORD",
                   2859:        NO_STR
                   2860:        MATCH_STR
                   2861:        "Match BGP AS path list\n"
                   2862:        "AS path access-list name\n")
                   2863: 
                   2864: DEFUN (match_origin,
                   2865:        match_origin_cmd,
                   2866:        "match origin (egp|igp|incomplete)",
                   2867:        MATCH_STR
                   2868:        "BGP origin code\n"
                   2869:        "remote EGP\n"
                   2870:        "local IGP\n"
                   2871:        "unknown heritage\n")
                   2872: {
                   2873:   if (strncmp (argv[0], "igp", 2) == 0)
                   2874:     return bgp_route_match_add (vty, vty->index, "origin", "igp");
                   2875:   if (strncmp (argv[0], "egp", 1) == 0)
                   2876:     return bgp_route_match_add (vty, vty->index, "origin", "egp");
                   2877:   if (strncmp (argv[0], "incomplete", 2) == 0)
                   2878:     return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
                   2879: 
                   2880:   return CMD_WARNING;
                   2881: }
                   2882: 
                   2883: DEFUN (no_match_origin,
                   2884:        no_match_origin_cmd,
                   2885:        "no match origin",
                   2886:        NO_STR
                   2887:        MATCH_STR
                   2888:        "BGP origin code\n")
                   2889: {
                   2890:   return bgp_route_match_delete (vty, vty->index, "origin", NULL);
                   2891: }
                   2892: 
                   2893: ALIAS (no_match_origin,
                   2894:        no_match_origin_val_cmd,
                   2895:        "no match origin (egp|igp|incomplete)",
                   2896:        NO_STR
                   2897:        MATCH_STR
                   2898:        "BGP origin code\n"
                   2899:        "remote EGP\n"
                   2900:        "local IGP\n"
                   2901:        "unknown heritage\n")
                   2902: 
                   2903: DEFUN (set_ip_nexthop,
                   2904:        set_ip_nexthop_cmd,
                   2905:        "set ip next-hop A.B.C.D",
                   2906:        SET_STR
                   2907:        IP_STR
                   2908:        "Next hop address\n"
                   2909:        "IP address of next hop\n")
                   2910: {
                   2911:   union sockunion su;
                   2912:   int ret;
                   2913: 
                   2914:   ret = str2sockunion (argv[0], &su);
                   2915:   if (ret < 0)
                   2916:     {
                   2917:       vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
                   2918:       return CMD_WARNING;
                   2919:     }
                   2920:  
                   2921:   return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
                   2922: }
                   2923: 
                   2924: DEFUN (set_ip_nexthop_peer,
                   2925:        set_ip_nexthop_peer_cmd,
                   2926:        "set ip next-hop peer-address",
                   2927:        SET_STR
                   2928:        IP_STR
                   2929:        "Next hop address\n"
                   2930:        "Use peer address (for BGP only)\n")
                   2931: {
                   2932:   return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
                   2933: }
                   2934: 
                   2935: DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
                   2936:        no_set_ip_nexthop_peer_cmd,
                   2937:        "no set ip next-hop peer-address",
                   2938:        NO_STR
                   2939:        SET_STR
                   2940:        IP_STR
                   2941:        "Next hop address\n"
                   2942:        "Use peer address (for BGP only)\n")
                   2943: {
                   2944:   return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
                   2945: }
                   2946: 
                   2947: 
                   2948: DEFUN (no_set_ip_nexthop,
                   2949:        no_set_ip_nexthop_cmd,
                   2950:        "no set ip next-hop",
                   2951:        NO_STR
                   2952:        SET_STR
                   2953:        "Next hop address\n")
                   2954: {
                   2955:   if (argc == 0)
                   2956:     return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
                   2957: 
                   2958:   return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
                   2959: }
                   2960: 
                   2961: ALIAS (no_set_ip_nexthop,
                   2962:        no_set_ip_nexthop_val_cmd,
                   2963:        "no set ip next-hop A.B.C.D",
                   2964:        NO_STR
                   2965:        SET_STR
                   2966:        IP_STR
                   2967:        "Next hop address\n"
                   2968:        "IP address of next hop\n")
                   2969: 
                   2970: DEFUN (set_metric,
                   2971:        set_metric_cmd,
                   2972:        "set metric <0-4294967295>",
                   2973:        SET_STR
                   2974:        "Metric value for destination routing protocol\n"
                   2975:        "Metric value\n")
                   2976: {
                   2977:   return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
                   2978: }
                   2979: 
                   2980: ALIAS (set_metric,
                   2981:        set_metric_addsub_cmd,
                   2982:        "set metric <+/-metric>",
                   2983:        SET_STR
                   2984:        "Metric value for destination routing protocol\n"
                   2985:        "Add or subtract metric\n")
                   2986: 
1.1.1.4 ! misho    2987: ALIAS (set_metric,
        !          2988:        set_metric_rtt_cmd,
        !          2989:        "set metric (rtt|+rtt|-rtt)",
        !          2990:        SET_STR
        !          2991:        "Metric value for destination routing protocol\n"
        !          2992:        "Assign round trip time\n"
        !          2993:        "Add round trip time\n"
        !          2994:        "Subtract round trip time\n")
        !          2995: 
1.1       misho    2996: DEFUN (no_set_metric,
                   2997:        no_set_metric_cmd,
                   2998:        "no set metric",
                   2999:        NO_STR
                   3000:        SET_STR
                   3001:        "Metric value for destination routing protocol\n")
                   3002: {
                   3003:   if (argc == 0)
                   3004:     return bgp_route_set_delete (vty, vty->index, "metric", NULL);
                   3005: 
                   3006:   return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
                   3007: }
                   3008: 
                   3009: ALIAS (no_set_metric,
                   3010:        no_set_metric_val_cmd,
                   3011:        "no set metric <0-4294967295>",
                   3012:        NO_STR
                   3013:        SET_STR
                   3014:        "Metric value for destination routing protocol\n"
                   3015:        "Metric value\n")
                   3016: 
                   3017: DEFUN (set_local_pref,
                   3018:        set_local_pref_cmd,
                   3019:        "set local-preference <0-4294967295>",
                   3020:        SET_STR
                   3021:        "BGP local preference path attribute\n"
                   3022:        "Preference value\n")
                   3023: {
                   3024:   return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
                   3025: }
                   3026: 
                   3027: DEFUN (no_set_local_pref,
                   3028:        no_set_local_pref_cmd,
                   3029:        "no set local-preference",
                   3030:        NO_STR
                   3031:        SET_STR
                   3032:        "BGP local preference path attribute\n")
                   3033: {
                   3034:   if (argc == 0)
                   3035:     return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
                   3036: 
                   3037:   return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
                   3038: }
                   3039: 
                   3040: ALIAS (no_set_local_pref,
                   3041:        no_set_local_pref_val_cmd,
                   3042:        "no set local-preference <0-4294967295>",
                   3043:        NO_STR
                   3044:        SET_STR
                   3045:        "BGP local preference path attribute\n"
                   3046:        "Preference value\n")
                   3047: 
                   3048: DEFUN (set_weight,
                   3049:        set_weight_cmd,
                   3050:        "set weight <0-4294967295>",
                   3051:        SET_STR
                   3052:        "BGP weight for routing table\n"
                   3053:        "Weight value\n")
                   3054: {
                   3055:   return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
                   3056: }
                   3057: 
                   3058: DEFUN (no_set_weight,
                   3059:        no_set_weight_cmd,
                   3060:        "no set weight",
                   3061:        NO_STR
                   3062:        SET_STR
                   3063:        "BGP weight for routing table\n")
                   3064: {
                   3065:   if (argc == 0)
                   3066:     return bgp_route_set_delete (vty, vty->index, "weight", NULL);
                   3067:   
                   3068:   return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
                   3069: }
                   3070: 
                   3071: ALIAS (no_set_weight,
                   3072:        no_set_weight_val_cmd,
                   3073:        "no set weight <0-4294967295>",
                   3074:        NO_STR
                   3075:        SET_STR
                   3076:        "BGP weight for routing table\n"
                   3077:        "Weight value\n")
                   3078: 
                   3079: DEFUN (set_aspath_prepend,
                   3080:        set_aspath_prepend_cmd,
                   3081:        "set as-path prepend ." CMD_AS_RANGE,
                   3082:        SET_STR
                   3083:        "Transform BGP AS_PATH attribute\n"
                   3084:        "Prepend to the as-path\n"
                   3085:        "AS number\n")
                   3086: {
                   3087:   int ret;
                   3088:   char *str;
                   3089: 
                   3090:   str = argv_concat (argv, argc, 0);
                   3091:   ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
                   3092:   XFREE (MTYPE_TMP, str);
                   3093: 
                   3094:   return ret;
                   3095: }
                   3096: 
1.1.1.4 ! misho    3097: ALIAS (set_aspath_prepend,
        !          3098:        set_aspath_prepend_lastas_cmd,
        !          3099:        "set as-path prepend (last-as) <1-10>",
        !          3100:        SET_STR
        !          3101:        "Transform BGP AS_PATH attribute\n"
        !          3102:        "Prepend to the as-path\n"
        !          3103:        "Use the peer's AS-number\n"
        !          3104:        "Number of times to insert")
        !          3105: 
1.1       misho    3106: DEFUN (no_set_aspath_prepend,
                   3107:        no_set_aspath_prepend_cmd,
                   3108:        "no set as-path prepend",
                   3109:        NO_STR
                   3110:        SET_STR
                   3111:        "Transform BGP AS_PATH attribute\n"
                   3112:        "Prepend to the as-path\n")
                   3113: {
                   3114:   int ret;
                   3115:   char *str;
                   3116: 
                   3117:   if (argc == 0)
                   3118:     return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
                   3119: 
                   3120:   str = argv_concat (argv, argc, 0);
                   3121:   ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
                   3122:   XFREE (MTYPE_TMP, str);
                   3123:   return ret;
                   3124: }
                   3125: 
                   3126: ALIAS (no_set_aspath_prepend,
                   3127:        no_set_aspath_prepend_val_cmd,
                   3128:        "no set as-path prepend ." CMD_AS_RANGE,
                   3129:        NO_STR
                   3130:        SET_STR
                   3131:        "Transform BGP AS_PATH attribute\n"
                   3132:        "Prepend to the as-path\n"
                   3133:        "AS number\n")
                   3134: 
                   3135: DEFUN (set_aspath_exclude,
                   3136:        set_aspath_exclude_cmd,
                   3137:        "set as-path exclude ." CMD_AS_RANGE,
                   3138:        SET_STR
                   3139:        "Transform BGP AS-path attribute\n"
                   3140:        "Exclude from the as-path\n"
                   3141:        "AS number\n")
                   3142: {
                   3143:   int ret;
                   3144:   char *str;
                   3145: 
                   3146:   str = argv_concat (argv, argc, 0);
                   3147:   ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
                   3148:   XFREE (MTYPE_TMP, str);
                   3149:   return ret;
                   3150: }
                   3151: 
                   3152: DEFUN (no_set_aspath_exclude,
                   3153:        no_set_aspath_exclude_cmd,
                   3154:        "no set as-path exclude",
                   3155:        NO_STR
                   3156:        SET_STR
                   3157:        "Transform BGP AS_PATH attribute\n"
                   3158:        "Exclude from the as-path\n")
                   3159: {
                   3160:   int ret;
                   3161:   char *str;
                   3162: 
                   3163:   if (argc == 0)
                   3164:     return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
                   3165: 
                   3166:   str = argv_concat (argv, argc, 0);
                   3167:   ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
                   3168:   XFREE (MTYPE_TMP, str);
                   3169:   return ret;
                   3170: }
                   3171: 
                   3172: ALIAS (no_set_aspath_exclude,
                   3173:        no_set_aspath_exclude_val_cmd,
                   3174:        "no set as-path exclude ." CMD_AS_RANGE,
                   3175:        NO_STR
                   3176:        SET_STR
                   3177:        "Transform BGP AS_PATH attribute\n"
                   3178:        "Exclude from the as-path\n"
                   3179:        "AS number\n")
                   3180: 
                   3181: DEFUN (set_community,
                   3182:        set_community_cmd,
                   3183:        "set community .AA:NN",
                   3184:        SET_STR
                   3185:        "BGP community attribute\n"
                   3186:        "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
                   3187: {
                   3188:   int i;
                   3189:   int first = 0;
                   3190:   int additive = 0;
                   3191:   struct buffer *b;
                   3192:   struct community *com = NULL;
                   3193:   char *str;
                   3194:   char *argstr;
                   3195:   int ret;
                   3196: 
                   3197:   b = buffer_new (1024);
                   3198: 
                   3199:   for (i = 0; i < argc; i++)
                   3200:     {
                   3201:       if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
                   3202:        {
                   3203:          additive = 1;
                   3204:          continue;
                   3205:        }
                   3206: 
                   3207:       if (first)
                   3208:        buffer_putc (b, ' ');
                   3209:       else
                   3210:        first = 1;
                   3211: 
                   3212:       if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
                   3213:        {
                   3214:          buffer_putstr (b, "internet");
                   3215:          continue;
                   3216:        }
                   3217:       if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
                   3218:        {
                   3219:          buffer_putstr (b, "local-AS");
                   3220:          continue;
                   3221:        }
                   3222:       if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
                   3223:          && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
                   3224:        {
                   3225:          buffer_putstr (b, "no-advertise");
                   3226:          continue;
                   3227:        }
                   3228:       if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
                   3229:          && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
                   3230:        {
                   3231:          buffer_putstr (b, "no-export");
                   3232:          continue;
                   3233:        }
                   3234:       buffer_putstr (b, argv[i]);
                   3235:     }
                   3236:   buffer_putc (b, '\0');
                   3237: 
                   3238:   /* Fetch result string then compile it to communities attribute.  */
                   3239:   str = buffer_getstr (b);
                   3240:   buffer_free (b);
                   3241: 
                   3242:   if (str)
                   3243:     {
                   3244:       com = community_str2com (str);
                   3245:       XFREE (MTYPE_TMP, str);
                   3246:     }
                   3247: 
                   3248:   /* Can't compile user input into communities attribute.  */
                   3249:   if (! com)
                   3250:     {
                   3251:       vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
                   3252:       return CMD_WARNING;
                   3253:     }
                   3254: 
                   3255:   /* Set communites attribute string.  */
                   3256:   str = community_str (com);
                   3257: 
                   3258:   if (additive)
                   3259:     {
                   3260:       argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
                   3261:       strcpy (argstr, str);
                   3262:       strcpy (argstr + strlen (str), " additive");
                   3263:       ret =  bgp_route_set_add (vty, vty->index, "community", argstr);
                   3264:       XFREE (MTYPE_TMP, argstr);
                   3265:     }
                   3266:   else
                   3267:     ret =  bgp_route_set_add (vty, vty->index, "community", str);
                   3268: 
                   3269:   community_free (com);
                   3270: 
                   3271:   return ret;
                   3272: }
                   3273: 
                   3274: DEFUN (set_community_none,
                   3275:        set_community_none_cmd,
                   3276:        "set community none",
                   3277:        SET_STR
                   3278:        "BGP community attribute\n"
                   3279:        "No community attribute\n")
                   3280: {
                   3281:   return bgp_route_set_add (vty, vty->index, "community", "none");
                   3282: }
                   3283: 
                   3284: DEFUN (no_set_community,
                   3285:        no_set_community_cmd,
                   3286:        "no set community",
                   3287:        NO_STR
                   3288:        SET_STR
                   3289:        "BGP community attribute\n")
                   3290: {
                   3291:   return bgp_route_set_delete (vty, vty->index, "community", NULL);
                   3292: }
                   3293: 
                   3294: ALIAS (no_set_community,
                   3295:        no_set_community_val_cmd,
                   3296:        "no set community .AA:NN",
                   3297:        NO_STR
                   3298:        SET_STR
                   3299:        "BGP community attribute\n"
                   3300:        "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
                   3301: 
                   3302: ALIAS (no_set_community,
                   3303:        no_set_community_none_cmd,
                   3304:        "no set community none",
                   3305:        NO_STR
                   3306:        SET_STR
                   3307:        "BGP community attribute\n"
                   3308:        "No community attribute\n")
                   3309: 
                   3310: DEFUN (set_community_delete,
                   3311:        set_community_delete_cmd,
                   3312:        "set comm-list (<1-99>|<100-500>|WORD) delete",
                   3313:        SET_STR
                   3314:        "set BGP community list (for deletion)\n"
                   3315:        "Community-list number (standard)\n"
                   3316:        "Communitly-list number (expanded)\n"
                   3317:        "Community-list name\n"
                   3318:        "Delete matching communities\n")
                   3319: {
                   3320:   char *str;
                   3321: 
                   3322:   str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
                   3323:   strcpy (str, argv[0]);
                   3324:   strcpy (str + strlen (argv[0]), " delete");
                   3325: 
                   3326:   bgp_route_set_add (vty, vty->index, "comm-list", str);
                   3327: 
                   3328:   XFREE (MTYPE_TMP, str);
                   3329:   return CMD_SUCCESS;
                   3330: }
                   3331: 
                   3332: DEFUN (no_set_community_delete,
                   3333:        no_set_community_delete_cmd,
                   3334:        "no set comm-list",
                   3335:        NO_STR
                   3336:        SET_STR
                   3337:        "set BGP community list (for deletion)\n")
                   3338: {
                   3339:   return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
                   3340: }
                   3341: 
                   3342: ALIAS (no_set_community_delete,
                   3343:        no_set_community_delete_val_cmd,
                   3344:        "no set comm-list (<1-99>|<100-500>|WORD) delete",
                   3345:        NO_STR
                   3346:        SET_STR
                   3347:        "set BGP community list (for deletion)\n"
                   3348:        "Community-list number (standard)\n"
                   3349:        "Communitly-list number (expanded)\n"
                   3350:        "Community-list name\n"
                   3351:        "Delete matching communities\n")
                   3352: 
                   3353: DEFUN (set_ecommunity_rt,
                   3354:        set_ecommunity_rt_cmd,
                   3355:        "set extcommunity rt .ASN:nn_or_IP-address:nn",
                   3356:        SET_STR
                   3357:        "BGP extended community attribute\n"
                   3358:        "Route Target extended community\n"
                   3359:        "VPN extended community\n")
                   3360: {
                   3361:   int ret;
                   3362:   char *str;
                   3363: 
                   3364:   str = argv_concat (argv, argc, 0);
                   3365:   ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
                   3366:   XFREE (MTYPE_TMP, str);
                   3367: 
                   3368:   return ret;
                   3369: }
                   3370: 
                   3371: DEFUN (no_set_ecommunity_rt,
                   3372:        no_set_ecommunity_rt_cmd,
                   3373:        "no set extcommunity rt",
                   3374:        NO_STR
                   3375:        SET_STR
                   3376:        "BGP extended community attribute\n"
                   3377:        "Route Target extended community\n")
                   3378: {
                   3379:   return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
                   3380: }
                   3381: 
                   3382: ALIAS (no_set_ecommunity_rt,
                   3383:        no_set_ecommunity_rt_val_cmd,
                   3384:        "no set extcommunity rt .ASN:nn_or_IP-address:nn",
                   3385:        NO_STR
                   3386:        SET_STR
                   3387:        "BGP extended community attribute\n"
                   3388:        "Route Target extended community\n"
                   3389:        "VPN extended community\n")
                   3390: 
                   3391: DEFUN (set_ecommunity_soo,
                   3392:        set_ecommunity_soo_cmd,
                   3393:        "set extcommunity soo .ASN:nn_or_IP-address:nn",
                   3394:        SET_STR
                   3395:        "BGP extended community attribute\n"
                   3396:        "Site-of-Origin extended community\n"
                   3397:        "VPN extended community\n")
                   3398: {
                   3399:   int ret;
                   3400:   char *str;
                   3401: 
                   3402:   str = argv_concat (argv, argc, 0);
                   3403:   ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
                   3404:   XFREE (MTYPE_TMP, str);
                   3405:   return ret;
                   3406: }
                   3407: 
                   3408: DEFUN (no_set_ecommunity_soo,
                   3409:        no_set_ecommunity_soo_cmd,
                   3410:        "no set extcommunity soo",
                   3411:        NO_STR
                   3412:        SET_STR
                   3413:        "BGP extended community attribute\n"
                   3414:        "Site-of-Origin extended community\n")
                   3415: {
                   3416:   return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
                   3417: }
                   3418: 
                   3419: ALIAS (no_set_ecommunity_soo,
                   3420:        no_set_ecommunity_soo_val_cmd,
                   3421:        "no set extcommunity soo .ASN:nn_or_IP-address:nn",
                   3422:        NO_STR
                   3423:        SET_STR
                   3424:        "BGP extended community attribute\n"
                   3425:        "Site-of-Origin extended community\n"
                   3426:        "VPN extended community\n")
                   3427: 
                   3428: DEFUN (set_origin,
                   3429:        set_origin_cmd,
                   3430:        "set origin (egp|igp|incomplete)",
                   3431:        SET_STR
                   3432:        "BGP origin code\n"
                   3433:        "remote EGP\n"
                   3434:        "local IGP\n"
                   3435:        "unknown heritage\n")
                   3436: {
                   3437:   if (strncmp (argv[0], "igp", 2) == 0)
                   3438:     return bgp_route_set_add (vty, vty->index, "origin", "igp");
                   3439:   if (strncmp (argv[0], "egp", 1) == 0)
                   3440:     return bgp_route_set_add (vty, vty->index, "origin", "egp");
                   3441:   if (strncmp (argv[0], "incomplete", 2) == 0)
                   3442:     return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
                   3443: 
                   3444:   return CMD_WARNING;
                   3445: }
                   3446: 
                   3447: DEFUN (no_set_origin,
                   3448:        no_set_origin_cmd,
                   3449:        "no set origin",
                   3450:        NO_STR
                   3451:        SET_STR
                   3452:        "BGP origin code\n")
                   3453: {
                   3454:   return bgp_route_set_delete (vty, vty->index, "origin", NULL);
                   3455: }
                   3456: 
                   3457: ALIAS (no_set_origin,
                   3458:        no_set_origin_val_cmd,
                   3459:        "no set origin (egp|igp|incomplete)",
                   3460:        NO_STR
                   3461:        SET_STR
                   3462:        "BGP origin code\n"
                   3463:        "remote EGP\n"
                   3464:        "local IGP\n"
                   3465:        "unknown heritage\n")
                   3466: 
                   3467: DEFUN (set_atomic_aggregate,
                   3468:        set_atomic_aggregate_cmd,
                   3469:        "set atomic-aggregate",
                   3470:        SET_STR
                   3471:        "BGP atomic aggregate attribute\n" )
                   3472: {
                   3473:   return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
                   3474: }
                   3475: 
                   3476: DEFUN (no_set_atomic_aggregate,
                   3477:        no_set_atomic_aggregate_cmd,
                   3478:        "no set atomic-aggregate",
                   3479:        NO_STR
                   3480:        SET_STR
                   3481:        "BGP atomic aggregate attribute\n" )
                   3482: {
                   3483:   return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
                   3484: }
                   3485: 
                   3486: DEFUN (set_aggregator_as,
                   3487:        set_aggregator_as_cmd,
                   3488:        "set aggregator as " CMD_AS_RANGE " A.B.C.D",
                   3489:        SET_STR
                   3490:        "BGP aggregator attribute\n"
                   3491:        "AS number of aggregator\n"
                   3492:        "AS number\n"
                   3493:        "IP address of aggregator\n")
                   3494: {
                   3495:   int ret;
1.1.1.4 ! misho    3496:   as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
1.1       misho    3497:   struct in_addr address;
                   3498:   char *argstr;
                   3499: 
                   3500:   VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
                   3501:   
                   3502:   ret = inet_aton (argv[1], &address);
                   3503:   if (ret == 0)
                   3504:     {
                   3505:       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
                   3506:       return CMD_WARNING;
                   3507:     }
                   3508: 
                   3509:   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
                   3510:                    strlen (argv[0]) + strlen (argv[1]) + 2);
                   3511: 
                   3512:   sprintf (argstr, "%s %s", argv[0], argv[1]);
                   3513: 
                   3514:   ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
                   3515: 
                   3516:   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
                   3517: 
                   3518:   return ret;
                   3519: }
                   3520: 
                   3521: DEFUN (no_set_aggregator_as,
                   3522:        no_set_aggregator_as_cmd,
                   3523:        "no set aggregator as",
                   3524:        NO_STR
                   3525:        SET_STR
                   3526:        "BGP aggregator attribute\n"
                   3527:        "AS number of aggregator\n")
                   3528: {
                   3529:   int ret;
1.1.1.4 ! misho    3530:   as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
1.1       misho    3531:   struct in_addr address;
                   3532:   char *argstr;
                   3533: 
                   3534:   if (argv == 0)
                   3535:     return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
                   3536:   
                   3537:   VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
                   3538: 
                   3539:   ret = inet_aton (argv[1], &address);
                   3540:   if (ret == 0)
                   3541:     {
                   3542:       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
                   3543:       return CMD_WARNING;
                   3544:     }
                   3545: 
                   3546:   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
                   3547:                    strlen (argv[0]) + strlen (argv[1]) + 2);
                   3548: 
                   3549:   sprintf (argstr, "%s %s", argv[0], argv[1]);
                   3550: 
                   3551:   ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
                   3552: 
                   3553:   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
                   3554: 
                   3555:   return ret;
                   3556: }
                   3557: 
                   3558: ALIAS (no_set_aggregator_as,
                   3559:        no_set_aggregator_as_val_cmd,
                   3560:        "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
                   3561:        NO_STR
                   3562:        SET_STR
                   3563:        "BGP aggregator attribute\n"
                   3564:        "AS number of aggregator\n"
                   3565:        "AS number\n"
                   3566:        "IP address of aggregator\n")
                   3567: 
                   3568: DEFUN (match_ipv6_address, 
                   3569:        match_ipv6_address_cmd,
                   3570:        "match ipv6 address WORD",
                   3571:        MATCH_STR
                   3572:        IPV6_STR
                   3573:        "Match IPv6 address of route\n"
                   3574:        "IPv6 access-list name\n")
                   3575: {
                   3576:   return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
                   3577: }
                   3578: 
                   3579: DEFUN (no_match_ipv6_address, 
                   3580:        no_match_ipv6_address_cmd,
                   3581:        "no match ipv6 address WORD",
                   3582:        NO_STR
                   3583:        MATCH_STR
                   3584:        IPV6_STR
                   3585:        "Match IPv6 address of route\n"
                   3586:        "IPv6 access-list name\n")
                   3587: {
                   3588:   return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
                   3589: }
                   3590: 
                   3591: DEFUN (match_ipv6_next_hop, 
                   3592:        match_ipv6_next_hop_cmd,
                   3593:        "match ipv6 next-hop X:X::X:X",
                   3594:        MATCH_STR
                   3595:        IPV6_STR
                   3596:        "Match IPv6 next-hop address of route\n"
                   3597:        "IPv6 address of next hop\n")
                   3598: {
                   3599:   return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
                   3600: }
                   3601: 
                   3602: DEFUN (no_match_ipv6_next_hop,
                   3603:        no_match_ipv6_next_hop_cmd,
                   3604:        "no match ipv6 next-hop X:X::X:X",
                   3605:        NO_STR
                   3606:        MATCH_STR
                   3607:        IPV6_STR
                   3608:        "Match IPv6 next-hop address of route\n"
                   3609:        "IPv6 address of next hop\n")
                   3610: {
                   3611:   return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
                   3612: }
                   3613: 
                   3614: DEFUN (match_ipv6_address_prefix_list, 
                   3615:        match_ipv6_address_prefix_list_cmd,
                   3616:        "match ipv6 address prefix-list WORD",
                   3617:        MATCH_STR
                   3618:        IPV6_STR
                   3619:        "Match address of route\n"
                   3620:        "Match entries of prefix-lists\n"
                   3621:        "IP prefix-list name\n")
                   3622: {
                   3623:   return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
                   3624: }
                   3625: 
                   3626: DEFUN (no_match_ipv6_address_prefix_list,
                   3627:        no_match_ipv6_address_prefix_list_cmd,
                   3628:        "no match ipv6 address prefix-list WORD",
                   3629:        NO_STR
                   3630:        MATCH_STR
                   3631:        IPV6_STR
                   3632:        "Match address of route\n"
                   3633:        "Match entries of prefix-lists\n"
                   3634:        "IP prefix-list name\n")
                   3635: {
                   3636:   return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
                   3637: }
                   3638: 
1.1.1.4 ! misho    3639: DEFUN (set_ipv6_nexthop_peer,
        !          3640:        set_ipv6_nexthop_peer_cmd,
        !          3641:        "set ipv6 next-hop peer-address",
        !          3642:        SET_STR
        !          3643:        IPV6_STR
        !          3644:        "Next hop address\n"
        !          3645:        "Use peer address (for BGP only)\n")
        !          3646: {
        !          3647:   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
        !          3648: }
        !          3649: 
        !          3650: DEFUN (no_set_ipv6_nexthop_peer,
        !          3651:        no_set_ipv6_nexthop_peer_cmd,
        !          3652:        "no set ipv6 next-hop peer-address",
        !          3653:        NO_STR
        !          3654:        SET_STR
        !          3655:        IPV6_STR
        !          3656:        "IPv6 next-hop address\n"
        !          3657:        )
        !          3658: {
        !          3659:   return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
        !          3660: }
        !          3661: 
1.1       misho    3662: DEFUN (set_ipv6_nexthop_global,
                   3663:        set_ipv6_nexthop_global_cmd,
                   3664:        "set ipv6 next-hop global X:X::X:X",
                   3665:        SET_STR
                   3666:        IPV6_STR
                   3667:        "IPv6 next-hop address\n"
                   3668:        "IPv6 global address\n"
                   3669:        "IPv6 address of next hop\n")
                   3670: {
                   3671:   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
                   3672: }
                   3673: 
                   3674: DEFUN (no_set_ipv6_nexthop_global,
                   3675:        no_set_ipv6_nexthop_global_cmd,
                   3676:        "no set ipv6 next-hop global",
                   3677:        NO_STR
                   3678:        SET_STR
                   3679:        IPV6_STR
                   3680:        "IPv6 next-hop address\n"
                   3681:        "IPv6 global address\n")
                   3682: {
                   3683:   if (argc == 0)
                   3684:     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
                   3685: 
                   3686:   return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
                   3687: }
                   3688: 
                   3689: ALIAS (no_set_ipv6_nexthop_global,
                   3690:        no_set_ipv6_nexthop_global_val_cmd,
                   3691:        "no set ipv6 next-hop global X:X::X:X",
                   3692:        NO_STR
                   3693:        SET_STR
                   3694:        IPV6_STR
                   3695:        "IPv6 next-hop address\n"
                   3696:        "IPv6 global address\n"
                   3697:        "IPv6 address of next hop\n")
                   3698: 
                   3699: DEFUN (set_ipv6_nexthop_local,
                   3700:        set_ipv6_nexthop_local_cmd,
                   3701:        "set ipv6 next-hop local X:X::X:X",
                   3702:        SET_STR
                   3703:        IPV6_STR
                   3704:        "IPv6 next-hop address\n"
                   3705:        "IPv6 local address\n"
                   3706:        "IPv6 address of next hop\n")
                   3707: {
                   3708:   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
                   3709: }
                   3710: 
                   3711: DEFUN (no_set_ipv6_nexthop_local,
                   3712:        no_set_ipv6_nexthop_local_cmd,
                   3713:        "no set ipv6 next-hop local",
                   3714:        NO_STR
                   3715:        SET_STR
                   3716:        IPV6_STR
                   3717:        "IPv6 next-hop address\n"
                   3718:        "IPv6 local address\n")
                   3719: {
                   3720:   if (argc == 0)
                   3721:     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
                   3722:   
                   3723:   return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
                   3724: }
                   3725: 
                   3726: ALIAS (no_set_ipv6_nexthop_local,
                   3727:        no_set_ipv6_nexthop_local_val_cmd,
                   3728:        "no set ipv6 next-hop local X:X::X:X",
                   3729:        NO_STR
                   3730:        SET_STR
                   3731:        IPV6_STR
                   3732:        "IPv6 next-hop address\n"
                   3733:        "IPv6 local address\n"
                   3734:        "IPv6 address of next hop\n")
                   3735: 
                   3736: DEFUN (set_vpnv4_nexthop,
                   3737:        set_vpnv4_nexthop_cmd,
                   3738:        "set vpnv4 next-hop A.B.C.D",
                   3739:        SET_STR
                   3740:        "VPNv4 information\n"
                   3741:        "VPNv4 next-hop address\n"
                   3742:        "IP address of next hop\n")
                   3743: {
                   3744:   return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
                   3745: }
                   3746: 
                   3747: DEFUN (no_set_vpnv4_nexthop,
                   3748:        no_set_vpnv4_nexthop_cmd,
                   3749:        "no set vpnv4 next-hop",
                   3750:        NO_STR
                   3751:        SET_STR
                   3752:        "VPNv4 information\n"
                   3753:        "VPNv4 next-hop address\n")
                   3754: {
                   3755:   if (argc == 0)
                   3756:     return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
                   3757: 
                   3758:   return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
                   3759: }
                   3760: 
                   3761: ALIAS (no_set_vpnv4_nexthop,
                   3762:        no_set_vpnv4_nexthop_val_cmd,
                   3763:        "no set vpnv4 next-hop A.B.C.D",
                   3764:        NO_STR
                   3765:        SET_STR
                   3766:        "VPNv4 information\n"
                   3767:        "VPNv4 next-hop address\n"
                   3768:        "IP address of next hop\n")
                   3769: 
                   3770: DEFUN (set_originator_id,
                   3771:        set_originator_id_cmd,
                   3772:        "set originator-id A.B.C.D",
                   3773:        SET_STR
                   3774:        "BGP originator ID attribute\n"
                   3775:        "IP address of originator\n")
                   3776: {
                   3777:   return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
                   3778: }
                   3779: 
                   3780: DEFUN (no_set_originator_id,
                   3781:        no_set_originator_id_cmd,
                   3782:        "no set originator-id",
                   3783:        NO_STR
                   3784:        SET_STR
                   3785:        "BGP originator ID attribute\n")
                   3786: {
                   3787:   if (argc == 0)
                   3788:     return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
                   3789:   
                   3790:   return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
                   3791: }
                   3792: 
                   3793: ALIAS (no_set_originator_id,
                   3794:        no_set_originator_id_val_cmd,
                   3795:        "no set originator-id A.B.C.D",
                   3796:        NO_STR
                   3797:        SET_STR
                   3798:        "BGP originator ID attribute\n"
                   3799:        "IP address of originator\n")
                   3800: 
                   3801: DEFUN_DEPRECATED (set_pathlimit_ttl,
                   3802:        set_pathlimit_ttl_cmd,
                   3803:        "set pathlimit ttl <1-255>",
                   3804:        SET_STR
                   3805:        "BGP AS-Pathlimit attribute\n"
                   3806:        "Set AS-Path Hop-count TTL\n")
                   3807: {
                   3808:   return CMD_SUCCESS;
                   3809: }
                   3810: 
                   3811: DEFUN_DEPRECATED (no_set_pathlimit_ttl,
                   3812:        no_set_pathlimit_ttl_cmd,
                   3813:        "no set pathlimit ttl",
                   3814:        NO_STR
                   3815:        SET_STR
                   3816:        "BGP AS-Pathlimit attribute\n"
                   3817:        "Set AS-Path Hop-count TTL\n")
                   3818: {
                   3819:   return CMD_SUCCESS;
                   3820: }
                   3821: 
                   3822: ALIAS (no_set_pathlimit_ttl,
                   3823:        no_set_pathlimit_ttl_val_cmd,
                   3824:        "no set pathlimit ttl <1-255>",
                   3825:        NO_STR
                   3826:        MATCH_STR
                   3827:        "BGP AS-Pathlimit attribute\n"
                   3828:        "Set AS-Path Hop-count TTL\n")
                   3829: 
                   3830: DEFUN_DEPRECATED (match_pathlimit_as,
                   3831:        match_pathlimit_as_cmd,
                   3832:        "match pathlimit as <1-65535>",
                   3833:        MATCH_STR
                   3834:        "BGP AS-Pathlimit attribute\n"
                   3835:        "Match Pathlimit AS number\n")
                   3836: {
                   3837:   return CMD_SUCCESS;
                   3838: }
                   3839: 
                   3840: DEFUN_DEPRECATED (no_match_pathlimit_as,
                   3841:        no_match_pathlimit_as_cmd,
                   3842:        "no match pathlimit as",
                   3843:        NO_STR
                   3844:        MATCH_STR
                   3845:        "BGP AS-Pathlimit attribute\n"
                   3846:        "Match Pathlimit AS number\n")
                   3847: {
                   3848:   return CMD_SUCCESS;
                   3849: }
                   3850: 
                   3851: ALIAS (no_match_pathlimit_as,
                   3852:        no_match_pathlimit_as_val_cmd,
                   3853:        "no match pathlimit as <1-65535>",
                   3854:        NO_STR
                   3855:        MATCH_STR
                   3856:        "BGP AS-Pathlimit attribute\n"
                   3857:        "Match Pathlimit ASN\n")
                   3858: 
1.1.1.4 ! misho    3859: 
1.1       misho    3860: /* Initialization of route map. */
                   3861: void
                   3862: bgp_route_map_init (void)
                   3863: {
                   3864:   route_map_init ();
                   3865:   route_map_init_vty ();
                   3866:   route_map_add_hook (bgp_route_map_update);
                   3867:   route_map_delete_hook (bgp_route_map_update);
                   3868: 
                   3869:   route_map_install_match (&route_match_peer_cmd);
                   3870:   route_map_install_match (&route_match_ip_address_cmd);
                   3871:   route_map_install_match (&route_match_ip_next_hop_cmd);
                   3872:   route_map_install_match (&route_match_ip_route_source_cmd);
                   3873:   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
                   3874:   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
                   3875:   route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
                   3876:   route_map_install_match (&route_match_aspath_cmd);
                   3877:   route_map_install_match (&route_match_community_cmd);
                   3878:   route_map_install_match (&route_match_ecommunity_cmd);
                   3879:   route_map_install_match (&route_match_metric_cmd);
                   3880:   route_map_install_match (&route_match_origin_cmd);
1.1.1.2   misho    3881:   route_map_install_match (&route_match_probability_cmd);
1.1       misho    3882: 
                   3883:   route_map_install_set (&route_set_ip_nexthop_cmd);
                   3884:   route_map_install_set (&route_set_local_pref_cmd);
                   3885:   route_map_install_set (&route_set_weight_cmd);
                   3886:   route_map_install_set (&route_set_metric_cmd);
                   3887:   route_map_install_set (&route_set_aspath_prepend_cmd);
                   3888:   route_map_install_set (&route_set_aspath_exclude_cmd);
                   3889:   route_map_install_set (&route_set_origin_cmd);
                   3890:   route_map_install_set (&route_set_atomic_aggregate_cmd);
                   3891:   route_map_install_set (&route_set_aggregator_as_cmd);
                   3892:   route_map_install_set (&route_set_community_cmd);
                   3893:   route_map_install_set (&route_set_community_delete_cmd);
                   3894:   route_map_install_set (&route_set_vpnv4_nexthop_cmd);
                   3895:   route_map_install_set (&route_set_originator_id_cmd);
                   3896:   route_map_install_set (&route_set_ecommunity_rt_cmd);
                   3897:   route_map_install_set (&route_set_ecommunity_soo_cmd);
                   3898: 
                   3899:   install_element (RMAP_NODE, &match_peer_cmd);
                   3900:   install_element (RMAP_NODE, &match_peer_local_cmd);
                   3901:   install_element (RMAP_NODE, &no_match_peer_cmd);
                   3902:   install_element (RMAP_NODE, &no_match_peer_val_cmd);
                   3903:   install_element (RMAP_NODE, &no_match_peer_local_cmd);
                   3904:   install_element (RMAP_NODE, &match_ip_address_cmd);
                   3905:   install_element (RMAP_NODE, &no_match_ip_address_cmd);
                   3906:   install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
                   3907:   install_element (RMAP_NODE, &match_ip_next_hop_cmd);
                   3908:   install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
                   3909:   install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
                   3910:   install_element (RMAP_NODE, &match_ip_route_source_cmd);
                   3911:   install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
                   3912:   install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
                   3913:   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
                   3914:   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
                   3915:   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
                   3916:   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
                   3917:   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
                   3918:   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
                   3919:   install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
                   3920:   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
                   3921:   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
                   3922: 
                   3923:   install_element (RMAP_NODE, &match_aspath_cmd);
                   3924:   install_element (RMAP_NODE, &no_match_aspath_cmd);
                   3925:   install_element (RMAP_NODE, &no_match_aspath_val_cmd);
                   3926:   install_element (RMAP_NODE, &match_metric_cmd);
                   3927:   install_element (RMAP_NODE, &no_match_metric_cmd);
                   3928:   install_element (RMAP_NODE, &no_match_metric_val_cmd);
                   3929:   install_element (RMAP_NODE, &match_community_cmd);
                   3930:   install_element (RMAP_NODE, &match_community_exact_cmd);
                   3931:   install_element (RMAP_NODE, &no_match_community_cmd);
                   3932:   install_element (RMAP_NODE, &no_match_community_val_cmd);
                   3933:   install_element (RMAP_NODE, &no_match_community_exact_cmd);
                   3934:   install_element (RMAP_NODE, &match_ecommunity_cmd);
                   3935:   install_element (RMAP_NODE, &no_match_ecommunity_cmd);
                   3936:   install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
                   3937:   install_element (RMAP_NODE, &match_origin_cmd);
                   3938:   install_element (RMAP_NODE, &no_match_origin_cmd);
                   3939:   install_element (RMAP_NODE, &no_match_origin_val_cmd);
1.1.1.2   misho    3940:   install_element (RMAP_NODE, &match_probability_cmd);
                   3941:   install_element (RMAP_NODE, &no_match_probability_cmd);
                   3942:   install_element (RMAP_NODE, &no_match_probability_val_cmd);
1.1       misho    3943: 
                   3944:   install_element (RMAP_NODE, &set_ip_nexthop_cmd);
                   3945:   install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
                   3946:   install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
                   3947:   install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
                   3948:   install_element (RMAP_NODE, &set_local_pref_cmd);
                   3949:   install_element (RMAP_NODE, &no_set_local_pref_cmd);
                   3950:   install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
                   3951:   install_element (RMAP_NODE, &set_weight_cmd);
                   3952:   install_element (RMAP_NODE, &no_set_weight_cmd);
                   3953:   install_element (RMAP_NODE, &no_set_weight_val_cmd);
                   3954:   install_element (RMAP_NODE, &set_metric_cmd);
                   3955:   install_element (RMAP_NODE, &set_metric_addsub_cmd);
1.1.1.4 ! misho    3956:   install_element (RMAP_NODE, &set_metric_rtt_cmd);
1.1       misho    3957:   install_element (RMAP_NODE, &no_set_metric_cmd);
                   3958:   install_element (RMAP_NODE, &no_set_metric_val_cmd);
                   3959:   install_element (RMAP_NODE, &set_aspath_prepend_cmd);
1.1.1.4 ! misho    3960:   install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
1.1       misho    3961:   install_element (RMAP_NODE, &set_aspath_exclude_cmd);
                   3962:   install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
                   3963:   install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
                   3964:   install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
                   3965:   install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
                   3966:   install_element (RMAP_NODE, &set_origin_cmd);
                   3967:   install_element (RMAP_NODE, &no_set_origin_cmd);
                   3968:   install_element (RMAP_NODE, &no_set_origin_val_cmd);
                   3969:   install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
                   3970:   install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
                   3971:   install_element (RMAP_NODE, &set_aggregator_as_cmd);
                   3972:   install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
                   3973:   install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
                   3974:   install_element (RMAP_NODE, &set_community_cmd);
                   3975:   install_element (RMAP_NODE, &set_community_none_cmd);
                   3976:   install_element (RMAP_NODE, &no_set_community_cmd);
                   3977:   install_element (RMAP_NODE, &no_set_community_val_cmd);
                   3978:   install_element (RMAP_NODE, &no_set_community_none_cmd);
                   3979:   install_element (RMAP_NODE, &set_community_delete_cmd);
                   3980:   install_element (RMAP_NODE, &no_set_community_delete_cmd);
                   3981:   install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
                   3982:   install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
                   3983:   install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
                   3984:   install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
                   3985:   install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
                   3986:   install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
                   3987:   install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
                   3988:   install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
                   3989:   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
                   3990:   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
                   3991:   install_element (RMAP_NODE, &set_originator_id_cmd);
                   3992:   install_element (RMAP_NODE, &no_set_originator_id_cmd);
                   3993:   install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
                   3994: 
                   3995:   route_map_install_match (&route_match_ipv6_address_cmd);
                   3996:   route_map_install_match (&route_match_ipv6_next_hop_cmd);
                   3997:   route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
                   3998:   route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
                   3999:   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
1.1.1.4 ! misho    4000:   route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
        !          4001: 
1.1       misho    4002:   install_element (RMAP_NODE, &match_ipv6_address_cmd);
                   4003:   install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
                   4004:   install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
                   4005:   install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
                   4006:   install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
                   4007:   install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
                   4008:   install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
                   4009:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
                   4010:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
                   4011:   install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
                   4012:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
                   4013:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
1.1.1.4 ! misho    4014:   install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
        !          4015:   install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
1.1       misho    4016: 
                   4017:   /* AS-Pathlimit: functionality removed, commands kept for
                   4018:    * compatibility.
                   4019:    */
                   4020:   install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
                   4021:   install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
                   4022:   install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
                   4023:   install_element (RMAP_NODE, &match_pathlimit_as_cmd);
                   4024:   install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
                   4025:   install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
                   4026: }

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