diff options
Diffstat (limited to 'ripd/rip_routemap.c')
| -rw-r--r-- | ripd/rip_routemap.c | 273 | 
1 files changed, 249 insertions, 24 deletions
diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c index 8262f508..b354a896 100644 --- a/ripd/rip_routemap.c +++ b/ripd/rip_routemap.c @@ -31,6 +31,18 @@  #include "plist.h"  #include "ripd/ripd.h" + +struct rip_metric_modifier +{ +  enum  +  { +    metric_increment, +    metric_decrement, +    metric_absolute +  } type; + +  u_char metric; +};  /* Add rip route map rule. */  int @@ -439,6 +451,57 @@ struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =    route_match_ip_address_prefix_list_compile,    route_match_ip_address_prefix_list_free  }; + +/* `match tag TAG' */ +/* Match function return 1 if match is success else return zero. */ +route_map_result_t +route_match_tag (void *rule, struct prefix *prefix,  +		    route_map_object_t type, void *object) +{ +  u_short *tag; +  struct rip_info *rinfo; + +  if (type == RMAP_RIP) +    { +      tag = rule; +      rinfo = object; + +      /* The information stored by rinfo is host ordered. */ +      if (rinfo->tag == *tag) +	return RMAP_MATCH; +      else +	return RMAP_NOMATCH; +    } +  return RMAP_NOMATCH; +} + +/* Route map `match tag' match statement. `arg' is TAG value */ +void * +route_match_tag_compile (char *arg) +{ +  u_short *tag; + +  tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); +  *tag = atoi (arg); + +  return tag; +} + +/* Free route map's compiled `match tag' value. */ +void +route_match_tag_free (void *rule) +{ +  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for tag matching. */ +struct route_map_rule_cmd route_match_tag_cmd = +{ +  "tag", +  route_match_tag, +  route_match_tag_compile, +  route_match_tag_free +};  /* `set metric METRIC' */ @@ -447,17 +510,26 @@ route_map_result_t  route_set_metric (void *rule, struct prefix *prefix,   		  route_map_object_t type, void *object)  { -  u_int32_t *metric; -  struct rip_info *rinfo; -    if (type == RMAP_RIP)      { -      /* Fetch routemap's rule information. */ -      metric = rule; +      struct rip_metric_modifier *mod; +      struct rip_info *rinfo; + +      mod = rule;        rinfo = object; -     -      /* Set metric out value. */ -      rinfo->metric_out = *metric; + +      if (mod->type == metric_increment) +	rinfo->metric_out += mod->metric; +      else if (mod->type == metric_decrement) +	rinfo->metric_out -= mod->metric; +      else if (mod->type == metric_absolute) +	rinfo->metric_out = mod->metric; + +      if (rinfo->metric_out < 1) +	rinfo->metric_out = 1; +      if (rinfo->metric_out > RIP_METRIC_INFINITY) +	rinfo->metric_out = RIP_METRIC_INFINITY; +        rinfo->metric_set = 1;      }    return RMAP_OKAY; @@ -467,22 +539,51 @@ route_set_metric (void *rule, struct prefix *prefix,  void *  route_set_metric_compile (char *arg)  { -  u_int32_t *metric; +  int len; +  char *pnt; +  int type; +  long metric; +  char *endptr = NULL; +  struct rip_metric_modifier *mod; -  metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); -  *metric = atoi (arg); +  len = strlen (arg); +  pnt = arg; -  return metric; +  if (len == 0) +    return NULL; -#if 0 -  /* To make it consistent to other daemon, metric check is commented -     out.*/ -  if (*metric >= 0 && *metric <= 16) -    return metric; +  /* Examine first character. */ +  if (arg[0] == '+') +    { +      type = metric_increment; +      pnt++; +    } +  else if (arg[0] == '-') +    { +      type = metric_decrement; +      pnt++; +    } +  else +    type = metric_absolute; -  XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); -  return NULL; -#endif /* 0 */ +  /* Check beginning with digit string. */ +  if (*pnt < '0' || *pnt > '9') +    return NULL; + +  /* Convert string to integer. */ +  metric = strtol (pnt, &endptr, 10); + +  if (metric == LONG_MAX || *endptr != '\0') +    return NULL; +  if (metric < 0 || metric > RIP_METRIC_INFINITY) +    return NULL; + +  mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,  +		 sizeof (struct rip_metric_modifier)); +  mod->type = type; +  mod->metric = metric; + +  return mod;  }  /* Free route map's compiled `set metric' value. */ @@ -560,6 +661,58 @@ struct route_map_rule_cmd route_set_ip_nexthop_cmd =    route_set_ip_nexthop_compile,    route_set_ip_nexthop_free  }; + +/* `set tag TAG' */ + +/* Set tag to object.  ojbect must be pointer to struct attr. */ +route_map_result_t +route_set_tag (void *rule, struct prefix *prefix,  +		      route_map_object_t type, void *object) +{ +  u_short *tag; +  struct rip_info *rinfo; + +  if(type == RMAP_RIP) +    { +      /* Fetch routemap's rule information. */ +      tag = rule; +      rinfo = object; +     +      /* Set next hop value. */  +      rinfo->tag_out = *tag; +    } + +  return RMAP_OKAY; +} + +/* Route map `tag' compile function.  Given string is converted +   to u_short. */ +void * +route_set_tag_compile (char *arg) +{ +  u_short *tag; + +  tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); +  *tag = atoi (arg); + +  return tag; +} + +/* Free route map's compiled `ip nexthop' value. */ +void +route_set_tag_free (void *rule) +{ +  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for tag set. */ +struct route_map_rule_cmd route_set_tag_cmd = +{ +  "tag", +  route_set_tag, +  route_set_tag_compile, +  route_set_tag_free +};  #define MATCH_STR "Match values from routing table\n"  #define SET_STR "Set values in destination routing protocol\n" @@ -777,14 +930,46 @@ ALIAS (no_match_ip_address_prefix_list,         "Match entries of prefix-lists\n"         "IP prefix-list name\n") +DEFUN (match_tag,  +       match_tag_cmd, +       "match tag <0-65535>", +       MATCH_STR +       "Match tag of route\n" +       "Metric value\n") +{ +  return rip_route_match_add (vty, vty->index, "tag", argv[0]); +} + +DEFUN (no_match_tag, +       no_match_tag_cmd, +       "no match tag", +       NO_STR +       MATCH_STR +       "Match tag of route\n") +{ +  if (argc == 0) +    return rip_route_match_delete (vty, vty->index, "tag", NULL); + +  return rip_route_match_delete (vty, vty->index, "tag", argv[0]); +} + +ALIAS (no_match_tag, +       no_match_tag_val_cmd, +       "no match tag <0-65535>", +       NO_STR +       MATCH_STR +       "Match tag of route\n" +       "Metric value\n") +  /* set functions */  DEFUN (set_metric,         set_metric_cmd, -       "set metric <0-4294967295>", +       "set metric (<0-4294967295>|<+/-metric>)",         SET_STR         "Metric value for destination routing protocol\n" -       "Metric value\n") +       "Metric value\n" +       "Add or subtract metric\n")  {    return rip_route_set_add (vty, vty->index, "metric", argv[0]);  } @@ -804,11 +989,12 @@ DEFUN (no_set_metric,  ALIAS (no_set_metric,         no_set_metric_val_cmd, -       "no set metric <0-4294967295>", +       "no set metric (<0-4294967295>|<+/-metric>)",         NO_STR         SET_STR         "Metric value for destination routing protocol\n" -       "Metric value\n") +       "Metric value\n" +       "Add or subtract metric\n")  DEFUN (set_ip_nexthop,         set_ip_nexthop_cmd, @@ -854,6 +1040,37 @@ ALIAS (no_set_ip_nexthop,         "Next hop address\n"         "IP address of next hop\n") +DEFUN (set_tag, +       set_tag_cmd, +       "set tag <0-65535>", +       SET_STR +       "Tag value for routing protocol\n" +       "Tag value\n") +{ +  return rip_route_set_add (vty, vty->index, "tag", argv[0]); +} + +DEFUN (no_set_tag, +       no_set_tag_cmd, +       "no set tag", +       NO_STR +       SET_STR +       "Tag value for routing protocol\n") +{ +  if (argc == 0) +    return rip_route_set_delete (vty, vty->index, "tag", NULL); +   +  return rip_route_set_delete (vty, vty->index, "tag", argv[0]); +} + +ALIAS (no_set_tag, +       no_set_tag_val_cmd, +       "no set tag <0-65535>", +       NO_STR +       SET_STR +       "Tag value for routing protocol\n" +       "Tag value\n") +  void  rip_route_map_reset ()  { @@ -875,9 +1092,11 @@ rip_route_map_init ()    route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);    route_map_install_match (&route_match_ip_address_cmd);    route_map_install_match (&route_match_ip_address_prefix_list_cmd); +  route_map_install_match (&route_match_tag_cmd);    route_map_install_set (&route_set_metric_cmd);    route_map_install_set (&route_set_ip_nexthop_cmd); +  route_map_install_set (&route_set_tag_cmd);    install_element (RMAP_NODE, &match_metric_cmd);    install_element (RMAP_NODE, &no_match_metric_cmd); @@ -897,6 +1116,9 @@ rip_route_map_init ()    install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);    install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);    install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd); +  install_element (RMAP_NODE, &match_tag_cmd); +  install_element (RMAP_NODE, &no_match_tag_cmd); +  install_element (RMAP_NODE, &no_match_tag_val_cmd);    install_element (RMAP_NODE, &set_metric_cmd);    install_element (RMAP_NODE, &no_set_metric_cmd); @@ -904,4 +1126,7 @@ rip_route_map_init ()    install_element (RMAP_NODE, &set_ip_nexthop_cmd);    install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);    install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd); +  install_element (RMAP_NODE, &set_tag_cmd); +  install_element (RMAP_NODE, &no_set_tag_cmd); +  install_element (RMAP_NODE, &no_set_tag_val_cmd);  }  | 
