summaryrefslogtreecommitdiff
path: root/ripd/rip_routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'ripd/rip_routemap.c')
-rw-r--r--ripd/rip_routemap.c273
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);
}