Diff for /embedaddon/quagga/bgpd/bgp_routemap.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/21 23:54:38 version 1.1.1.4, 2016/11/02 10:09:10
Line 93  o Cisco route-map Line 93  o Cisco route-map
       tag               :  (This will not be implemented by bgpd)        tag               :  (This will not be implemented by bgpd)
       weight            :  Done        weight            :  Done
   
o Local extentiono Local extensions
   
   set ipv6 next-hop global: Done    set ipv6 next-hop global: Done
   set ipv6 next-hop local : Done    set ipv6 next-hop local : Done
   set as-path exclude     : Done    set as-path exclude     : Done
   
 */   */ 
  /* generic value manipulation to be shared in multiple rules */
 
 #define RMAP_VALUE_SET 0
 #define RMAP_VALUE_ADD 1
 #define RMAP_VALUE_SUB 2
 
 struct rmap_value
 {
   u_int8_t action;
   u_int8_t variable;
   u_int32_t value;
 };
 
 static int
 route_value_match (struct rmap_value *rv, u_int32_t value)
 {
   if (rv->variable == 0 && value == rv->value)
     return RMAP_MATCH;
 
   return RMAP_NOMATCH;
 }
 
 static u_int32_t
 route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
 {
   u_int32_t value;
 
   switch (rv->variable)
     {
     case 1:
       value = peer->rtt;
       break;
     default:
       value = rv->value;
       break;
     }
 
   switch (rv->action)
     {
     case RMAP_VALUE_ADD:
       if (current > UINT32_MAX-value)
         return UINT32_MAX;
       return current + value;
     case RMAP_VALUE_SUB:
       if (current <= value)
         return 0;
       return current - value;
     default:
       return value;
     }
 }
 
 static void *
 route_value_compile (const char *arg)
 {
   u_int8_t action = RMAP_VALUE_SET, var = 0;
   unsigned long larg = 0;
   char *endptr = NULL;
   struct rmap_value *rv;
 
   if (arg[0] == '+')
     {
       action = RMAP_VALUE_ADD;
       arg++;
     }
   else if (arg[0] == '-')
     {
       action = RMAP_VALUE_SUB;
       arg++;
     }
 
   if (all_digit(arg))
     {
       errno = 0;
       larg = strtoul (arg, &endptr, 10);
       if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
         return NULL;
     }
   else
     {
       if (strcmp(arg, "rtt") == 0)
         var = 1;
       else
         return NULL;
     }
 
   rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
   if (!rv)
     return NULL;
 
   rv->action = action;
   rv->variable = var;
   rv->value = larg;
   return rv;
 }
 
 static void
 route_value_free (void *rule)
 {
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 }
 
  /* generic as path object to be shared in multiple rules */
 
 static void *
 route_aspath_compile (const char *arg)
 {
   struct aspath *aspath;
 
   aspath = aspath_str2aspath (arg);
   if (! aspath)
     return NULL;
   return aspath;
 }
 
 static void
 route_aspath_free (void *rule)
 {
   struct aspath *aspath = rule;
   aspath_free (aspath);
 }
 
  /* 'match peer (A.B.C.D|X:X::X:X)' */   /* 'match peer (A.B.C.D|X:X::X:X)' */
   
 /* Compares the peer specified in the 'match peer' clause with the peer  /* Compares the peer specified in the 'match peer' clause with the peer
Line 111  route_match_peer (void *rule, struct prefix *prefix, r Line 233  route_match_peer (void *rule, struct prefix *prefix, r
       void *object)        void *object)
 {  {
   union sockunion *su;    union sockunion *su;
  union sockunion su_def = { .sa.sa_family = AF_INET,  union sockunion su_def = { .sin = { .sin_family = AF_INET,
                             .sin.sin_addr.s_addr = INADDR_ANY };                                      .sin_addr.s_addr = INADDR_ANY } };
   struct peer_group *group;    struct peer_group *group;
   struct peer *peer;    struct peer *peer;
   struct listnode *node, *nnode;    struct listnode *node, *nnode;
Line 240  struct route_map_rule_cmd route_match_ip_address_cmd = Line 362  struct route_map_rule_cmd route_match_ip_address_cmd =
   route_match_ip_address_compile,    route_match_ip_address_compile,
   route_match_ip_address_free    route_match_ip_address_free
 };  };
 /* `match ip next-hop IP_ADDRESS' */  /* `match ip next-hop IP_ADDRESS' */
   
 /* Match function return 1 if match is success else return zero. */  /* Match function return 1 if match is success else return zero. */
Line 292  struct route_map_rule_cmd route_match_ip_next_hop_cmd  Line 414  struct route_map_rule_cmd route_match_ip_next_hop_cmd 
   route_match_ip_next_hop_compile,    route_match_ip_next_hop_compile,
   route_match_ip_next_hop_free    route_match_ip_next_hop_free
 };  };
 /* `match ip route-source ACCESS-LIST' */  /* `match ip route-source ACCESS-LIST' */
   
 /* Match function return 1 if match is success else return zero. */  /* Match function return 1 if match is success else return zero. */
Line 350  struct route_map_rule_cmd route_match_ip_route_source_ Line 472  struct route_map_rule_cmd route_match_ip_route_source_
   route_match_ip_route_source_compile,    route_match_ip_route_source_compile,
   route_match_ip_route_source_free    route_match_ip_route_source_free
 };  };
 /* `match ip address prefix-list PREFIX_LIST' */  /* `match ip address prefix-list PREFIX_LIST' */
   
 static route_map_result_t  static route_map_result_t
Line 390  struct route_map_rule_cmd route_match_ip_address_prefi Line 512  struct route_map_rule_cmd route_match_ip_address_prefi
   route_match_ip_address_prefix_list_compile,    route_match_ip_address_prefix_list_compile,
   route_match_ip_address_prefix_list_free    route_match_ip_address_prefix_list_free
 };  };
 /* `match ip next-hop prefix-list PREFIX_LIST' */  /* `match ip next-hop prefix-list PREFIX_LIST' */
   
 static route_map_result_t  static route_map_result_t
Line 437  struct route_map_rule_cmd route_match_ip_next_hop_pref Line 559  struct route_map_rule_cmd route_match_ip_next_hop_pref
   route_match_ip_next_hop_prefix_list_compile,    route_match_ip_next_hop_prefix_list_compile,
   route_match_ip_next_hop_prefix_list_free    route_match_ip_next_hop_prefix_list_free
 };  };
 /* `match ip route-source prefix-list PREFIX_LIST' */  /* `match ip route-source prefix-list PREFIX_LIST' */
   
 static route_map_result_t  static route_map_result_t
Line 490  struct route_map_rule_cmd route_match_ip_route_source_ Line 612  struct route_map_rule_cmd route_match_ip_route_source_
   route_match_ip_route_source_prefix_list_compile,    route_match_ip_route_source_prefix_list_compile,
   route_match_ip_route_source_prefix_list_free    route_match_ip_route_source_prefix_list_free
 };  };
 /* `match metric METRIC' */  /* `match metric METRIC' */
   
 /* Match function return 1 if match is success else return zero. */  /* Match function return 1 if match is success else return zero. */
Line 498  static route_map_result_t Line 620  static route_map_result_t
 route_match_metric (void *rule, struct prefix *prefix,   route_match_metric (void *rule, struct prefix *prefix, 
                     route_map_object_t type, void *object)                      route_map_object_t type, void *object)
 {  {
  u_int32_t *med;  struct rmap_value *rv;
   struct bgp_info *bgp_info;    struct bgp_info *bgp_info;
   
   if (type == RMAP_BGP)    if (type == RMAP_BGP)
     {      {
      med = rule;      rv = rule;
       bgp_info = object;        bgp_info = object;
          return route_value_match(rv, bgp_info->attr->med);
      if (bgp_info->attr->med == *med) 
        return RMAP_MATCH; 
      else 
        return RMAP_NOMATCH; 
     }      }
   return RMAP_NOMATCH;    return RMAP_NOMATCH;
 }  }
   
 /* Route map `match metric' match statement. `arg' is MED value */  
 static void *  
 route_match_metric_compile (const char *arg)  
 {  
   u_int32_t *med;  
   char *endptr = NULL;  
   unsigned long tmpval;  
   
   /* Metric value shoud be integer. */  
   if (! all_digit (arg))  
     return NULL;  
   
   errno = 0;  
   tmpval = strtoul (arg, &endptr, 10);  
   if (*endptr != '\0' || errno || tmpval > UINT32_MAX)  
     return NULL;  
       
   med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));  
     
   if (!med)  
     return med;  
     
   *med = tmpval;  
   return med;  
 }  
   
 /* Free route map's compiled `match metric' value. */  
 static void  
 route_match_metric_free (void *rule)  
 {  
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);  
 }  
   
 /* Route map commands for metric matching. */  /* Route map commands for metric matching. */
 struct route_map_rule_cmd route_match_metric_cmd =  struct route_map_rule_cmd route_match_metric_cmd =
 {  {
   "metric",    "metric",
   route_match_metric,    route_match_metric,
  route_match_metric_compile,  route_value_compile,
  route_match_metric_free  route_value_free,
 };  };
 /* `match as-path ASPATH' */  /* `match as-path ASPATH' */
   
 /* Match function for as-path match.  I assume given object is */  /* Match function for as-path match.  I assume given object is */
Line 603  struct route_map_rule_cmd route_match_aspath_cmd =  Line 688  struct route_map_rule_cmd route_match_aspath_cmd = 
   route_match_aspath_compile,    route_match_aspath_compile,
   route_match_aspath_free    route_match_aspath_free
 };  };
 /* `match community COMMUNIY' */  /* `match community COMMUNIY' */
 struct rmap_community  struct rmap_community
 {  {
Line 687  struct route_map_rule_cmd route_match_community_cmd =  Line 772  struct route_map_rule_cmd route_match_community_cmd = 
   route_match_community_compile,    route_match_community_compile,
   route_match_community_free    route_match_community_free
 };  };
 /* Match function for extcommunity match. */  /* Match function for extcommunity match. */
 static route_map_result_t  static route_map_result_t
 route_match_ecommunity (void *rule, struct prefix *prefix,   route_match_ecommunity (void *rule, struct prefix *prefix, 
Line 736  struct route_map_rule_cmd route_match_ecommunity_cmd = Line 821  struct route_map_rule_cmd route_match_ecommunity_cmd =
   route_match_ecommunity_compile,    route_match_ecommunity_compile,
   route_match_ecommunity_free    route_match_ecommunity_free
 };  };
 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`  /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
    and `address-family vpnv4'.  */     and `address-family vpnv4'.  */
 /* `match origin' */  /* `match origin' */
 static route_map_result_t  static route_map_result_t
 route_match_origin (void *rule, struct prefix *prefix,   route_match_origin (void *rule, struct prefix *prefix, 
Line 799  static route_map_result_t Line 884  static route_map_result_t
 route_match_probability (void *rule, struct prefix *prefix,  route_match_probability (void *rule, struct prefix *prefix,
                     route_map_object_t type, void *object)                      route_map_object_t type, void *object)
 {  {
  long r;  long r = random();
#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 
  r = random(); 
#else 
  r = (long) rand(); 
#endif 
   
  switch (*(unsigned *) rule)  switch (*(long *) rule)
   {    {
     case 0: break;      case 0: break;
     case RAND_MAX: return RMAP_MATCH;      case RAND_MAX: return RMAP_MATCH;
     default:      default:
      if (r < *(unsigned *) rule)      if (r < *(long *) rule)
         {          {
           return RMAP_MATCH;            return RMAP_MATCH;
         }          }
Line 823  route_match_probability (void *rule, struct prefix *pr Line 903  route_match_probability (void *rule, struct prefix *pr
 static void *  static void *
 route_match_probability_compile (const char *arg)  route_match_probability_compile (const char *arg)
 {  {
  unsigned *lobule;  long *lobule;
   unsigned  perc;    unsigned  perc;
   
 #if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500  
   srandom (time (NULL));  
 #else  
   srand (time (NULL));  
 #endif  
   
   perc    = atoi (arg);    perc    = atoi (arg);
  lobule  = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));  lobule  = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
   
   switch (perc)    switch (perc)
     {      {
Line 964  struct route_map_rule_cmd route_set_ip_nexthop_cmd = Line 1038  struct route_map_rule_cmd route_set_ip_nexthop_cmd =
   route_set_ip_nexthop_compile,    route_set_ip_nexthop_compile,
   route_set_ip_nexthop_free    route_set_ip_nexthop_free
 };  };
 /* `set local-preference LOCAL_PREF' */  /* `set local-preference LOCAL_PREF' */
   
 /* Set local preference. */  /* Set local preference. */
Line 972  static route_map_result_t Line 1046  static route_map_result_t
 route_set_local_pref (void *rule, struct prefix *prefix,  route_set_local_pref (void *rule, struct prefix *prefix,
                       route_map_object_t type, void *object)                        route_map_object_t type, void *object)
 {  {
  u_int32_t *local_pref;  struct rmap_value *rv;
   struct bgp_info *bgp_info;    struct bgp_info *bgp_info;
     u_int32_t locpref = 0;
   
   if (type == RMAP_BGP)    if (type == RMAP_BGP)
     {      {
       /* Fetch routemap's rule information. */        /* Fetch routemap's rule information. */
      local_pref = rule;      rv = rule;
       bgp_info = object;        bgp_info = object;
           
       /* Set local preference value. */         /* Set local preference value. */ 
         if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
           locpref = bgp_info->attr->local_pref;
   
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);        bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
      bgp_info->attr->local_pref = *local_pref;      bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
     }      }
   
   return RMAP_OKAY;    return RMAP_OKAY;
 }  }
   
 /* set local preference compilation. */  
 static void *  
 route_set_local_pref_compile (const char *arg)  
 {  
   unsigned long tmp;  
   u_int32_t *local_pref;  
   char *endptr = NULL;  
   
   /* Local preference value shoud be integer. */  
   if (! all_digit (arg))  
     return NULL;  
     
   errno = 0;  
   tmp = strtoul (arg, &endptr, 10);  
   if (*endptr != '\0' || errno || tmp > UINT32_MAX)  
     return NULL;  
      
   local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));   
     
   if (!local_pref)  
     return local_pref;  
     
   *local_pref = tmp;  
     
   return local_pref;  
 }  
   
 /* Free route map's local preference value. */  
 static void  
 route_set_local_pref_free (void *rule)  
 {  
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);  
 }  
   
 /* Set local preference rule structure. */  /* Set local preference rule structure. */
 struct route_map_rule_cmd route_set_local_pref_cmd =   struct route_map_rule_cmd route_set_local_pref_cmd = 
 {  {
   "local-preference",    "local-preference",
   route_set_local_pref,    route_set_local_pref,
  route_set_local_pref_compile,  route_value_compile,
  route_set_local_pref_free,  route_value_free,
 };  };
 /* `set weight WEIGHT' */  /* `set weight WEIGHT' */
   
 /* Set weight. */  /* Set weight. */
Line 1039  static route_map_result_t Line 1083  static route_map_result_t
 route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,  route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
                   void *object)                    void *object)
 {  {
  u_int32_t *weight;  struct rmap_value *rv;
   struct bgp_info *bgp_info;    struct bgp_info *bgp_info;
     u_int32_t weight;
   
   if (type == RMAP_BGP)    if (type == RMAP_BGP)
     {      {
       /* Fetch routemap's rule information. */        /* Fetch routemap's rule information. */
      weight = rule;      rv = rule;
       bgp_info = object;        bgp_info = object;
           
       /* Set weight value. */         /* Set weight value. */ 
      if (*weight)      weight = route_value_adjust(rv, 0, bgp_info->peer);
        (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;      if (weight)
         (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
       else if (bgp_info->attr->extra)        else if (bgp_info->attr->extra)
         bgp_info->attr->extra->weight = 0;          bgp_info->attr->extra->weight = 0;
     }      }
Line 1058  route_set_weight (void *rule, struct prefix *prefix, r Line 1104  route_set_weight (void *rule, struct prefix *prefix, r
   return RMAP_OKAY;    return RMAP_OKAY;
 }  }
   
 /* set local preference compilation. */  
 static void *  
 route_set_weight_compile (const char *arg)  
 {  
   unsigned long tmp;  
   u_int32_t *weight;  
   char *endptr = NULL;  
   
   /* Local preference value shoud be integer. */  
   if (! all_digit (arg))  
     return NULL;  
   
   errno = 0;  
   tmp = strtoul (arg, &endptr, 10);  
   if (*endptr != '\0' || errno || tmp > UINT32_MAX)  
     return NULL;  
     
   weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));  
     
   if (weight == NULL)  
     return weight;  
     
   *weight = tmp;    
     
   return weight;  
 }  
   
 /* Free route map's local preference value. */  
 static void  
 route_set_weight_free (void *rule)  
 {  
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);  
 }  
   
 /* Set local preference rule structure. */  /* Set local preference rule structure. */
 struct route_map_rule_cmd route_set_weight_cmd =   struct route_map_rule_cmd route_set_weight_cmd = 
 {  {
   "weight",    "weight",
   route_set_weight,    route_set_weight,
  route_set_weight_compile,  route_value_compile,
  route_set_weight_free,  route_value_free,
 };  };
 /* `set metric METRIC' */  /* `set metric METRIC' */
   
 /* Set metric to attribute. */  /* Set metric to attribute. */
Line 1108  static route_map_result_t Line 1120  static route_map_result_t
 route_set_metric (void *rule, struct prefix *prefix,   route_set_metric (void *rule, struct prefix *prefix, 
                   route_map_object_t type, void *object)                    route_map_object_t type, void *object)
 {  {
  char *metric;  struct rmap_value *rv;
  u_int32_t metric_val; 
   struct bgp_info *bgp_info;    struct bgp_info *bgp_info;
     u_int32_t med = 0;
   
   if (type == RMAP_BGP)    if (type == RMAP_BGP)
     {      {
       /* Fetch routemap's rule information. */        /* Fetch routemap's rule information. */
      metric = rule;      rv = rule;
       bgp_info = object;        bgp_info = object;
   
      if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))      if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
        bgp_info->attr->med = 0;        med = bgp_info->attr->med;
      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); 
   
      if (all_digit (metric))      bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
        {      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
          metric_val = strtoul (metric, (char **)NULL, 10); 
          bgp_info->attr->med = metric_val; 
        } 
      else 
        { 
          metric_val = strtoul (metric+1, (char **)NULL, 10); 
 
          if (strncmp (metric, "+", 1) == 0) 
            { 
              if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2) 
                bgp_info->attr->med = BGP_MED_MAX - 1; 
              else 
                bgp_info->attr->med += metric_val; 
            } 
          else if (strncmp (metric, "-", 1) == 0) 
            { 
              if (bgp_info->attr->med <= metric_val) 
                bgp_info->attr->med = 0; 
              else 
                bgp_info->attr->med -= metric_val; 
            } 
        } 
     }      }
   return RMAP_OKAY;    return RMAP_OKAY;
 }  }
   
 /* set metric compilation. */  
 static void *  
 route_set_metric_compile (const char *arg)  
 {  
   u_int32_t metric;  
   unsigned long larg;  
   char *endptr = NULL;  
   
   if (all_digit (arg))  
     {  
       /* set metric value check*/  
       errno = 0;  
       larg = strtoul (arg, &endptr, 10);  
       if (*endptr != '\0' || errno || larg > UINT32_MAX)  
         return NULL;  
       metric = larg;  
     }  
   else  
     {  
       /* set metric +/-value check */  
       if ((strncmp (arg, "+", 1) != 0  
            && strncmp (arg, "-", 1) != 0)  
            || (! all_digit (arg+1)))  
         return NULL;  
   
       errno = 0;  
       larg = strtoul (arg+1, &endptr, 10);  
       if (*endptr != '\0' || errno || larg > UINT32_MAX)  
         return NULL;  
       metric = larg;  
     }  
   
   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);  
 }  
   
 /* Free route map's compiled `set metric' value. */  
 static void  
 route_set_metric_free (void *rule)  
 {  
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);  
 }  
   
 /* Set metric rule structure. */  /* Set metric rule structure. */
 struct route_map_rule_cmd route_set_metric_cmd =   struct route_map_rule_cmd route_set_metric_cmd = 
 {  {
   "metric",    "metric",
   route_set_metric,    route_set_metric,
  route_set_metric_compile,  route_value_compile,
  route_set_metric_free,  route_value_free,
 };  };
 /* `set as-path prepend ASPATH' */  /* `set as-path prepend ASPATH' */
   
 /* For AS path prepend mechanism. */  /* For AS path prepend mechanism. */
Line 1213  route_set_aspath_prepend (void *rule, struct prefix *p Line 1160  route_set_aspath_prepend (void *rule, struct prefix *p
   
   if (type == RMAP_BGP)    if (type == RMAP_BGP)
     {      {
       aspath = rule;  
       binfo = object;        binfo = object;
           
       if (binfo->attr->aspath->refcnt)        if (binfo->attr->aspath->refcnt)
Line 1221  route_set_aspath_prepend (void *rule, struct prefix *p Line 1167  route_set_aspath_prepend (void *rule, struct prefix *p
       else        else
         new = binfo->attr->aspath;          new = binfo->attr->aspath;
   
      aspath_prepend (aspath, new);      if ((uintptr_t)rule > 10)
       {
         aspath = rule;
         aspath_prepend (aspath, new);
       }
       else
       {
         as_t as = aspath_leftmost(new);
         if (!as) as = binfo->peer->as;
         new = aspath_add_seq_n (new, as, (uintptr_t) rule);
       }
 
       binfo->attr->aspath = new;        binfo->attr->aspath = new;
     }      }
   
   return RMAP_OKAY;    return RMAP_OKAY;
 }  }
   
 /* Compile function for as-path prepend. */  
 static void *  static void *
 route_set_aspath_prepend_compile (const char *arg)  route_set_aspath_prepend_compile (const char *arg)
 {  {
  struct aspath *aspath;  unsigned int num;
   
  aspath = aspath_str2aspath (arg);  if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
  if (! aspath)    return (void*)(uintptr_t)num;
    return NULL;
  return aspath;  return route_aspath_compile(arg);
 }  }
   
 /* Compile function for as-path prepend. */  
 static void  static void
 route_set_aspath_prepend_free (void *rule)  route_set_aspath_prepend_free (void *rule)
 {  {
  struct aspath *aspath = rule;  if ((uintptr_t)rule > 10)
  aspath_free (aspath);    route_aspath_free(rule);
 }  }
   
/* Set metric rule structure. */
 /* Set as-path prepend rule structure. */
 struct route_map_rule_cmd route_set_aspath_prepend_cmd =   struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
 {  {
   "as-path prepend",    "as-path prepend",
Line 1256  struct route_map_rule_cmd route_set_aspath_prepend_cmd Line 1212  struct route_map_rule_cmd route_set_aspath_prepend_cmd
   route_set_aspath_prepend_compile,    route_set_aspath_prepend_compile,
   route_set_aspath_prepend_free,    route_set_aspath_prepend_free,
 };  };
 /* `set as-path exclude ASn' */  /* `set as-path exclude ASn' */
   
 /* For ASN exclude mechanism.  /* For ASN exclude mechanism.
Line 1282  route_set_aspath_exclude (void *rule, struct prefix *d Line 1238  route_set_aspath_exclude (void *rule, struct prefix *d
   return RMAP_OKAY;    return RMAP_OKAY;
 }  }
   
 /* FIXME: consider using route_set_aspath_prepend_compile() and  
  * route_set_aspath_prepend_free(), which two below function are  
  * exact clones of.  
  */  
   
 /* Compile function for as-path exclude. */  
 static void *  
 route_set_aspath_exclude_compile (const char *arg)  
 {  
   struct aspath *aspath;  
   
   aspath = aspath_str2aspath (arg);  
   if (! aspath)  
     return NULL;  
   return aspath;  
 }  
   
 static void  
 route_set_aspath_exclude_free (void *rule)  
 {  
   struct aspath *aspath = rule;  
   aspath_free (aspath);  
 }  
   
 /* Set ASn exlude rule structure. */  /* Set ASn exlude rule structure. */
 struct route_map_rule_cmd route_set_aspath_exclude_cmd =   struct route_map_rule_cmd route_set_aspath_exclude_cmd = 
 {  {
   "as-path exclude",    "as-path exclude",
   route_set_aspath_exclude,    route_set_aspath_exclude,
  route_set_aspath_exclude_compile,  route_aspath_compile,
  route_set_aspath_exclude_free,  route_aspath_free,
 };  };
 /* `set community COMMUNITY' */  /* `set community COMMUNITY' */
 struct rmap_com_set  struct rmap_com_set
 {  {
Line 1438  struct route_map_rule_cmd route_set_community_cmd =  Line 1370  struct route_map_rule_cmd route_set_community_cmd = 
   route_set_community_compile,    route_set_community_compile,
   route_set_community_free,    route_set_community_free,
 };  };
 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */  /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
   
 /* For community set mechanism. */  /* For community set mechanism. */
Line 1527  struct route_map_rule_cmd route_set_community_delete_c Line 1459  struct route_map_rule_cmd route_set_community_delete_c
   route_set_community_delete_compile,    route_set_community_delete_compile,
   route_set_community_delete_free,    route_set_community_delete_free,
 };  };
 /* `set extcommunity rt COMMUNITY' */  /* `set extcommunity rt COMMUNITY' */
   
/* For community set mechanism. *//* For community set mechanism.  Used by _rt and _soo. */
 static route_map_result_t  static route_map_result_t
route_set_ecommunity_rt (void *rule, struct prefix *prefix, route_set_ecommunity (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)                      route_map_object_t type, void *object)
 {  {
   struct ecommunity *ecom;    struct ecommunity *ecom;
   struct ecommunity *new_ecom;    struct ecommunity *new_ecom;
Line 1552  route_set_ecommunity_rt (void *rule, struct prefix *pr Line 1484  route_set_ecommunity_rt (void *rule, struct prefix *pr
       old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;        old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
   
       if (old_ecom)        if (old_ecom)
        new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);        {
           new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
 
           /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
            *         ->refcnt = 0 => set by a previous route-map statement */
           if (!old_ecom->refcnt)
             ecommunity_free (&old_ecom);
         }
       else        else
         new_ecom = ecommunity_dup (ecom);          new_ecom = ecommunity_dup (ecom);
   
      bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);      /* will be intern()'d or attr_flush()'d by bgp_update_main() */
       bgp_info->attr->extra->ecommunity = new_ecom;
   
       if (old_ecom)  
         ecommunity_unintern (&old_ecom);  
   
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);        bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
     }      }
   return RMAP_OKAY;    return RMAP_OKAY;
Line 1578  route_set_ecommunity_rt_compile (const char *arg) Line 1515  route_set_ecommunity_rt_compile (const char *arg)
   return ecommunity_intern (ecom);    return ecommunity_intern (ecom);
 }  }
   
/* Free function for set community. *//* Free function for set community.  Used by _rt and _soo */
 static void  static void
route_set_ecommunity_rt_free (void *rule)route_set_ecommunity_free (void *rule)
 {  {
   struct ecommunity *ecom = rule;    struct ecommunity *ecom = rule;
   ecommunity_unintern (&ecom);    ecommunity_unintern (&ecom);
Line 1590  route_set_ecommunity_rt_free (void *rule) Line 1527  route_set_ecommunity_rt_free (void *rule)
 struct route_map_rule_cmd route_set_ecommunity_rt_cmd =   struct route_map_rule_cmd route_set_ecommunity_rt_cmd = 
 {  {
   "extcommunity rt",    "extcommunity rt",
  route_set_ecommunity_rt,  route_set_ecommunity,
   route_set_ecommunity_rt_compile,    route_set_ecommunity_rt_compile,
  route_set_ecommunity_rt_free,  route_set_ecommunity_free,
 };  };
   
 /* `set extcommunity soo COMMUNITY' */  /* `set extcommunity soo COMMUNITY' */
   
 /* For community set mechanism. */  
 static route_map_result_t  
 route_set_ecommunity_soo (void *rule, struct prefix *prefix,   
                          route_map_object_t type, void *object)  
 {  
   struct ecommunity *ecom, *old_ecom, *new_ecom;  
   struct bgp_info *bgp_info;  
   
   if (type == RMAP_BGP)  
     {  
       ecom = rule;  
       bgp_info = object;  
       
       if (! ecom)  
         return RMAP_OKAY;  
       
       old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;  
         
       if (old_ecom)  
         new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);  
       else  
         new_ecom = ecommunity_dup (ecom);  
   
       bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);  
   
       if (old_ecom)  
         ecommunity_unintern (&old_ecom);  
   
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);  
     }  
   return RMAP_OKAY;  
 }  
   
 /* Compile function for set community. */  /* Compile function for set community. */
 static void *  static void *
 route_set_ecommunity_soo_compile (const char *arg)  route_set_ecommunity_soo_compile (const char *arg)
Line 1643  route_set_ecommunity_soo_compile (const char *arg) Line 1547  route_set_ecommunity_soo_compile (const char *arg)
   return ecommunity_intern (ecom);    return ecommunity_intern (ecom);
 }  }
   
 /* Free function for set community. */  
 static void  
 route_set_ecommunity_soo_free (void *rule)  
 {  
   struct ecommunity *ecom = rule;  
   ecommunity_unintern (&ecom);  
 }  
   
 /* Set community rule structure. */  /* Set community rule structure. */
 struct route_map_rule_cmd route_set_ecommunity_soo_cmd =   struct route_map_rule_cmd route_set_ecommunity_soo_cmd = 
 {  {
   "extcommunity soo",    "extcommunity soo",
  route_set_ecommunity_soo,  route_set_ecommunity,
   route_set_ecommunity_soo_compile,    route_set_ecommunity_soo_compile,
  route_set_ecommunity_soo_free,  route_set_ecommunity_free,
 };  };
 /* `set origin ORIGIN' */  /* `set origin ORIGIN' */
   
 /* For origin set. */  /* For origin set. */
Line 1705  route_set_origin_free (void *rule) Line 1601  route_set_origin_free (void *rule)
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);    XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 }  }
   
/* Set metric rule structure. *//* Set origin rule structure. */
 struct route_map_rule_cmd route_set_origin_cmd =   struct route_map_rule_cmd route_set_origin_cmd = 
 {  {
   "origin",    "origin",
Line 1713  struct route_map_rule_cmd route_set_origin_cmd =  Line 1609  struct route_map_rule_cmd route_set_origin_cmd = 
   route_set_origin_compile,    route_set_origin_compile,
   route_set_origin_free,    route_set_origin_free,
 };  };
 /* `set atomic-aggregate' */  /* `set atomic-aggregate' */
   
 /* For atomic aggregate set. */  /* For atomic aggregate set. */
Line 1754  struct route_map_rule_cmd route_set_atomic_aggregate_c Line 1650  struct route_map_rule_cmd route_set_atomic_aggregate_c
   route_set_atomic_aggregate_compile,    route_set_atomic_aggregate_compile,
   route_set_atomic_aggregate_free,    route_set_atomic_aggregate_free,
 };  };
 /* `set aggregator as AS A.B.C.D' */  /* `set aggregator as AS A.B.C.D' */
 struct aggregator  struct aggregator
 {  {
Line 1813  struct route_map_rule_cmd route_set_aggregator_as_cmd  Line 1709  struct route_map_rule_cmd route_set_aggregator_as_cmd 
   route_set_aggregator_as_compile,    route_set_aggregator_as_compile,
   route_set_aggregator_as_free,    route_set_aggregator_as_free,
 };  };
#ifdef HAVE_IPV6 
 /* `match ipv6 address IP_ACCESS_LIST' */  /* `match ipv6 address IP_ACCESS_LIST' */
   
 static route_map_result_t  static route_map_result_t
Line 1855  struct route_map_rule_cmd route_match_ipv6_address_cmd Line 1750  struct route_map_rule_cmd route_match_ipv6_address_cmd
   route_match_ipv6_address_compile,    route_match_ipv6_address_compile,
   route_match_ipv6_address_free    route_match_ipv6_address_free
 };  };
 /* `match ipv6 next-hop IP_ADDRESS' */  /* `match ipv6 next-hop IP_ADDRESS' */
   
 static route_map_result_t  static route_map_result_t
 route_match_ipv6_next_hop (void *rule, struct prefix *prefix,   route_match_ipv6_next_hop (void *rule, struct prefix *prefix, 
                            route_map_object_t type, void *object)                             route_map_object_t type, void *object)
 {  {
  struct in6_addr *addr;  struct in6_addr *addr = rule;
   struct bgp_info *bgp_info;    struct bgp_info *bgp_info;
   
   if (type == RMAP_BGP)    if (type == RMAP_BGP)
     {      {
       addr = rule;  
       bgp_info = object;        bgp_info = object;
               
       if (!bgp_info->attr->extra)        if (!bgp_info->attr->extra)
         return RMAP_NOMATCH;          return RMAP_NOMATCH;
               
      if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))      if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
         return RMAP_MATCH;          return RMAP_MATCH;
   
       if (bgp_info->attr->extra->mp_nexthop_len == 32 &&        if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
          IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))          IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
         return RMAP_MATCH;          return RMAP_MATCH;
   
       return RMAP_NOMATCH;        return RMAP_NOMATCH;
Line 1917  struct route_map_rule_cmd route_match_ipv6_next_hop_cm Line 1811  struct route_map_rule_cmd route_match_ipv6_next_hop_cm
   route_match_ipv6_next_hop_compile,    route_match_ipv6_next_hop_compile,
   route_match_ipv6_next_hop_free    route_match_ipv6_next_hop_free
 };  };
 /* `match ipv6 address prefix-list PREFIX_LIST' */  /* `match ipv6 address prefix-list PREFIX_LIST' */
   
 static route_map_result_t  static route_map_result_t
Line 1957  struct route_map_rule_cmd route_match_ipv6_address_pre Line 1851  struct route_map_rule_cmd route_match_ipv6_address_pre
   route_match_ipv6_address_prefix_list_compile,    route_match_ipv6_address_prefix_list_compile,
   route_match_ipv6_address_prefix_list_free    route_match_ipv6_address_prefix_list_free
 };  };
 /* `set ipv6 nexthop global IP_ADDRESS' */  /* `set ipv6 nexthop global IP_ADDRESS' */
   
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */  /* Set nexthop to object.  ojbect must be pointer to struct attr. */
Line 2021  struct route_map_rule_cmd route_set_ipv6_nexthop_globa Line 1915  struct route_map_rule_cmd route_set_ipv6_nexthop_globa
   route_set_ipv6_nexthop_global_compile,    route_set_ipv6_nexthop_global_compile,
   route_set_ipv6_nexthop_global_free    route_set_ipv6_nexthop_global_free
 };  };
 /* `set ipv6 nexthop local IP_ADDRESS' */  /* `set ipv6 nexthop local IP_ADDRESS' */
   
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */  /* Set nexthop to object.  ojbect must be pointer to struct attr. */
Line 2085  struct route_map_rule_cmd route_set_ipv6_nexthop_local Line 1979  struct route_map_rule_cmd route_set_ipv6_nexthop_local
   route_set_ipv6_nexthop_local_compile,    route_set_ipv6_nexthop_local_compile,
   route_set_ipv6_nexthop_local_free    route_set_ipv6_nexthop_local_free
 };  };
#endif /* HAVE_IPV6 */
/* `set ipv6 nexthop peer-address' */
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t
 route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
                              route_map_object_t type, void *object)
 {
   struct in6_addr peer_address;
   struct bgp_info *bgp_info;
   struct peer *peer;
   char peer_addr_buf[INET6_ADDRSTRLEN];
 
   if (type == RMAP_BGP)
     {
       /* Fetch routemap's rule information. */
       bgp_info = object;
       peer = bgp_info->peer;
 
       if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
            CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
           && peer->su_remote
           && sockunion_family (peer->su_remote) == AF_INET6)
         {
           inet_pton (AF_INET6, sockunion2str (peer->su_remote,
                                               peer_addr_buf,
                                               INET6_ADDRSTRLEN),
                      &peer_address);
         }
       else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
                && peer->su_local
                && sockunion_family (peer->su_local) == AF_INET6)
         {
           inet_pton (AF_INET, sockunion2str (peer->su_local,
                                              peer_addr_buf,
                                              INET6_ADDRSTRLEN),
                      &peer_address);
         }
 
       if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
         {
           /* Set next hop value. */
           (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
 
           /* Set nexthop length. */
           if (bgp_info->attr->extra->mp_nexthop_len != 32)
             bgp_info->attr->extra->mp_nexthop_len = 32;
         }
       else
         {
           /* Set next hop value. */
           (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
 
           /* Set nexthop length. */
           if (bgp_info->attr->extra->mp_nexthop_len == 0)
             bgp_info->attr->extra->mp_nexthop_len = 16;
         }
     }
 
   return RMAP_OKAY;
 }
 
 /* Route map `ip next-hop' compile function.  Given string is converted
    to struct in_addr structure. */
 static void *
 route_set_ipv6_nexthop_peer_compile (const char *arg)
 {
   int *rins = NULL;
 
   rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
   *rins = 1;
 
   return rins;
 }
 
 /* Free route map's compiled `ip next-hop' value. */
 static void
 route_set_ipv6_nexthop_peer_free (void *rule)
 {
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 }
 
 /* Route map commands for ip nexthop set. */
 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
 {
   "ipv6 next-hop peer-address",
   route_set_ipv6_nexthop_peer,
   route_set_ipv6_nexthop_peer_compile,
   route_set_ipv6_nexthop_peer_free
 };
 
 /* `set vpnv4 nexthop A.B.C.D' */  /* `set vpnv4 nexthop A.B.C.D' */
   
 static route_map_result_t  static route_map_result_t
Line 2104  route_set_vpnv4_nexthop (void *rule, struct prefix *pr Line 2087  route_set_vpnv4_nexthop (void *rule, struct prefix *pr
           
       /* Set next hop value. */         /* Set next hop value. */ 
       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;        (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
         (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
     }      }
   
   return RMAP_OKAY;    return RMAP_OKAY;
Line 2142  struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd  Line 2126  struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd 
   route_set_vpnv4_nexthop_compile,    route_set_vpnv4_nexthop_compile,
   route_set_vpnv4_nexthop_free    route_set_vpnv4_nexthop_free
 };  };
 /* `set originator-id' */  /* `set originator-id' */
   
 /* For origin set. */  /* For origin set. */
Line 2191  route_set_originator_id_free (void *rule) Line 2175  route_set_originator_id_free (void *rule)
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);    XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 }  }
   
/* Set metric rule structure. *//* Set originator-id rule structure. */
 struct route_map_rule_cmd route_set_originator_id_cmd =   struct route_map_rule_cmd route_set_originator_id_cmd = 
 {  {
   "originator-id",    "originator-id",
Line 2199  struct route_map_rule_cmd route_set_originator_id_cmd  Line 2183  struct route_map_rule_cmd route_set_originator_id_cmd 
   route_set_originator_id_compile,    route_set_originator_id_compile,
   route_set_originator_id_free,    route_set_originator_id_free,
 };  };
 /* Add bgp route map rule. */  /* Add bgp route map rule. */
 static int  static int
 bgp_route_match_add (struct vty *vty, struct route_map_index *index,  bgp_route_match_add (struct vty *vty, struct route_map_index *index,
Line 2309  bgp_route_map_update (const char *unused) Line 2293  bgp_route_map_update (const char *unused)
   struct bgp_node *bn;    struct bgp_node *bn;
   struct bgp_static *bgp_static;    struct bgp_static *bgp_static;
   
     if (bm->bgp == NULL)          /* may be called during cleanup */
       return;
   
   /* For neighbor route-map updates. */    /* For neighbor route-map updates. */
   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))    for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
     {      {
Line 2397  bgp_route_map_update (const char *unused) Line 2384  bgp_route_map_update (const char *unused)
     {      {
       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)        for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
         {          {
          if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)          if (bgp->rmap[AFI_IP][i].name)
            bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =             bgp->rmap[AFI_IP][i].map =
              route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);              route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
#ifdef HAVE_IPV6          if (bgp->rmap[AFI_IP6][i].name)
          if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)            bgp->rmap[AFI_IP6][i].map =
            bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =              route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
              route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name); 
#endif /* HAVE_IPV6 */ 
         }          }
     }      }
 }  }
 DEFUN (match_peer,  DEFUN (match_peer,
        match_peer_cmd,         match_peer_cmd,
        "match peer (A.B.C.D|X:X::X:X)",         "match peer (A.B.C.D|X:X::X:X)",
Line 2999  ALIAS (set_metric, Line 2984  ALIAS (set_metric,
        "Metric value for destination routing protocol\n"         "Metric value for destination routing protocol\n"
        "Add or subtract metric\n")         "Add or subtract metric\n")
   
   ALIAS (set_metric,
          set_metric_rtt_cmd,
          "set metric (rtt|+rtt|-rtt)",
          SET_STR
          "Metric value for destination routing protocol\n"
          "Assign round trip time\n"
          "Add round trip time\n"
          "Subtract round trip time\n")
   
 DEFUN (no_set_metric,  DEFUN (no_set_metric,
        no_set_metric_cmd,         no_set_metric_cmd,
        "no set metric",         "no set metric",
Line 3100  DEFUN (set_aspath_prepend, Line 3094  DEFUN (set_aspath_prepend,
   return ret;    return ret;
 }  }
   
   ALIAS (set_aspath_prepend,
          set_aspath_prepend_lastas_cmd,
          "set as-path prepend (last-as) <1-10>",
          SET_STR
          "Transform BGP AS_PATH attribute\n"
          "Prepend to the as-path\n"
          "Use the peer's AS-number\n"
          "Number of times to insert")
   
 DEFUN (no_set_aspath_prepend,  DEFUN (no_set_aspath_prepend,
        no_set_aspath_prepend_cmd,         no_set_aspath_prepend_cmd,
        "no set as-path prepend",         "no set as-path prepend",
Line 3490  DEFUN (set_aggregator_as, Line 3493  DEFUN (set_aggregator_as,
        "IP address of aggregator\n")         "IP address of aggregator\n")
 {  {
   int ret;    int ret;
  as_t as;  as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
   struct in_addr address;    struct in_addr address;
   char *argstr;    char *argstr;
   
Line 3524  DEFUN (no_set_aggregator_as, Line 3527  DEFUN (no_set_aggregator_as,
        "AS number of aggregator\n")         "AS number of aggregator\n")
 {  {
   int ret;    int ret;
  as_t as;  as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
   struct in_addr address;    struct in_addr address;
   char *argstr;    char *argstr;
   
Line 3562  ALIAS (no_set_aggregator_as, Line 3565  ALIAS (no_set_aggregator_as,
        "AS number\n"         "AS number\n"
        "IP address of aggregator\n")         "IP address of aggregator\n")
   
   
 #ifdef HAVE_IPV6  
 DEFUN (match_ipv6_address,   DEFUN (match_ipv6_address, 
        match_ipv6_address_cmd,         match_ipv6_address_cmd,
        "match ipv6 address WORD",         "match ipv6 address WORD",
Line 3635  DEFUN (no_match_ipv6_address_prefix_list, Line 3636  DEFUN (no_match_ipv6_address_prefix_list,
   return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);    return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
 }  }
   
   DEFUN (set_ipv6_nexthop_peer,
          set_ipv6_nexthop_peer_cmd,
          "set ipv6 next-hop peer-address",
          SET_STR
          IPV6_STR
          "Next hop address\n"
          "Use peer address (for BGP only)\n")
   {
     return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
   }
   
   DEFUN (no_set_ipv6_nexthop_peer,
          no_set_ipv6_nexthop_peer_cmd,
          "no set ipv6 next-hop peer-address",
          NO_STR
          SET_STR
          IPV6_STR
          "IPv6 next-hop address\n"
          )
   {
     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
   }
   
 DEFUN (set_ipv6_nexthop_global,  DEFUN (set_ipv6_nexthop_global,
        set_ipv6_nexthop_global_cmd,         set_ipv6_nexthop_global_cmd,
        "set ipv6 next-hop global X:X::X:X",         "set ipv6 next-hop global X:X::X:X",
Line 3708  ALIAS (no_set_ipv6_nexthop_local, Line 3732  ALIAS (no_set_ipv6_nexthop_local,
        "IPv6 next-hop address\n"         "IPv6 next-hop address\n"
        "IPv6 local address\n"         "IPv6 local address\n"
        "IPv6 address of next hop\n")         "IPv6 address of next hop\n")
 #endif /* HAVE_IPV6 */  
   
 DEFUN (set_vpnv4_nexthop,  DEFUN (set_vpnv4_nexthop,
        set_vpnv4_nexthop_cmd,         set_vpnv4_nexthop_cmd,
Line 3833  ALIAS (no_match_pathlimit_as, Line 3856  ALIAS (no_match_pathlimit_as,
        "BGP AS-Pathlimit attribute\n"         "BGP AS-Pathlimit attribute\n"
        "Match Pathlimit ASN\n")         "Match Pathlimit ASN\n")
   
 /* Initialization of route map. */  /* Initialization of route map. */
 void  void
 bgp_route_map_init (void)  bgp_route_map_init (void)
Line 3930  bgp_route_map_init (void) Line 3953  bgp_route_map_init (void)
   install_element (RMAP_NODE, &no_set_weight_val_cmd);    install_element (RMAP_NODE, &no_set_weight_val_cmd);
   install_element (RMAP_NODE, &set_metric_cmd);    install_element (RMAP_NODE, &set_metric_cmd);
   install_element (RMAP_NODE, &set_metric_addsub_cmd);    install_element (RMAP_NODE, &set_metric_addsub_cmd);
     install_element (RMAP_NODE, &set_metric_rtt_cmd);
   install_element (RMAP_NODE, &no_set_metric_cmd);    install_element (RMAP_NODE, &no_set_metric_cmd);
   install_element (RMAP_NODE, &no_set_metric_val_cmd);    install_element (RMAP_NODE, &no_set_metric_val_cmd);
   install_element (RMAP_NODE, &set_aspath_prepend_cmd);    install_element (RMAP_NODE, &set_aspath_prepend_cmd);
     install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
   install_element (RMAP_NODE, &set_aspath_exclude_cmd);    install_element (RMAP_NODE, &set_aspath_exclude_cmd);
   install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);    install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
   install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);    install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Line 3967  bgp_route_map_init (void) Line 3992  bgp_route_map_init (void)
   install_element (RMAP_NODE, &no_set_originator_id_cmd);    install_element (RMAP_NODE, &no_set_originator_id_cmd);
   install_element (RMAP_NODE, &no_set_originator_id_val_cmd);    install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
   
 #ifdef HAVE_IPV6  
   route_map_install_match (&route_match_ipv6_address_cmd);    route_map_install_match (&route_match_ipv6_address_cmd);
   route_map_install_match (&route_match_ipv6_next_hop_cmd);    route_map_install_match (&route_match_ipv6_next_hop_cmd);
   route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);    route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
   route_map_install_set (&route_set_ipv6_nexthop_global_cmd);    route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);    route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
    route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
 
   install_element (RMAP_NODE, &match_ipv6_address_cmd);    install_element (RMAP_NODE, &match_ipv6_address_cmd);
   install_element (RMAP_NODE, &no_match_ipv6_address_cmd);    install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
   install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);    install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
Line 3986  bgp_route_map_init (void) Line 4011  bgp_route_map_init (void)
   install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);    install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);    install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);    install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
#endif /* HAVE_IPV6 */  install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
   
   /* AS-Pathlimit: functionality removed, commands kept for    /* AS-Pathlimit: functionality removed, commands kept for
    * compatibility.     * compatibility.

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


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