LCOV - code coverage report
Current view: top level - bgpd - bgp_routemap.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1233 0.0 %
Date: 2015-11-19 Functions: 0 180 0.0 %

          Line data    Source code
       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           0 : route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
     111             :       void *object)
     112             : {
     113             :   union sockunion *su;
     114           0 :   union sockunion su_def = { .sa.sa_family = AF_INET,
     115             :                              .sin.sin_addr.s_addr = INADDR_ANY };
     116             :   struct peer_group *group;
     117             :   struct peer *peer;
     118             :   struct listnode *node, *nnode;
     119             : 
     120           0 :   if (type == RMAP_BGP)
     121             :     {
     122           0 :       su = rule;
     123           0 :       peer = ((struct bgp_info *) object)->peer;
     124             : 
     125           0 :       if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
     126           0 :            ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
     127           0 :         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 */
     131           0 :       if (sockunion_same (su, &su_def))
     132             :         {
     133             :           int ret;
     134           0 :           if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
     135           0 :                CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
     136           0 :                CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
     137           0 :             ret = RMAP_MATCH;
     138             :           else
     139           0 :             ret = RMAP_NOMATCH;
     140           0 :           return ret;
     141             :         }
     142             : 
     143           0 :       if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     144             :         {
     145           0 :           if (sockunion_same (su, &peer->su))
     146           0 :             return RMAP_MATCH;
     147             : 
     148           0 :           return RMAP_NOMATCH;
     149             :         }
     150             :       else
     151             :         {
     152           0 :           group = peer->group;
     153           0 :           for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
     154             :             {
     155           0 :               if (sockunion_same (su, &peer->su))
     156           0 :                 return RMAP_MATCH;
     157             :             }
     158           0 :           return RMAP_NOMATCH;
     159             :         }
     160             :     }
     161           0 :   return RMAP_NOMATCH;
     162             : }
     163             : 
     164             : static void *
     165           0 : route_match_peer_compile (const char *arg)
     166             : {
     167             :   union sockunion *su;
     168             :   int ret;
     169             : 
     170           0 :   su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
     171             : 
     172           0 :   ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
     173           0 :   if (ret < 0) {
     174           0 :     XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
     175           0 :     return NULL;
     176             :   }
     177             : 
     178           0 :   return su;
     179             : }
     180             : 
     181             : /* Free route map's compiled `ip address' value. */
     182             : static void
     183           0 : route_match_peer_free (void *rule)
     184             : {
     185           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     186           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     209             :     {
     210           0 :       alist = access_list_lookup (AFI_IP, (char *) rule);
     211           0 :       if (alist == NULL)
     212           0 :         return RMAP_NOMATCH;
     213             :     
     214           0 :       return (access_list_apply (alist, prefix) == FILTER_DENY ?
     215             :               RMAP_NOMATCH : RMAP_MATCH);
     216             :     }
     217           0 :   return RMAP_NOMATCH;
     218             : }
     219             : 
     220             : /* Route map `ip address' match statement.  `arg' should be
     221             :    access-list name. */
     222             : static void *
     223           0 : route_match_ip_address_compile (const char *arg)
     224             : {
     225           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     226             : }
     227             : 
     228             : /* Free route map's compiled `ip address' value. */
     229             : static void
     230           0 : route_match_ip_address_free (void *rule)
     231             : {
     232           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     233           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     256             :     {
     257           0 :       bgp_info = object;
     258           0 :       p.family = AF_INET;
     259           0 :       p.prefix = bgp_info->attr->nexthop;
     260           0 :       p.prefixlen = IPV4_MAX_BITLEN;
     261             : 
     262           0 :       alist = access_list_lookup (AFI_IP, (char *) rule);
     263           0 :       if (alist == NULL)
     264           0 :         return RMAP_NOMATCH;
     265             : 
     266           0 :       return (access_list_apply (alist, &p) == FILTER_DENY ?
     267             :               RMAP_NOMATCH : RMAP_MATCH);
     268             :     }
     269           0 :   return RMAP_NOMATCH;
     270             : }
     271             : 
     272             : /* Route map `ip next-hop' match statement. `arg' is
     273             :    access-list name. */
     274             : static void *
     275           0 : route_match_ip_next_hop_compile (const char *arg)
     276             : {
     277           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     278             : }
     279             : 
     280             : /* Free route map's compiled `ip address' value. */
     281             : static void
     282           0 : route_match_ip_next_hop_free (void *rule)
     283             : {
     284           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     285           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     309             :     {
     310           0 :       bgp_info = object;
     311           0 :       peer = bgp_info->peer;
     312             : 
     313           0 :       if (! peer || sockunion_family (&peer->su) != AF_INET)
     314           0 :         return RMAP_NOMATCH;
     315             : 
     316           0 :       p.family = AF_INET;
     317           0 :       p.prefix = peer->su.sin.sin_addr;
     318           0 :       p.prefixlen = IPV4_MAX_BITLEN;
     319             : 
     320           0 :       alist = access_list_lookup (AFI_IP, (char *) rule);
     321           0 :       if (alist == NULL)
     322           0 :         return RMAP_NOMATCH;
     323             : 
     324           0 :       return (access_list_apply (alist, &p) == FILTER_DENY ?
     325             :               RMAP_NOMATCH : RMAP_MATCH);
     326             :     }
     327           0 :   return RMAP_NOMATCH;
     328             : }
     329             : 
     330             : /* Route map `ip route-source' match statement. `arg' is
     331             :    access-list name. */
     332             : static void *
     333           0 : route_match_ip_route_source_compile (const char *arg)
     334             : {
     335           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     336             : }
     337             : 
     338             : /* Free route map's compiled `ip address' value. */
     339             : static void
     340           0 : route_match_ip_route_source_free (void *rule)
     341             : {
     342           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     343           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     363             :     {
     364           0 :       plist = prefix_list_lookup (AFI_IP, (char *) rule);
     365           0 :       if (plist == NULL)
     366           0 :         return RMAP_NOMATCH;
     367             :     
     368           0 :       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
     369             :               RMAP_NOMATCH : RMAP_MATCH);
     370             :     }
     371           0 :   return RMAP_NOMATCH;
     372             : }
     373             : 
     374             : static void *
     375           0 : route_match_ip_address_prefix_list_compile (const char *arg)
     376             : {
     377           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     378             : }
     379             : 
     380             : static void
     381           0 : route_match_ip_address_prefix_list_free (void *rule)
     382             : {
     383           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     384           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     405             :     {
     406           0 :       bgp_info = object;
     407           0 :       p.family = AF_INET;
     408           0 :       p.prefix = bgp_info->attr->nexthop;
     409           0 :       p.prefixlen = IPV4_MAX_BITLEN;
     410             : 
     411           0 :       plist = prefix_list_lookup (AFI_IP, (char *) rule);
     412           0 :       if (plist == NULL)
     413           0 :         return RMAP_NOMATCH;
     414             : 
     415           0 :       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
     416             :               RMAP_NOMATCH : RMAP_MATCH);
     417             :     }
     418           0 :   return RMAP_NOMATCH;
     419             : }
     420             : 
     421             : static void *
     422           0 : route_match_ip_next_hop_prefix_list_compile (const char *arg)
     423             : {
     424           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     425             : }
     426             : 
     427             : static void
     428           0 : route_match_ip_next_hop_prefix_list_free (void *rule)
     429             : {
     430           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     431           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     453             :     {
     454           0 :       bgp_info = object;
     455           0 :       peer = bgp_info->peer;
     456             : 
     457           0 :       if (! peer || sockunion_family (&peer->su) != AF_INET)
     458           0 :         return RMAP_NOMATCH;
     459             : 
     460           0 :       p.family = AF_INET;
     461           0 :       p.prefix = peer->su.sin.sin_addr;
     462           0 :       p.prefixlen = IPV4_MAX_BITLEN;
     463             : 
     464           0 :       plist = prefix_list_lookup (AFI_IP, (char *) rule);
     465           0 :       if (plist == NULL)
     466           0 :         return RMAP_NOMATCH;
     467             : 
     468           0 :       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
     469             :               RMAP_NOMATCH : RMAP_MATCH);
     470             :     }
     471           0 :   return RMAP_NOMATCH;
     472             : }
     473             : 
     474             : static void *
     475           0 : route_match_ip_route_source_prefix_list_compile (const char *arg)
     476             : {
     477           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     478             : }
     479             : 
     480             : static void
     481           0 : route_match_ip_route_source_prefix_list_free (void *rule)
     482             : {
     483           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     484           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     505             :     {
     506           0 :       med = rule;
     507           0 :       bgp_info = object;
     508             :     
     509           0 :       if (bgp_info->attr->med == *med)
     510           0 :         return RMAP_MATCH;
     511             :       else
     512           0 :         return RMAP_NOMATCH;
     513             :     }
     514           0 :   return RMAP_NOMATCH;
     515             : }
     516             : 
     517             : /* Route map `match metric' match statement. `arg' is MED value */
     518             : static void *
     519           0 : route_match_metric_compile (const char *arg)
     520             : {
     521             :   u_int32_t *med;
     522           0 :   char *endptr = NULL;
     523             :   unsigned long tmpval;
     524             : 
     525             :   /* Metric value shoud be integer. */
     526           0 :   if (! all_digit (arg))
     527           0 :     return NULL;
     528             : 
     529           0 :   errno = 0;
     530           0 :   tmpval = strtoul (arg, &endptr, 10);
     531           0 :   if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
     532           0 :     return NULL;
     533             :     
     534           0 :   med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
     535             :   
     536           0 :   if (!med)
     537           0 :     return med;
     538             :   
     539           0 :   *med = tmpval;
     540           0 :   return med;
     541             : }
     542             : 
     543             : /* Free route map's compiled `match metric' value. */
     544             : static void
     545           0 : route_match_metric_free (void *rule)
     546             : {
     547           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     548           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     571             :     {
     572           0 :       as_list = as_list_lookup ((char *) rule);
     573           0 :       if (as_list == NULL)
     574           0 :         return RMAP_NOMATCH;
     575             :     
     576           0 :       bgp_info = object;
     577             :     
     578             :       /* Perform match. */
     579           0 :       return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
     580             :     }
     581           0 :   return RMAP_NOMATCH;
     582             : }
     583             : 
     584             : /* Compile function for as-path match. */
     585             : static void *
     586           0 : route_match_aspath_compile (const char *arg)
     587             : {
     588           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     589             : }
     590             : 
     591             : /* Compile function for as-path match. */
     592             : static void
     593           0 : route_match_aspath_free (void *rule)
     594             : {
     595           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     596           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP) 
     624             :     {
     625           0 :       bgp_info = object;
     626           0 :       rcom = rule;
     627             : 
     628           0 :       list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
     629           0 :       if (! list)
     630           0 :         return RMAP_NOMATCH;
     631             : 
     632           0 :       if (rcom->exact)
     633             :         {
     634           0 :           if (community_list_exact_match (bgp_info->attr->community, list))
     635           0 :             return RMAP_MATCH;
     636             :         }
     637             :       else
     638             :         {
     639           0 :           if (community_list_match (bgp_info->attr->community, list))
     640           0 :             return RMAP_MATCH;
     641             :         }
     642             :     }
     643           0 :   return RMAP_NOMATCH;
     644             : }
     645             : 
     646             : /* Compile function for community match. */
     647             : static void *
     648           0 : route_match_community_compile (const char *arg)
     649             : {
     650             :   struct rmap_community *rcom;
     651             :   int len;
     652             :   char *p;
     653             : 
     654           0 :   rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
     655             : 
     656           0 :   p = strchr (arg, ' ');
     657           0 :   if (p)
     658             :     {
     659           0 :       len = p - arg;
     660           0 :       rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
     661           0 :       memcpy (rcom->name, arg, len);
     662           0 :       rcom->exact = 1;
     663             :     }
     664             :   else
     665             :     {
     666           0 :       rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     667           0 :       rcom->exact = 0;
     668             :     }
     669           0 :   return rcom;
     670             : }
     671             : 
     672             : /* Compile function for community match. */
     673             : static void
     674           0 : route_match_community_free (void *rule)
     675             : {
     676           0 :   struct rmap_community *rcom = rule;
     677             : 
     678           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); 
     679           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
     680           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP) 
     700             :     {
     701           0 :       bgp_info = object;
     702             :       
     703           0 :       if (!bgp_info->attr->extra)
     704           0 :         return RMAP_NOMATCH;
     705             :       
     706           0 :       list = community_list_lookup (bgp_clist, (char *) rule,
     707             :                                     EXTCOMMUNITY_LIST_MASTER);
     708           0 :       if (! list)
     709           0 :         return RMAP_NOMATCH;
     710             : 
     711           0 :       if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
     712           0 :         return RMAP_MATCH;
     713             :     }
     714           0 :   return RMAP_NOMATCH;
     715             : }
     716             : 
     717             : /* Compile function for extcommunity match. */
     718             : static void *
     719           0 : route_match_ecommunity_compile (const char *arg)
     720             : {
     721           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
     722             : }
     723             : 
     724             : /* Compile function for extcommunity match. */
     725             : static void
     726           0 : route_match_ecommunity_free (void *rule)
     727             : {
     728           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     729           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     752             :     {
     753           0 :       origin = rule;
     754           0 :       bgp_info = object;
     755             :     
     756           0 :       if (bgp_info->attr->origin == *origin)
     757           0 :         return RMAP_MATCH;
     758             :     }
     759             : 
     760           0 :   return RMAP_NOMATCH;
     761             : }
     762             : 
     763             : static void *
     764           0 : route_match_origin_compile (const char *arg)
     765             : {
     766             :   u_char *origin;
     767             : 
     768           0 :   origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
     769             : 
     770           0 :   if (strcmp (arg, "igp") == 0)
     771           0 :     *origin = 0;
     772           0 :   else if (strcmp (arg, "egp") == 0)
     773           0 :     *origin = 1;
     774             :   else
     775           0 :     *origin = 2;
     776             : 
     777           0 :   return origin;
     778             : }
     779             : 
     780             : /* Free route map's compiled `ip address' value. */
     781             : static void
     782           0 : route_match_origin_free (void *rule)
     783             : {
     784           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     785           0 : }
     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             : };
     795             : 
     796             : /* match probability  { */
     797             : 
     798             : static route_map_result_t
     799           0 : 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           0 :   r = random();
     805             : #else
     806             :   r = (long) rand();
     807             : #endif
     808             : 
     809           0 :   switch (*(unsigned *) rule)
     810             :   {
     811           0 :     case 0: break;
     812           0 :     case RAND_MAX: return RMAP_MATCH;
     813             :     default:
     814           0 :       if (r < *(unsigned *) rule)
     815             :         {
     816           0 :           return RMAP_MATCH;
     817             :         }
     818             :   }
     819             : 
     820           0 :   return RMAP_NOMATCH;
     821             : }
     822             : 
     823             : static void *
     824           0 : 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           0 :   srandom (time (NULL));
     831             : #else
     832             :   srand (time (NULL));
     833             : #endif
     834             : 
     835           0 :   perc    = atoi (arg);
     836           0 :   lobule  = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
     837             : 
     838           0 :   switch (perc)
     839             :     {
     840           0 :       case 0:   *lobule = 0; break;
     841           0 :       case 100: *lobule = RAND_MAX; break;
     842           0 :       default:  *lobule = RAND_MAX / 100 * perc;
     843             :     }
     844             : 
     845           0 :   return lobule;
     846             : }
     847             : 
     848             : static void
     849           0 : route_match_probability_free (void *rule)
     850             : {
     851           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
     852           0 : }
     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             : 
     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           0 : route_set_ip_nexthop (void *rule, struct prefix *prefix,
     875             :                       route_map_object_t type, void *object)
     876             : {
     877           0 :   struct rmap_ip_nexthop_set *rins = rule;
     878             :   struct bgp_info *bgp_info;
     879             :   struct peer *peer;
     880             : 
     881           0 :   if (type == RMAP_BGP)
     882             :     {
     883           0 :       bgp_info = object;
     884           0 :       peer = bgp_info->peer;
     885             : 
     886           0 :       if (rins->peer_address)
     887             :         {
     888           0 :          if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
     889           0 :            CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
     890           0 :               && peer->su_remote 
     891           0 :               && sockunion_family (peer->su_remote) == AF_INET)
     892             :             {
     893           0 :               bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
     894           0 :               bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
     895             :             }
     896           0 :           else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
     897           0 :                    && peer->su_local
     898           0 :                    && sockunion_family (peer->su_local) == AF_INET)
     899             :             {
     900           0 :               bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
     901           0 :               bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
     902             :             }
     903             :         }
     904             :       else
     905             :         {
     906             :           /* Set next hop value. */ 
     907           0 :           bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
     908           0 :           bgp_info->attr->nexthop = *rins->address;
     909             :         }
     910             :     }
     911             : 
     912           0 :   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           0 : route_set_ip_nexthop_compile (const char *arg)
     919             : {
     920             :   struct rmap_ip_nexthop_set *rins;
     921           0 :   struct in_addr *address = NULL;
     922           0 :   int peer_address = 0;
     923             :   int ret;
     924             : 
     925           0 :   if (strcmp (arg, "peer-address") == 0)
     926           0 :     peer_address = 1;
     927             :   else
     928             :     {
     929           0 :       address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
     930           0 :       ret = inet_aton (arg, address);
     931             : 
     932           0 :       if (ret == 0)
     933             :         {
     934           0 :           XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
     935           0 :           return NULL;
     936             :         }
     937             :     }
     938             : 
     939           0 :   rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
     940             : 
     941           0 :   rins->address = address;
     942           0 :   rins->peer_address = peer_address;
     943             : 
     944           0 :   return rins;
     945             : }
     946             : 
     947             : /* Free route map's compiled `ip nexthop' value. */
     948             : static void
     949           0 : route_set_ip_nexthop_free (void *rule)
     950             : {
     951           0 :   struct rmap_ip_nexthop_set *rins = rule;
     952             : 
     953           0 :   if (rins->address)
     954           0 :     XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
     955             :     
     956           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
     957           0 : }
     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           0 : 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           0 :   if (type == RMAP_BGP)
     979             :     {
     980             :       /* Fetch routemap's rule information. */
     981           0 :       local_pref = rule;
     982           0 :       bgp_info = object;
     983             :     
     984             :       /* Set local preference value. */ 
     985           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
     986           0 :       bgp_info->attr->local_pref = *local_pref;
     987             :     }
     988             : 
     989           0 :   return RMAP_OKAY;
     990             : }
     991             : 
     992             : /* set local preference compilation. */
     993             : static void *
     994           0 : route_set_local_pref_compile (const char *arg)
     995             : {
     996             :   unsigned long tmp;
     997             :   u_int32_t *local_pref;
     998           0 :   char *endptr = NULL;
     999             : 
    1000             :   /* Local preference value shoud be integer. */
    1001           0 :   if (! all_digit (arg))
    1002           0 :     return NULL;
    1003             :   
    1004           0 :   errno = 0;
    1005           0 :   tmp = strtoul (arg, &endptr, 10);
    1006           0 :   if (*endptr != '\0' || errno || tmp > UINT32_MAX)
    1007           0 :     return NULL;
    1008             :    
    1009           0 :   local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); 
    1010             :   
    1011           0 :   if (!local_pref)
    1012           0 :     return local_pref;
    1013             :   
    1014           0 :   *local_pref = tmp;
    1015             :   
    1016           0 :   return local_pref;
    1017             : }
    1018             : 
    1019             : /* Free route map's local preference value. */
    1020             : static void
    1021           0 : route_set_local_pref_free (void *rule)
    1022             : {
    1023           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1024           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1046             :     {
    1047             :       /* Fetch routemap's rule information. */
    1048           0 :       weight = rule;
    1049           0 :       bgp_info = object;
    1050             :     
    1051             :       /* Set weight value. */ 
    1052           0 :       if (*weight)
    1053           0 :         (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
    1054           0 :       else if (bgp_info->attr->extra)
    1055           0 :         bgp_info->attr->extra->weight = 0;
    1056             :     }
    1057             : 
    1058           0 :   return RMAP_OKAY;
    1059             : }
    1060             : 
    1061             : /* set local preference compilation. */
    1062             : static void *
    1063           0 : route_set_weight_compile (const char *arg)
    1064             : {
    1065             :   unsigned long tmp;
    1066             :   u_int32_t *weight;
    1067           0 :   char *endptr = NULL;
    1068             : 
    1069             :   /* Local preference value shoud be integer. */
    1070           0 :   if (! all_digit (arg))
    1071           0 :     return NULL;
    1072             : 
    1073           0 :   errno = 0;
    1074           0 :   tmp = strtoul (arg, &endptr, 10);
    1075           0 :   if (*endptr != '\0' || errno || tmp > UINT32_MAX)
    1076           0 :     return NULL;
    1077             :   
    1078           0 :   weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
    1079             :   
    1080           0 :   if (weight == NULL)
    1081           0 :     return weight;
    1082             :   
    1083           0 :   *weight = tmp;  
    1084             :   
    1085           0 :   return weight;
    1086             : }
    1087             : 
    1088             : /* Free route map's local preference value. */
    1089             : static void
    1090           0 : route_set_weight_free (void *rule)
    1091             : {
    1092           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1093           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1116             :     {
    1117             :       /* Fetch routemap's rule information. */
    1118           0 :       metric = rule;
    1119           0 :       bgp_info = object;
    1120             : 
    1121           0 :       if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
    1122           0 :         bgp_info->attr->med = 0;
    1123           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
    1124             : 
    1125           0 :       if (all_digit (metric))
    1126             :         {
    1127           0 :           metric_val = strtoul (metric, (char **)NULL, 10);
    1128           0 :           bgp_info->attr->med = metric_val;
    1129             :         }
    1130             :       else
    1131             :         {
    1132           0 :           metric_val = strtoul (metric+1, (char **)NULL, 10);
    1133             : 
    1134           0 :           if (strncmp (metric, "+", 1) == 0)
    1135             :             {
    1136           0 :               if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
    1137           0 :                 bgp_info->attr->med = BGP_MED_MAX - 1;
    1138             :               else
    1139           0 :                 bgp_info->attr->med += metric_val;
    1140             :             }
    1141           0 :           else if (strncmp (metric, "-", 1) == 0)
    1142             :             {
    1143           0 :               if (bgp_info->attr->med <= metric_val)
    1144           0 :                 bgp_info->attr->med = 0;
    1145             :               else
    1146           0 :                 bgp_info->attr->med -= metric_val;
    1147             :             }
    1148             :         }
    1149             :     }
    1150           0 :   return RMAP_OKAY;
    1151             : }
    1152             : 
    1153             : /* set metric compilation. */
    1154             : static void *
    1155           0 : route_set_metric_compile (const char *arg)
    1156             : {
    1157             :   u_int32_t metric;
    1158             :   unsigned long larg;
    1159           0 :   char *endptr = NULL;
    1160             : 
    1161           0 :   if (all_digit (arg))
    1162             :     {
    1163             :       /* set metric value check*/
    1164           0 :       errno = 0;
    1165           0 :       larg = strtoul (arg, &endptr, 10);
    1166           0 :       if (*endptr != '\0' || errno || larg > UINT32_MAX)
    1167           0 :         return NULL;
    1168           0 :       metric = larg;
    1169             :     }
    1170             :   else
    1171             :     {
    1172             :       /* set metric +/-value check */
    1173           0 :       if ((strncmp (arg, "+", 1) != 0
    1174           0 :            && strncmp (arg, "-", 1) != 0)
    1175           0 :            || (! all_digit (arg+1)))
    1176           0 :         return NULL;
    1177             : 
    1178           0 :       errno = 0;
    1179           0 :       larg = strtoul (arg+1, &endptr, 10);
    1180           0 :       if (*endptr != '\0' || errno || larg > UINT32_MAX)
    1181           0 :         return NULL;
    1182           0 :       metric = larg;
    1183             :     }
    1184             : 
    1185           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
    1186             : }
    1187             : 
    1188             : /* Free route map's compiled `set metric' value. */
    1189             : static void
    1190           0 : route_set_metric_free (void *rule)
    1191             : {
    1192           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1193           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1215             :     {
    1216           0 :       aspath = rule;
    1217           0 :       binfo = object;
    1218             :     
    1219           0 :       if (binfo->attr->aspath->refcnt)
    1220           0 :         new = aspath_dup (binfo->attr->aspath);
    1221             :       else
    1222           0 :         new = binfo->attr->aspath;
    1223             : 
    1224           0 :       aspath_prepend (aspath, new);
    1225           0 :       binfo->attr->aspath = new;
    1226             :     }
    1227             : 
    1228           0 :   return RMAP_OKAY;
    1229             : }
    1230             : 
    1231             : /* Compile function for as-path prepend. */
    1232             : static void *
    1233           0 : route_set_aspath_prepend_compile (const char *arg)
    1234             : {
    1235             :   struct aspath *aspath;
    1236             : 
    1237           0 :   aspath = aspath_str2aspath (arg);
    1238           0 :   if (! aspath)
    1239           0 :     return NULL;
    1240           0 :   return aspath;
    1241             : }
    1242             : 
    1243             : /* Compile function for as-path prepend. */
    1244             : static void
    1245           0 : route_set_aspath_prepend_free (void *rule)
    1246             : {
    1247           0 :   struct aspath *aspath = rule;
    1248           0 :   aspath_free (aspath);
    1249           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1273             :   {
    1274           0 :     exclude_path = rule;
    1275           0 :     binfo = object;
    1276           0 :     if (binfo->attr->aspath->refcnt)
    1277           0 :       new_path = aspath_dup (binfo->attr->aspath);
    1278             :     else
    1279           0 :       new_path = binfo->attr->aspath;
    1280           0 :     binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
    1281             :   }
    1282           0 :   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           0 : route_set_aspath_exclude_compile (const char *arg)
    1293             : {
    1294             :   struct aspath *aspath;
    1295             : 
    1296           0 :   aspath = aspath_str2aspath (arg);
    1297           0 :   if (! aspath)
    1298           0 :     return NULL;
    1299           0 :   return aspath;
    1300             : }
    1301             : 
    1302             : static void
    1303           0 : route_set_aspath_exclude_free (void *rule)
    1304             : {
    1305           0 :   struct aspath *aspath = rule;
    1306           0 :   aspath_free (aspath);
    1307           0 : }
    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           0 : 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           0 :   struct community *new = NULL;
    1335             :   struct community *old;
    1336             :   struct community *merge;
    1337             :   
    1338           0 :   if (type == RMAP_BGP)
    1339             :     {
    1340           0 :       rcs = rule;
    1341           0 :       binfo = object;
    1342           0 :       attr = binfo->attr;
    1343           0 :       old = attr->community;
    1344             : 
    1345             :       /* "none" case.  */
    1346           0 :       if (rcs->none)
    1347             :         {
    1348           0 :           attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
    1349           0 :           attr->community = NULL;
    1350             :           /* See the longer comment down below. */
    1351           0 :           if (old && old->refcnt == 0)
    1352           0 :             community_free(old);
    1353           0 :           return RMAP_OKAY;
    1354             :         }
    1355             : 
    1356             :       /* "additive" case.  */
    1357           0 :       if (rcs->additive && old)
    1358             :         {
    1359           0 :           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           0 :           if (old->refcnt == 0)
    1366           0 :             community_free (old);
    1367           0 :           new = community_uniq_sort (merge);
    1368           0 :           community_free (merge);
    1369             :         }
    1370             :       else
    1371           0 :         new = community_dup (rcs->com);
    1372             :       
    1373             :       /* will be interned by caller if required */
    1374           0 :       attr->community = new;
    1375             : 
    1376           0 :       attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
    1377             :     }
    1378             : 
    1379           0 :   return RMAP_OKAY;
    1380             : }
    1381             : 
    1382             : /* Compile function for set community. */
    1383             : static void *
    1384           0 : route_set_community_compile (const char *arg)
    1385             : {
    1386             :   struct rmap_com_set *rcs;
    1387           0 :   struct community *com = NULL;
    1388             :   char *sp;
    1389           0 :   int additive = 0;
    1390           0 :   int none = 0;
    1391             :   
    1392           0 :   if (strcmp (arg, "none") == 0)
    1393           0 :     none = 1;
    1394             :   else
    1395             :     {
    1396           0 :       sp = strstr (arg, "additive");
    1397             : 
    1398           0 :       if (sp && sp > arg)
    1399             :         {
    1400             :           /* "additive" keyworkd is included.  */
    1401           0 :           additive = 1;
    1402           0 :           *(sp - 1) = '\0';
    1403             :         }
    1404             : 
    1405           0 :       com = community_str2com (arg);
    1406             : 
    1407           0 :       if (additive)
    1408           0 :         *(sp - 1) = ' ';
    1409             : 
    1410           0 :       if (! com)
    1411           0 :         return NULL;
    1412             :     }
    1413             :   
    1414           0 :   rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
    1415           0 :   rcs->com = com;
    1416           0 :   rcs->additive = additive;
    1417           0 :   rcs->none = none;
    1418             :   
    1419           0 :   return rcs;
    1420             : }
    1421             : 
    1422             : /* Free function for set community. */
    1423             : static void
    1424           0 : route_set_community_free (void *rule)
    1425             : {
    1426           0 :   struct rmap_com_set *rcs = rule;
    1427             : 
    1428           0 :   if (rcs->com)
    1429           0 :     community_free (rcs->com);
    1430           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
    1431           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1456             :     {
    1457           0 :       if (! rule)
    1458           0 :         return RMAP_OKAY;
    1459             : 
    1460           0 :       binfo = object;
    1461           0 :       list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
    1462           0 :       old = binfo->attr->community;
    1463             : 
    1464           0 :       if (list && old)
    1465             :         {
    1466           0 :           merge = community_list_match_delete (community_dup (old), list);
    1467           0 :           new = community_uniq_sort (merge);
    1468           0 :           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           0 :           if (old->refcnt == 0)
    1475           0 :             community_free (old);
    1476             : 
    1477           0 :           if (new->size == 0)
    1478             :             {
    1479           0 :               binfo->attr->community = NULL;
    1480           0 :               binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
    1481           0 :               community_free (new);
    1482             :             }
    1483             :           else
    1484             :             {
    1485           0 :               binfo->attr->community = new;
    1486           0 :               binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
    1487             :             }
    1488             :         }
    1489             :     }
    1490             : 
    1491           0 :   return RMAP_OKAY;
    1492             : }
    1493             : 
    1494             : /* Compile function for set community. */
    1495             : static void *
    1496           0 : route_set_community_delete_compile (const char *arg)
    1497             : {
    1498             :   char *p;
    1499             :   char *str;
    1500             :   int len;
    1501             : 
    1502           0 :   p = strchr (arg, ' ');
    1503           0 :   if (p)
    1504             :     {
    1505           0 :       len = p - arg;
    1506           0 :       str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
    1507           0 :       memcpy (str, arg, len);
    1508             :     }
    1509             :   else
    1510           0 :     str = NULL;
    1511             : 
    1512           0 :   return str;
    1513             : }
    1514             : 
    1515             : /* Free function for set community. */
    1516             : static void
    1517           0 : route_set_community_delete_free (void *rule)
    1518             : {
    1519           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1520           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1544             :     {
    1545           0 :       ecom = rule;
    1546           0 :       bgp_info = object;
    1547             :     
    1548           0 :       if (! ecom)
    1549           0 :         return RMAP_OKAY;
    1550             :     
    1551             :       /* We assume additive for Extended Community. */
    1552           0 :       old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
    1553             : 
    1554           0 :       if (old_ecom)
    1555           0 :         new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
    1556             :       else
    1557           0 :         new_ecom = ecommunity_dup (ecom);
    1558             : 
    1559           0 :       bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
    1560             : 
    1561           0 :       if (old_ecom)
    1562           0 :         ecommunity_unintern (&old_ecom);
    1563             : 
    1564           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
    1565             :     }
    1566           0 :   return RMAP_OKAY;
    1567             : }
    1568             : 
    1569             : /* Compile function for set community. */
    1570             : static void *
    1571           0 : route_set_ecommunity_rt_compile (const char *arg)
    1572             : {
    1573             :   struct ecommunity *ecom;
    1574             : 
    1575           0 :   ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
    1576           0 :   if (! ecom)
    1577           0 :     return NULL;
    1578           0 :   return ecommunity_intern (ecom);
    1579             : }
    1580             : 
    1581             : /* Free function for set community. */
    1582             : static void
    1583           0 : route_set_ecommunity_rt_free (void *rule)
    1584             : {
    1585           0 :   struct ecommunity *ecom = rule;
    1586           0 :   ecommunity_unintern (&ecom);
    1587           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1609             :     {
    1610           0 :       ecom = rule;
    1611           0 :       bgp_info = object;
    1612             :     
    1613           0 :       if (! ecom)
    1614           0 :         return RMAP_OKAY;
    1615             :     
    1616           0 :       old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
    1617             :       
    1618           0 :       if (old_ecom)
    1619           0 :         new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
    1620             :       else
    1621           0 :         new_ecom = ecommunity_dup (ecom);
    1622             : 
    1623           0 :       bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
    1624             : 
    1625           0 :       if (old_ecom)
    1626           0 :         ecommunity_unintern (&old_ecom);
    1627             : 
    1628           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
    1629             :     }
    1630           0 :   return RMAP_OKAY;
    1631             : }
    1632             : 
    1633             : /* Compile function for set community. */
    1634             : static void *
    1635           0 : route_set_ecommunity_soo_compile (const char *arg)
    1636             : {
    1637             :   struct ecommunity *ecom;
    1638             : 
    1639           0 :   ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
    1640           0 :   if (! ecom)
    1641           0 :     return NULL;
    1642             :   
    1643           0 :   return ecommunity_intern (ecom);
    1644             : }
    1645             : 
    1646             : /* Free function for set community. */
    1647             : static void
    1648           0 : route_set_ecommunity_soo_free (void *rule)
    1649             : {
    1650           0 :   struct ecommunity *ecom = rule;
    1651           0 :   ecommunity_unintern (&ecom);
    1652           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1673             :     {
    1674           0 :       origin = rule;
    1675           0 :       bgp_info = object;
    1676             :     
    1677           0 :       bgp_info->attr->origin = *origin;
    1678             :     }
    1679             : 
    1680           0 :   return RMAP_OKAY;
    1681             : }
    1682             : 
    1683             : /* Compile function for origin set. */
    1684             : static void *
    1685           0 : route_set_origin_compile (const char *arg)
    1686             : {
    1687             :   u_char *origin;
    1688             : 
    1689           0 :   origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
    1690             : 
    1691           0 :   if (strcmp (arg, "igp") == 0)
    1692           0 :     *origin = 0;
    1693           0 :   else if (strcmp (arg, "egp") == 0)
    1694           0 :     *origin = 1;
    1695             :   else
    1696           0 :     *origin = 2;
    1697             : 
    1698           0 :   return origin;
    1699             : }
    1700             : 
    1701             : /* Compile function for origin set. */
    1702             : static void
    1703           0 : route_set_origin_free (void *rule)
    1704             : {
    1705           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1706           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1727             :     {
    1728           0 :       bgp_info = object;
    1729           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
    1730             :     }
    1731             : 
    1732           0 :   return RMAP_OKAY;
    1733             : }
    1734             : 
    1735             : /* Compile function for atomic aggregate. */
    1736             : static void *
    1737           0 : route_set_atomic_aggregate_compile (const char *arg)
    1738             : {
    1739           0 :   return (void *)1;
    1740             : }
    1741             : 
    1742             : /* Compile function for atomic aggregate. */
    1743             : static void
    1744           0 : route_set_atomic_aggregate_free (void *rule)
    1745             : {
    1746           0 :   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           0 : 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           0 :   if (type == RMAP_BGP)
    1774             :     {
    1775           0 :       bgp_info = object;
    1776           0 :       aggregator = rule;
    1777           0 :       ae = bgp_attr_extra_get (bgp_info->attr);
    1778             :       
    1779           0 :       ae->aggregator_as = aggregator->as;
    1780           0 :       ae->aggregator_addr = aggregator->address;
    1781           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
    1782             :     }
    1783             : 
    1784           0 :   return RMAP_OKAY;
    1785             : }
    1786             : 
    1787             : static void *
    1788           0 : route_set_aggregator_as_compile (const char *arg)
    1789             : {
    1790             :   struct aggregator *aggregator;
    1791             :   char as[10];
    1792             :   char address[20];
    1793             : 
    1794           0 :   aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
    1795           0 :   sscanf (arg, "%s %s", as, address);
    1796             : 
    1797           0 :   aggregator->as = strtoul (as, NULL, 10);
    1798           0 :   inet_aton (address, &aggregator->address);
    1799             : 
    1800           0 :   return aggregator;
    1801             : }
    1802             : 
    1803             : static void
    1804           0 : route_set_aggregator_as_free (void *rule)
    1805             : {
    1806           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1807           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1827             :     {
    1828           0 :       alist = access_list_lookup (AFI_IP6, (char *) rule);
    1829           0 :       if (alist == NULL)
    1830           0 :         return RMAP_NOMATCH;
    1831             :     
    1832           0 :       return (access_list_apply (alist, prefix) == FILTER_DENY ?
    1833             :               RMAP_NOMATCH : RMAP_MATCH);
    1834             :     }
    1835           0 :   return RMAP_NOMATCH;
    1836             : }
    1837             : 
    1838             : static void *
    1839           0 : route_match_ipv6_address_compile (const char *arg)
    1840             : {
    1841           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
    1842             : }
    1843             : 
    1844             : static void
    1845           0 : route_match_ipv6_address_free (void *rule)
    1846             : {
    1847           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1848           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1869             :     {
    1870           0 :       addr = rule;
    1871           0 :       bgp_info = object;
    1872             :       
    1873           0 :       if (!bgp_info->attr->extra)
    1874           0 :         return RMAP_NOMATCH;
    1875             :       
    1876           0 :       if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
    1877           0 :         return RMAP_MATCH;
    1878             : 
    1879           0 :       if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
    1880           0 :           IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
    1881           0 :         return RMAP_MATCH;
    1882             : 
    1883           0 :       return RMAP_NOMATCH;
    1884             :     }
    1885             : 
    1886           0 :   return RMAP_NOMATCH;
    1887             : }
    1888             : 
    1889             : static void *
    1890           0 : route_match_ipv6_next_hop_compile (const char *arg)
    1891             : {
    1892             :   struct in6_addr *address;
    1893             :   int ret;
    1894             : 
    1895           0 :   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
    1896             : 
    1897           0 :   ret = inet_pton (AF_INET6, arg, address);
    1898           0 :   if (!ret)
    1899             :     {
    1900           0 :       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
    1901           0 :       return NULL;
    1902             :     }
    1903             : 
    1904           0 :   return address;
    1905             : }
    1906             : 
    1907             : static void
    1908           0 : route_match_ipv6_next_hop_free (void *rule)
    1909             : {
    1910           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1911           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1930             :     {
    1931           0 :       plist = prefix_list_lookup (AFI_IP6, (char *) rule);
    1932           0 :       if (plist == NULL)
    1933           0 :         return RMAP_NOMATCH;
    1934             :     
    1935           0 :       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
    1936             :               RMAP_NOMATCH : RMAP_MATCH);
    1937             :     }
    1938           0 :   return RMAP_NOMATCH;
    1939             : }
    1940             : 
    1941             : static void *
    1942           0 : route_match_ipv6_address_prefix_list_compile (const char *arg)
    1943             : {
    1944           0 :   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
    1945             : }
    1946             : 
    1947             : static void
    1948           0 : route_match_ipv6_address_prefix_list_free (void *rule)
    1949             : {
    1950           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    1951           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    1972             :     {
    1973             :       /* Fetch routemap's rule information. */
    1974           0 :       address = rule;
    1975           0 :       bgp_info = object;
    1976             :     
    1977             :       /* Set next hop value. */ 
    1978           0 :       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
    1979             :     
    1980             :       /* Set nexthop length. */
    1981           0 :       if (bgp_info->attr->extra->mp_nexthop_len == 0)
    1982           0 :         bgp_info->attr->extra->mp_nexthop_len = 16;
    1983             :     }
    1984             : 
    1985           0 :   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           0 : route_set_ipv6_nexthop_global_compile (const char *arg)
    1992             : {
    1993             :   int ret;
    1994             :   struct in6_addr *address;
    1995             : 
    1996           0 :   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
    1997             : 
    1998           0 :   ret = inet_pton (AF_INET6, arg, address);
    1999             : 
    2000           0 :   if (ret == 0)
    2001             :     {
    2002           0 :       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
    2003           0 :       return NULL;
    2004             :     }
    2005             : 
    2006           0 :   return address;
    2007             : }
    2008             : 
    2009             : /* Free route map's compiled `ip next-hop' value. */
    2010             : static void
    2011           0 : route_set_ipv6_nexthop_global_free (void *rule)
    2012             : {
    2013           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    2014           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    2036             :     {
    2037             :       /* Fetch routemap's rule information. */
    2038           0 :       address = rule;
    2039           0 :       bgp_info = object;
    2040             :     
    2041             :       /* Set next hop value. */ 
    2042           0 :       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
    2043             :     
    2044             :       /* Set nexthop length. */
    2045           0 :       if (bgp_info->attr->extra->mp_nexthop_len != 32)
    2046           0 :         bgp_info->attr->extra->mp_nexthop_len = 32;
    2047             :     }
    2048             : 
    2049           0 :   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           0 : route_set_ipv6_nexthop_local_compile (const char *arg)
    2056             : {
    2057             :   int ret;
    2058             :   struct in6_addr *address;
    2059             : 
    2060           0 :   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
    2061             : 
    2062           0 :   ret = inet_pton (AF_INET6, arg, address);
    2063             : 
    2064           0 :   if (ret == 0)
    2065             :     {
    2066           0 :       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
    2067           0 :       return NULL;
    2068             :     }
    2069             : 
    2070           0 :   return address;
    2071             : }
    2072             : 
    2073             : /* Free route map's compiled `ip nexthop' value. */
    2074             : static void
    2075           0 : route_set_ipv6_nexthop_local_free (void *rule)
    2076             : {
    2077           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    2078           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP)
    2100             :     {
    2101             :       /* Fetch routemap's rule information. */
    2102           0 :       address = rule;
    2103           0 :       bgp_info = object;
    2104             :     
    2105             :       /* Set next hop value. */ 
    2106           0 :       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
    2107             :     }
    2108             : 
    2109           0 :   return RMAP_OKAY;
    2110             : }
    2111             : 
    2112             : static void *
    2113           0 : route_set_vpnv4_nexthop_compile (const char *arg)
    2114             : {
    2115             :   int ret;
    2116             :   struct in_addr *address;
    2117             : 
    2118           0 :   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
    2119             : 
    2120           0 :   ret = inet_aton (arg, address);
    2121             : 
    2122           0 :   if (ret == 0)
    2123             :     {
    2124           0 :       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
    2125           0 :       return NULL;
    2126             :     }
    2127             : 
    2128           0 :   return address;
    2129             : }
    2130             : 
    2131             : static void
    2132           0 : route_set_vpnv4_nexthop_free (void *rule)
    2133             : {
    2134           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    2135           0 : }
    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           0 : 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           0 :   if (type == RMAP_BGP) 
    2156             :     {
    2157           0 :       address = rule;
    2158           0 :       bgp_info = object;
    2159             :     
    2160           0 :       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
    2161           0 :       (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
    2162             :     }
    2163             : 
    2164           0 :   return RMAP_OKAY;
    2165             : }
    2166             : 
    2167             : /* Compile function for originator-id set. */
    2168             : static void *
    2169           0 : route_set_originator_id_compile (const char *arg)
    2170             : {
    2171             :   int ret;
    2172             :   struct in_addr *address;
    2173             : 
    2174           0 :   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
    2175             : 
    2176           0 :   ret = inet_aton (arg, address);
    2177             : 
    2178           0 :   if (ret == 0)
    2179             :     {
    2180           0 :       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
    2181           0 :       return NULL;
    2182             :     }
    2183             : 
    2184           0 :   return address;
    2185             : }
    2186             : 
    2187             : /* Compile function for originator_id set. */
    2188             : static void
    2189           0 : route_set_originator_id_free (void *rule)
    2190             : {
    2191           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
    2192           0 : }
    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           0 : 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           0 :   ret = route_map_add_match (index, command, arg);
    2211           0 :   if (ret)
    2212             :     {
    2213           0 :       switch (ret)
    2214             :         {
    2215             :         case RMAP_RULE_MISSING:
    2216           0 :           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
    2217           0 :           return CMD_WARNING;
    2218             :         case RMAP_COMPILE_ERROR:
    2219           0 :           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
    2220           0 :           return CMD_WARNING;
    2221             :         }
    2222             :     }
    2223           0 :   return CMD_SUCCESS;
    2224             : }
    2225             : 
    2226             : /* Delete bgp route map rule. */
    2227             : static int
    2228           0 : 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           0 :   ret = route_map_delete_match (index, command, arg);
    2234           0 :   if (ret)
    2235             :     {
    2236           0 :       switch (ret)
    2237             :         {
    2238             :         case RMAP_RULE_MISSING:
    2239           0 :           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
    2240           0 :           return CMD_WARNING;
    2241             :         case RMAP_COMPILE_ERROR:
    2242           0 :           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
    2243           0 :           return CMD_WARNING;
    2244             :         }
    2245             :     }
    2246           0 :   return CMD_SUCCESS;
    2247             : }
    2248             : 
    2249             : /* Add bgp route map rule. */
    2250             : static int
    2251           0 : 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           0 :   ret = route_map_add_set (index, command, arg);
    2257           0 :   if (ret)
    2258             :     {
    2259           0 :       switch (ret)
    2260             :         {
    2261             :         case RMAP_RULE_MISSING:
    2262           0 :           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
    2263           0 :           return CMD_WARNING;
    2264             :         case RMAP_COMPILE_ERROR:
    2265           0 :           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
    2266           0 :           return CMD_WARNING;
    2267             :         }
    2268             :     }
    2269           0 :   return CMD_SUCCESS;
    2270             : }
    2271             : 
    2272             : /* Delete bgp route map rule. */
    2273             : static int
    2274           0 : 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           0 :   ret = route_map_delete_set (index, command, arg);
    2280           0 :   if (ret)
    2281             :     {
    2282           0 :       switch (ret)
    2283             :         {
    2284             :         case RMAP_RULE_MISSING:
    2285           0 :           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
    2286           0 :           return CMD_WARNING;
    2287             :         case RMAP_COMPILE_ERROR:
    2288           0 :           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
    2289           0 :           return CMD_WARNING;
    2290             :         }
    2291             :     }
    2292           0 :   return CMD_SUCCESS;
    2293             : }
    2294             : 
    2295             : /* Hook function for updating route_map assignment. */
    2296             : static void
    2297           0 : 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           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
    2314             :     {
    2315           0 :       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
    2316             :         {
    2317           0 :           for (afi = AFI_IP; afi < AFI_MAX; afi++)
    2318           0 :             for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    2319             :               {
    2320           0 :                 filter = &peer->filter[afi][safi];
    2321             :           
    2322           0 :                for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
    2323             :                   {
    2324           0 :                     if (filter->map[direct].name)
    2325           0 :                       filter->map[direct].map = 
    2326           0 :                         route_map_lookup_by_name (filter->map[direct].name);
    2327             :                     else
    2328           0 :                       filter->map[direct].map = NULL;
    2329             :                   }
    2330             : 
    2331           0 :                 if (filter->usmap.name)
    2332           0 :                   filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
    2333             :                 else
    2334           0 :                   filter->usmap.map = NULL;
    2335             :               }
    2336             :         }
    2337           0 :       for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
    2338             :         {
    2339           0 :           for (afi = AFI_IP; afi < AFI_MAX; afi++)
    2340           0 :             for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    2341             :               {
    2342           0 :                 filter = &group->conf->filter[afi][safi];
    2343             :           
    2344           0 :                for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
    2345             :                   {
    2346           0 :                     if (filter->map[direct].name)
    2347           0 :                       filter->map[direct].map = 
    2348           0 :                         route_map_lookup_by_name (filter->map[direct].name);
    2349             :                     else
    2350           0 :                       filter->map[direct].map = NULL;
    2351             :                   }
    2352             : 
    2353           0 :                 if (filter->usmap.name)
    2354           0 :                   filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
    2355             :                 else
    2356           0 :                   filter->usmap.map = NULL;
    2357             :               }
    2358             :         }
    2359             :     }
    2360             : 
    2361             :   /* For default-originate route-map updates. */
    2362           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
    2363             :     {
    2364           0 :       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
    2365             :         {
    2366           0 :           for (afi = AFI_IP; afi < AFI_MAX; afi++)
    2367           0 :             for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    2368             :               {
    2369           0 :                 if (peer->default_rmap[afi][safi].name)
    2370           0 :                   peer->default_rmap[afi][safi].map =
    2371           0 :                     route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
    2372             :                 else
    2373           0 :                   peer->default_rmap[afi][safi].map = NULL;
    2374             :               }
    2375             :         }
    2376             :     }
    2377             : 
    2378             :   /* For network route-map updates. */
    2379           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
    2380             :     {
    2381           0 :       for (afi = AFI_IP; afi < AFI_MAX; afi++)
    2382           0 :         for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    2383           0 :           for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
    2384           0 :                bn = bgp_route_next (bn))
    2385           0 :             if ((bgp_static = bn->info) != NULL)
    2386             :               {
    2387           0 :                 if (bgp_static->rmap.name)
    2388           0 :                   bgp_static->rmap.map =
    2389           0 :                          route_map_lookup_by_name (bgp_static->rmap.name);
    2390             :                 else
    2391           0 :                   bgp_static->rmap.map = NULL;
    2392             :               }
    2393             :     }
    2394             : 
    2395             :   /* For redistribute route-map updates. */
    2396           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
    2397             :     {
    2398           0 :       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    2399             :         {
    2400           0 :           if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
    2401           0 :             bgp->rmap[ZEBRA_FAMILY_IPV4][i].map = 
    2402           0 :               route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
    2403             : #ifdef HAVE_IPV6
    2404           0 :           if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
    2405           0 :             bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
    2406           0 :               route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
    2407             : #endif /* HAVE_IPV6 */
    2408             :         }
    2409             :     }
    2410           0 : }
    2411             : 
    2412           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
    2421             : }
    2422             : 
    2423           0 : 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             : {
    2430           0 :   return bgp_route_match_add (vty, vty->index, "peer", "local");
    2431             : }
    2432             : 
    2433           0 : 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           0 :  if (argc == 0)
    2441           0 :    return bgp_route_match_delete (vty, vty->index, "peer", NULL);
    2442             : 
    2443           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
    2474             : }
    2475             : 
    2476           0 : 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           0 :   if (argc == 0)
    2485           0 :     return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
    2486             : 
    2487           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
    2512             : }
    2513             : 
    2514           0 : 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           0 :   if (argc == 0)
    2523           0 :     return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
    2524             : 
    2525           0 :   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             : 
    2539             : /* match probability { */
    2540             : 
    2541           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
    2549             : }
    2550             : 
    2551           0 : 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           0 :   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             : 
    2571           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
    2582             : }
    2583             : 
    2584           0 : 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           0 :   if (argc == 0)
    2593           0 :     return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
    2594             : 
    2595           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
    2619             : }
    2620             : 
    2621           0 : 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           0 :   if (argc == 0)
    2631           0 :     return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
    2632             : 
    2633           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
    2656             : }
    2657             : 
    2658           0 : 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           0 :   if (argc == 0)
    2668           0 :     return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
    2669             : 
    2670           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
    2693             : }
    2694             : 
    2695           0 : 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           0 :   if (argc == 0)
    2705           0 :     return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
    2706             : 
    2707           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
    2728             : }
    2729             : 
    2730           0 : 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           0 :   if (argc == 0)
    2738           0 :     return bgp_route_match_delete (vty, vty->index, "metric", NULL);
    2739             : 
    2740           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "community", argv[0]);
    2761             : }
    2762             : 
    2763           0 : 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           0 :   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
    2777             :                     strlen (argv[0]) + strlen ("exact-match") + 2);
    2778             : 
    2779           0 :   sprintf (argstr, "%s exact-match", argv[0]);
    2780             : 
    2781           0 :   ret = bgp_route_match_add (vty, vty->index, "community", argstr);
    2782             : 
    2783           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
    2784             : 
    2785           0 :   return ret;
    2786             : }
    2787             : 
    2788           0 : 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           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
    2829             : }
    2830             : 
    2831           0 : 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           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
    2859             : }
    2860             : 
    2861           0 : 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           0 :   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           0 : 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           0 :   if (strncmp (argv[0], "igp", 2) == 0)
    2889           0 :     return bgp_route_match_add (vty, vty->index, "origin", "igp");
    2890           0 :   if (strncmp (argv[0], "egp", 1) == 0)
    2891           0 :     return bgp_route_match_add (vty, vty->index, "origin", "egp");
    2892           0 :   if (strncmp (argv[0], "incomplete", 2) == 0)
    2893           0 :     return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
    2894             : 
    2895           0 :   return CMD_WARNING;
    2896             : }
    2897             : 
    2898           0 : 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           0 :   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           0 : 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           0 :   ret = str2sockunion (argv[0], &su);
    2930           0 :   if (ret < 0)
    2931             :     {
    2932           0 :       vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
    2933           0 :       return CMD_WARNING;
    2934             :     }
    2935             :  
    2936           0 :   return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
    2937             : }
    2938             : 
    2939           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
    2948             : }
    2949             : 
    2950           0 : 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           0 :   return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
    2960             : }
    2961             : 
    2962             : 
    2963           0 : 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           0 :   if (argc == 0)
    2971           0 :     return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
    2972             : 
    2973           0 :   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           0 : 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           0 :   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           0 : 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           0 :   if (argc == 0)
    3010           0 :     return bgp_route_set_delete (vty, vty->index, "metric", NULL);
    3011             : 
    3012           0 :   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           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
    3031             : }
    3032             : 
    3033           0 : 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           0 :   if (argc == 0)
    3041           0 :     return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
    3042             : 
    3043           0 :   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           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
    3062             : }
    3063             : 
    3064           0 : 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           0 :   if (argc == 0)
    3072           0 :     return bgp_route_set_delete (vty, vty->index, "weight", NULL);
    3073             :   
    3074           0 :   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           0 : 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           0 :   str = argv_concat (argv, argc, 0);
    3097           0 :   ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
    3098           0 :   XFREE (MTYPE_TMP, str);
    3099             : 
    3100           0 :   return ret;
    3101             : }
    3102             : 
    3103           0 : 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           0 :   if (argc == 0)
    3115           0 :     return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
    3116             : 
    3117           0 :   str = argv_concat (argv, argc, 0);
    3118           0 :   ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
    3119           0 :   XFREE (MTYPE_TMP, str);
    3120           0 :   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           0 : 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           0 :   str = argv_concat (argv, argc, 0);
    3144           0 :   ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
    3145           0 :   XFREE (MTYPE_TMP, str);
    3146           0 :   return ret;
    3147             : }
    3148             : 
    3149           0 : 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           0 :   if (argc == 0)
    3161           0 :     return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
    3162             : 
    3163           0 :   str = argv_concat (argv, argc, 0);
    3164           0 :   ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
    3165           0 :   XFREE (MTYPE_TMP, str);
    3166           0 :   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           0 : 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           0 :   int first = 0;
    3187           0 :   int additive = 0;
    3188             :   struct buffer *b;
    3189           0 :   struct community *com = NULL;
    3190             :   char *str;
    3191             :   char *argstr;
    3192             :   int ret;
    3193             : 
    3194           0 :   b = buffer_new (1024);
    3195             : 
    3196           0 :   for (i = 0; i < argc; i++)
    3197             :     {
    3198           0 :       if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
    3199             :         {
    3200           0 :           additive = 1;
    3201           0 :           continue;
    3202             :         }
    3203             : 
    3204           0 :       if (first)
    3205           0 :         buffer_putc (b, ' ');
    3206             :       else
    3207           0 :         first = 1;
    3208             : 
    3209           0 :       if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
    3210             :         {
    3211           0 :           buffer_putstr (b, "internet");
    3212           0 :           continue;
    3213             :         }
    3214           0 :       if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
    3215             :         {
    3216           0 :           buffer_putstr (b, "local-AS");
    3217           0 :           continue;
    3218             :         }
    3219           0 :       if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
    3220           0 :           && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
    3221             :         {
    3222           0 :           buffer_putstr (b, "no-advertise");
    3223           0 :           continue;
    3224             :         }
    3225           0 :       if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
    3226           0 :           && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
    3227             :         {
    3228           0 :           buffer_putstr (b, "no-export");
    3229           0 :           continue;
    3230             :         }
    3231           0 :       buffer_putstr (b, argv[i]);
    3232             :     }
    3233           0 :   buffer_putc (b, '\0');
    3234             : 
    3235             :   /* Fetch result string then compile it to communities attribute.  */
    3236           0 :   str = buffer_getstr (b);
    3237           0 :   buffer_free (b);
    3238             : 
    3239           0 :   if (str)
    3240             :     {
    3241           0 :       com = community_str2com (str);
    3242           0 :       XFREE (MTYPE_TMP, str);
    3243             :     }
    3244             : 
    3245             :   /* Can't compile user input into communities attribute.  */
    3246           0 :   if (! com)
    3247             :     {
    3248           0 :       vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
    3249           0 :       return CMD_WARNING;
    3250             :     }
    3251             : 
    3252             :   /* Set communites attribute string.  */
    3253           0 :   str = community_str (com);
    3254             : 
    3255           0 :   if (additive)
    3256             :     {
    3257           0 :       argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
    3258           0 :       strcpy (argstr, str);
    3259           0 :       strcpy (argstr + strlen (str), " additive");
    3260           0 :       ret =  bgp_route_set_add (vty, vty->index, "community", argstr);
    3261           0 :       XFREE (MTYPE_TMP, argstr);
    3262             :     }
    3263             :   else
    3264           0 :     ret =  bgp_route_set_add (vty, vty->index, "community", str);
    3265             : 
    3266           0 :   community_free (com);
    3267             : 
    3268           0 :   return ret;
    3269             : }
    3270             : 
    3271           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "community", "none");
    3279             : }
    3280             : 
    3281           0 : 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           0 :   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           0 : 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           0 :   str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
    3320           0 :   strcpy (str, argv[0]);
    3321           0 :   strcpy (str + strlen (argv[0]), " delete");
    3322             : 
    3323           0 :   bgp_route_set_add (vty, vty->index, "comm-list", str);
    3324             : 
    3325           0 :   XFREE (MTYPE_TMP, str);
    3326           0 :   return CMD_SUCCESS;
    3327             : }
    3328             : 
    3329           0 : 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           0 :   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           0 : 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           0 :   str = argv_concat (argv, argc, 0);
    3362           0 :   ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
    3363           0 :   XFREE (MTYPE_TMP, str);
    3364             : 
    3365           0 :   return ret;
    3366             : }
    3367             : 
    3368           0 : 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           0 :   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           0 : 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           0 :   str = argv_concat (argv, argc, 0);
    3400           0 :   ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
    3401           0 :   XFREE (MTYPE_TMP, str);
    3402           0 :   return ret;
    3403             : }
    3404             : 
    3405           0 : 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           0 :   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           0 : 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           0 :   if (strncmp (argv[0], "igp", 2) == 0)
    3435           0 :     return bgp_route_set_add (vty, vty->index, "origin", "igp");
    3436           0 :   if (strncmp (argv[0], "egp", 1) == 0)
    3437           0 :     return bgp_route_set_add (vty, vty->index, "origin", "egp");
    3438           0 :   if (strncmp (argv[0], "incomplete", 2) == 0)
    3439           0 :     return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
    3440             : 
    3441           0 :   return CMD_WARNING;
    3442             : }
    3443             : 
    3444           0 : 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           0 :   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           0 : DEFUN (set_atomic_aggregate,
    3465             :        set_atomic_aggregate_cmd,
    3466             :        "set atomic-aggregate",
    3467             :        SET_STR
    3468             :        "BGP atomic aggregate attribute\n" )
    3469             : {
    3470           0 :   return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
    3471             : }
    3472             : 
    3473           0 : 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           0 :   return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
    3481             : }
    3482             : 
    3483           0 : 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           0 :   VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
    3498             :   
    3499           0 :   ret = inet_aton (argv[1], &address);
    3500           0 :   if (ret == 0)
    3501             :     {
    3502           0 :       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
    3503           0 :       return CMD_WARNING;
    3504             :     }
    3505             : 
    3506           0 :   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
    3507             :                     strlen (argv[0]) + strlen (argv[1]) + 2);
    3508             : 
    3509           0 :   sprintf (argstr, "%s %s", argv[0], argv[1]);
    3510             : 
    3511           0 :   ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
    3512             : 
    3513           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
    3514             : 
    3515           0 :   return ret;
    3516             : }
    3517             : 
    3518           0 : 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           0 :   if (argv == 0)
    3532           0 :     return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
    3533             :   
    3534           0 :   VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
    3535             : 
    3536           0 :   ret = inet_aton (argv[1], &address);
    3537           0 :   if (ret == 0)
    3538             :     {
    3539           0 :       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
    3540           0 :       return CMD_WARNING;
    3541             :     }
    3542             : 
    3543           0 :   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
    3544             :                     strlen (argv[0]) + strlen (argv[1]) + 2);
    3545             : 
    3546           0 :   sprintf (argstr, "%s %s", argv[0], argv[1]);
    3547             : 
    3548           0 :   ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
    3549             : 
    3550           0 :   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
    3551             : 
    3552           0 :   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           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
    3576             : }
    3577             : 
    3578           0 : 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           0 :   return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
    3588             : }
    3589             : 
    3590           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
    3599             : }
    3600             : 
    3601           0 : 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           0 :   return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
    3611             : }
    3612             : 
    3613           0 : 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           0 :   return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
    3623             : }
    3624             : 
    3625           0 : 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           0 :   return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
    3636             : }
    3637             : 
    3638           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
    3648             : }
    3649             : 
    3650           0 : 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           0 :   if (argc == 0)
    3660           0 :     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
    3661             : 
    3662           0 :   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           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
    3685             : }
    3686             : 
    3687           0 : 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           0 :   if (argc == 0)
    3697           0 :     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
    3698             :   
    3699           0 :   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           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
    3722             : }
    3723             : 
    3724           0 : 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           0 :   if (argc == 0)
    3733           0 :     return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
    3734             : 
    3735           0 :   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           0 : 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           0 :   return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
    3755             : }
    3756             : 
    3757           0 : 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           0 :   if (argc == 0)
    3765           0 :     return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
    3766             :   
    3767           0 :   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           0 : 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           0 :   return CMD_SUCCESS;
    3786             : }
    3787             : 
    3788           0 : 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           0 :   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           0 : 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           0 :   return CMD_SUCCESS;
    3815             : }
    3816             : 
    3817           0 : 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           0 :   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           0 : bgp_route_map_init (void)
    3840             : {
    3841           0 :   route_map_init ();
    3842           0 :   route_map_init_vty ();
    3843           0 :   route_map_add_hook (bgp_route_map_update);
    3844           0 :   route_map_delete_hook (bgp_route_map_update);
    3845             : 
    3846           0 :   route_map_install_match (&route_match_peer_cmd);
    3847           0 :   route_map_install_match (&route_match_ip_address_cmd);
    3848           0 :   route_map_install_match (&route_match_ip_next_hop_cmd);
    3849           0 :   route_map_install_match (&route_match_ip_route_source_cmd);
    3850           0 :   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
    3851           0 :   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
    3852           0 :   route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
    3853           0 :   route_map_install_match (&route_match_aspath_cmd);
    3854           0 :   route_map_install_match (&route_match_community_cmd);
    3855           0 :   route_map_install_match (&route_match_ecommunity_cmd);
    3856           0 :   route_map_install_match (&route_match_metric_cmd);
    3857           0 :   route_map_install_match (&route_match_origin_cmd);
    3858           0 :   route_map_install_match (&route_match_probability_cmd);
    3859             : 
    3860           0 :   route_map_install_set (&route_set_ip_nexthop_cmd);
    3861           0 :   route_map_install_set (&route_set_local_pref_cmd);
    3862           0 :   route_map_install_set (&route_set_weight_cmd);
    3863           0 :   route_map_install_set (&route_set_metric_cmd);
    3864           0 :   route_map_install_set (&route_set_aspath_prepend_cmd);
    3865           0 :   route_map_install_set (&route_set_aspath_exclude_cmd);
    3866           0 :   route_map_install_set (&route_set_origin_cmd);
    3867           0 :   route_map_install_set (&route_set_atomic_aggregate_cmd);
    3868           0 :   route_map_install_set (&route_set_aggregator_as_cmd);
    3869           0 :   route_map_install_set (&route_set_community_cmd);
    3870           0 :   route_map_install_set (&route_set_community_delete_cmd);
    3871           0 :   route_map_install_set (&route_set_vpnv4_nexthop_cmd);
    3872           0 :   route_map_install_set (&route_set_originator_id_cmd);
    3873           0 :   route_map_install_set (&route_set_ecommunity_rt_cmd);
    3874           0 :   route_map_install_set (&route_set_ecommunity_soo_cmd);
    3875             : 
    3876           0 :   install_element (RMAP_NODE, &match_peer_cmd);
    3877           0 :   install_element (RMAP_NODE, &match_peer_local_cmd);
    3878           0 :   install_element (RMAP_NODE, &no_match_peer_cmd);
    3879           0 :   install_element (RMAP_NODE, &no_match_peer_val_cmd);
    3880           0 :   install_element (RMAP_NODE, &no_match_peer_local_cmd);
    3881           0 :   install_element (RMAP_NODE, &match_ip_address_cmd);
    3882           0 :   install_element (RMAP_NODE, &no_match_ip_address_cmd);
    3883           0 :   install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
    3884           0 :   install_element (RMAP_NODE, &match_ip_next_hop_cmd);
    3885           0 :   install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
    3886           0 :   install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
    3887           0 :   install_element (RMAP_NODE, &match_ip_route_source_cmd);
    3888           0 :   install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
    3889           0 :   install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
    3890           0 :   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
    3891           0 :   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
    3892           0 :   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
    3893           0 :   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
    3894           0 :   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
    3895           0 :   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
    3896           0 :   install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
    3897           0 :   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
    3898           0 :   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
    3899             : 
    3900           0 :   install_element (RMAP_NODE, &match_aspath_cmd);
    3901           0 :   install_element (RMAP_NODE, &no_match_aspath_cmd);
    3902           0 :   install_element (RMAP_NODE, &no_match_aspath_val_cmd);
    3903           0 :   install_element (RMAP_NODE, &match_metric_cmd);
    3904           0 :   install_element (RMAP_NODE, &no_match_metric_cmd);
    3905           0 :   install_element (RMAP_NODE, &no_match_metric_val_cmd);
    3906           0 :   install_element (RMAP_NODE, &match_community_cmd);
    3907           0 :   install_element (RMAP_NODE, &match_community_exact_cmd);
    3908           0 :   install_element (RMAP_NODE, &no_match_community_cmd);
    3909           0 :   install_element (RMAP_NODE, &no_match_community_val_cmd);
    3910           0 :   install_element (RMAP_NODE, &no_match_community_exact_cmd);
    3911           0 :   install_element (RMAP_NODE, &match_ecommunity_cmd);
    3912           0 :   install_element (RMAP_NODE, &no_match_ecommunity_cmd);
    3913           0 :   install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
    3914           0 :   install_element (RMAP_NODE, &match_origin_cmd);
    3915           0 :   install_element (RMAP_NODE, &no_match_origin_cmd);
    3916           0 :   install_element (RMAP_NODE, &no_match_origin_val_cmd);
    3917           0 :   install_element (RMAP_NODE, &match_probability_cmd);
    3918           0 :   install_element (RMAP_NODE, &no_match_probability_cmd);
    3919           0 :   install_element (RMAP_NODE, &no_match_probability_val_cmd);
    3920             : 
    3921           0 :   install_element (RMAP_NODE, &set_ip_nexthop_cmd);
    3922           0 :   install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
    3923           0 :   install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
    3924           0 :   install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
    3925           0 :   install_element (RMAP_NODE, &set_local_pref_cmd);
    3926           0 :   install_element (RMAP_NODE, &no_set_local_pref_cmd);
    3927           0 :   install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
    3928           0 :   install_element (RMAP_NODE, &set_weight_cmd);
    3929           0 :   install_element (RMAP_NODE, &no_set_weight_cmd);
    3930           0 :   install_element (RMAP_NODE, &no_set_weight_val_cmd);
    3931           0 :   install_element (RMAP_NODE, &set_metric_cmd);
    3932           0 :   install_element (RMAP_NODE, &set_metric_addsub_cmd);
    3933           0 :   install_element (RMAP_NODE, &no_set_metric_cmd);
    3934           0 :   install_element (RMAP_NODE, &no_set_metric_val_cmd);
    3935           0 :   install_element (RMAP_NODE, &set_aspath_prepend_cmd);
    3936           0 :   install_element (RMAP_NODE, &set_aspath_exclude_cmd);
    3937           0 :   install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
    3938           0 :   install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
    3939           0 :   install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
    3940           0 :   install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
    3941           0 :   install_element (RMAP_NODE, &set_origin_cmd);
    3942           0 :   install_element (RMAP_NODE, &no_set_origin_cmd);
    3943           0 :   install_element (RMAP_NODE, &no_set_origin_val_cmd);
    3944           0 :   install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
    3945           0 :   install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
    3946           0 :   install_element (RMAP_NODE, &set_aggregator_as_cmd);
    3947           0 :   install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
    3948           0 :   install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
    3949           0 :   install_element (RMAP_NODE, &set_community_cmd);
    3950           0 :   install_element (RMAP_NODE, &set_community_none_cmd);
    3951           0 :   install_element (RMAP_NODE, &no_set_community_cmd);
    3952           0 :   install_element (RMAP_NODE, &no_set_community_val_cmd);
    3953           0 :   install_element (RMAP_NODE, &no_set_community_none_cmd);
    3954           0 :   install_element (RMAP_NODE, &set_community_delete_cmd);
    3955           0 :   install_element (RMAP_NODE, &no_set_community_delete_cmd);
    3956           0 :   install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
    3957           0 :   install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
    3958           0 :   install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
    3959           0 :   install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
    3960           0 :   install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
    3961           0 :   install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
    3962           0 :   install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
    3963           0 :   install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
    3964           0 :   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
    3965           0 :   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
    3966           0 :   install_element (RMAP_NODE, &set_originator_id_cmd);
    3967           0 :   install_element (RMAP_NODE, &no_set_originator_id_cmd);
    3968           0 :   install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
    3969             : 
    3970             : #ifdef HAVE_IPV6
    3971           0 :   route_map_install_match (&route_match_ipv6_address_cmd);
    3972           0 :   route_map_install_match (&route_match_ipv6_next_hop_cmd);
    3973           0 :   route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
    3974           0 :   route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
    3975           0 :   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
    3976             :   
    3977           0 :   install_element (RMAP_NODE, &match_ipv6_address_cmd);
    3978           0 :   install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
    3979           0 :   install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
    3980           0 :   install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
    3981           0 :   install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
    3982           0 :   install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
    3983           0 :   install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
    3984           0 :   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
    3985           0 :   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
    3986           0 :   install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
    3987           0 :   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
    3988           0 :   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           0 :   install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
    3995           0 :   install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
    3996           0 :   install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
    3997           0 :   install_element (RMAP_NODE, &match_pathlimit_as_cmd);
    3998           0 :   install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
    3999           0 :   install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
    4000           0 : }

Generated by: LCOV version 1.10