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

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

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