summaryrefslogtreecommitdiff
path: root/lib/routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/routemap.c')
-rw-r--r--lib/routemap.c1341
1 files changed, 1237 insertions, 104 deletions
diff --git a/lib/routemap.c b/lib/routemap.c
index eec36d3717..a4a8a2bb23 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -24,9 +24,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h"
#include "vector.h"
#include "prefix.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
-#include "vty.h"
#include "log.h"
#include "hash.h"
@@ -47,6 +47,594 @@ static vector route_match_vec;
/* Vector for route set rules. */
static vector route_set_vec;
+struct route_map_match_set_hooks
+{
+ /* match interface */
+ int (*match_interface) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match interface */
+ int (*no_match_interface) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip address */
+ int (*match_ip_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip address */
+ int (*no_match_ip_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip address prefix list */
+ int (*match_ip_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip address prefix list */
+ int (*no_match_ip_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip next hop */
+ int (*match_ip_next_hop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip next hop */
+ int (*no_match_ip_next_hop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip next hop prefix list */
+ int (*match_ip_next_hop_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip next hop prefix list */
+ int (*no_match_ip_next_hop_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ipv6 address */
+ int (*match_ipv6_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ipv6 address */
+ int (*no_match_ipv6_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+
+ /* match ipv6 address prefix list */
+ int (*match_ipv6_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ipv6 address prefix list */
+ int (*no_match_ipv6_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match metric */
+ int (*match_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match metric */
+ int (*no_match_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match tag */
+ int (*match_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match tag */
+ int (*no_match_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* set ip nexthop */
+ int (*set_ip_nexthop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set ip nexthop */
+ int (*no_set_ip_nexthop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* set ipv6 nexthop local */
+ int (*set_ipv6_nexthop_local) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set ipv6 nexthop local */
+ int (*no_set_ipv6_nexthop_local) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* set metric */
+ int (*set_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set metric */
+ int (*no_set_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* set tag */
+ int (*set_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set tag */
+ int (*no_set_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+};
+
+struct route_map_match_set_hooks rmap_match_set_hook;
+
+/* match interface */
+void
+route_map_match_interface_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_interface = func;
+}
+
+/* no match interface */
+void
+route_map_no_match_interface_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_interface = func;
+}
+
+/* match ip address */
+void
+route_map_match_ip_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_address = func;
+}
+
+/* no match ip address */
+void
+route_map_no_match_ip_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_address = func;
+}
+
+/* match ip address prefix list */
+void
+route_map_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_address_prefix_list = func;
+}
+
+/* no match ip address prefix list */
+void
+route_map_no_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_address_prefix_list = func;
+}
+
+/* match ip next hop */
+void
+route_map_match_ip_next_hop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_next_hop = func;
+}
+
+/* no match ip next hop */
+void
+route_map_no_match_ip_next_hop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_next_hop = func;
+}
+
+/* match ip next hop prefix list */
+void
+route_map_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_next_hop_prefix_list = func;
+}
+
+/* no match ip next hop prefix list */
+void
+route_map_no_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func;
+}
+
+/* match ipv6 address */
+void
+route_map_match_ipv6_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ipv6_address = func;
+}
+
+/* no match ipv6 address */
+void
+route_map_no_match_ipv6_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ipv6_address = func;
+}
+
+
+/* match ipv6 address prefix list */
+void
+route_map_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ipv6_address_prefix_list = func;
+}
+
+/* no match ipv6 address prefix list */
+void
+route_map_no_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ipv6_address_prefix_list = func;
+}
+
+/* match metric */
+void
+route_map_match_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_metric = func;
+}
+
+/* no match metric */
+void
+route_map_no_match_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_metric = func;
+}
+
+/* match tag */
+void
+route_map_match_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_tag = func;
+}
+
+/* no match tag */
+void
+route_map_no_match_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_tag = func;
+}
+
+/* set ip nexthop */
+void
+route_map_set_ip_nexthop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_ip_nexthop = func;
+}
+
+/* no set ip nexthop */
+void
+route_map_no_set_ip_nexthop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_ip_nexthop = func;
+}
+
+/* set ipv6 nexthop local */
+void
+route_map_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_ipv6_nexthop_local = func;
+}
+
+/* no set ipv6 nexthop local */
+void
+route_map_no_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_ipv6_nexthop_local = func;
+}
+
+/* set metric */
+void
+route_map_set_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_metric = func;
+}
+
+/* no set metric */
+void
+route_map_no_set_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_metric = func;
+}
+
+/* set tag */
+void
+route_map_set_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_tag = func;
+}
+
+/* no set tag */
+void
+route_map_no_set_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_tag = func;
+}
+
+int
+generic_match_add (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg,
+ route_map_event_t type)
+{
+ int ret;
+
+ ret = route_map_add_match (index, command, arg);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (type != RMAP_EVENT_MATCH_ADDED)
+ {
+ route_map_upd8_dependency (type, arg, index->map->name);
+ }
+ return CMD_SUCCESS;
+}
+
+int
+generic_match_delete (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg,
+ route_map_event_t type)
+{
+ int ret;
+ char *dep_name = NULL;
+ const char *tmpstr;
+ char *rmap_name = NULL;
+
+ if (type != RMAP_EVENT_MATCH_DELETED)
+ {
+ /* ignore the mundane, the types without any dependency */
+ if (arg == NULL)
+ {
+ if ((tmpstr = route_map_get_match_arg(index, command)) != NULL)
+ dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
+ }
+ else
+ {
+ dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
+ }
+ rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
+ }
+
+ ret = route_map_delete_match (index, command, dep_name);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
+ break;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
+ break;
+ }
+ if (dep_name)
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ if (rmap_name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ return CMD_WARNING;
+ }
+
+ if (type != RMAP_EVENT_MATCH_DELETED && dep_name)
+ route_map_upd8_dependency(type, dep_name, rmap_name);
+
+ if (dep_name)
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ if (rmap_name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+
+ return CMD_SUCCESS;
+}
+
+int
+generic_set_add (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg)
+{
+ int ret;
+
+ ret = route_map_add_set (index, command, arg);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+int
+generic_set_delete (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg)
+{
+ int ret;
+
+ ret = route_map_delete_set (index, command, arg);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+
/* Route map rule. This rule has both `match' rule and `set' rule. */
struct route_map_rule
{
@@ -1386,49 +1974,578 @@ route_map_notify_dependencies (const char *affected_name, route_map_event_t even
XFREE (MTYPE_ROUTE_MAP_NAME, name);
}
+
/* VTY related functions. */
-DEFUN (route_map,
- route_map_cmd,
- "route-map WORD (deny|permit) <1-65535>",
- "Create route-map or enter route-map command mode\n"
- "Route map tag\n"
- "Route map denies set operations\n"
- "Route map permits set operations\n"
- "Sequence to insert to/delete from existing route-map entry\n")
+DEFUN (match_interface,
+ match_interface_cmd,
+ "match interface WORD",
+ MATCH_STR
+ "match first hop interface of route\n"
+ "Interface name\n")
+{
+ int idx_word = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_interface)
+ return rmap_match_set_hook.match_interface (vty, index, "interface", argv[idx_word]->arg, RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_interface,
+ no_match_interface_cmd,
+ "no match interface [INTERFACE]",
+ NO_STR
+ MATCH_STR
+ "Match first hop interface of route\n"
+ "Interface name\n")
{
- int permit;
- unsigned long pref;
- struct route_map *map;
- struct route_map_index *index;
- char *endptr = NULL;
+ char *iface = (argc == 4) ? argv[3]->arg : NULL;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
- /* Permit check. */
- if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)
- permit = RMAP_PERMIT;
- else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)
- permit = RMAP_DENY;
- else
+ if (rmap_match_set_hook.no_match_interface)
+ return rmap_match_set_hook.no_match_interface (vty, index, "interface", iface, RMAP_EVENT_MATCH_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_address,
+ match_ip_address_cmd,
+ "match ip address <(1-199)|(1300-2699)|WORD>",
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_acl = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_address)
+ return rmap_match_set_hook.match_ip_address (vty, index, "ip address", argv[idx_acl]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_ip_address,
+ no_match_ip_address_cmd,
+ "no match ip address [<(1-199)|(1300-2699)|WORD>]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_address)
{
- vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", NULL,
+ RMAP_EVENT_FILTER_DELETED);
+ return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_address_prefix_list,
+ match_ip_address_prefix_list_cmd,
+ "match ip address prefix-list WORD",
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_address_prefix_list)
+ return rmap_match_set_hook.match_ip_address_prefix_list (vty, index, "ip address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_ip_address_prefix_list,
+ no_match_ip_address_prefix_list_cmd,
+ "no match ip address prefix-list [WORD]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_address_prefix_list)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_address_prefix_list (vty, index, "ip address prefix-list",
+ NULL, RMAP_EVENT_PLIST_DELETED);
+ return rmap_match_set_hook.no_match_ip_address_prefix_list(vty, index, "ip address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_next_hop,
+ match_ip_next_hop_cmd,
+ "match ip next-hop <(1-199)|(1300-2699)|WORD>",
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_acl = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_next_hop)
+ return rmap_match_set_hook.match_ip_next_hop (vty, index, "ip next-hop", argv[idx_acl]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_ip_next_hop,
+ no_match_ip_next_hop_cmd,
+ "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_next_hop)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", NULL,
+ RMAP_EVENT_FILTER_DELETED);
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_next_hop_prefix_list,
+ match_ip_next_hop_prefix_list_cmd,
+ "match ip next-hop prefix-list WORD",
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_next_hop_prefix_list)
+ return rmap_match_set_hook.match_ip_next_hop_prefix_list (vty, index, "ip next-hop prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_ip_next_hop_prefix_list,
+ no_match_ip_next_hop_prefix_list_cmd,
+ "no match ip next-hop prefix-list [WORD]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_next_hop)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list",
+ NULL, RMAP_EVENT_PLIST_DELETED);
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ipv6_address,
+ match_ipv6_address_cmd,
+ "match ipv6 address WORD",
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 address of route\n"
+ "IPv6 access-list name\n")
+{
+ int idx_word = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ipv6_address)
+ return rmap_match_set_hook.match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_ipv6_address,
+ no_match_ipv6_address_cmd,
+ "no match ipv6 address WORD",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 address of route\n"
+ "IPv6 access-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ipv6_address)
+ return rmap_match_set_hook.no_match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ipv6_address_prefix_list,
+ match_ipv6_address_prefix_list_cmd,
+ "match ipv6 address prefix-list WORD",
+ MATCH_STR
+ IPV6_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ipv6_address_prefix_list)
+ return rmap_match_set_hook.match_ipv6_address_prefix_list (vty, index, "ipv6 address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_ipv6_address_prefix_list,
+ no_match_ipv6_address_prefix_list_cmd,
+ "no match ipv6 address prefix-list WORD",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ipv6_address_prefix_list)
+ return rmap_match_set_hook.no_match_ipv6_address_prefix_list(vty, index, "ipv6 address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_metric,
+ match_metric_cmd,
+ "match metric (0-4294967295)",
+ MATCH_STR
+ "Match metric of route\n"
+ "Metric value\n")
+{
+ int idx_number = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_metric)
+ return rmap_match_set_hook.match_metric(vty, index, "metric", argv[idx_number]->arg,
+ RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_metric,
+ no_match_metric_cmd,
+ "no match metric [(0-4294967295)]",
+ NO_STR
+ MATCH_STR
+ "Match metric of route\n"
+ "Metric value\n")
+{
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_metric)
+ {
+ if (argc <= idx_number)
+ return rmap_match_set_hook.no_match_metric (vty, index, "metric",
+ NULL, RMAP_EVENT_MATCH_DELETED);
+ return rmap_match_set_hook.no_match_metric(vty, index, "metric",
+ argv[idx_number]->arg,
+ RMAP_EVENT_MATCH_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_tag,
+ match_tag_cmd,
+ "match tag (1-4294967295)",
+ MATCH_STR
+ "Match tag of route\n"
+ "Tag value\n")
+{
+ int idx_number = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_tag)
+ return rmap_match_set_hook.match_tag(vty, index, "tag", argv[idx_number]->arg,
+ RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_tag,
+ no_match_tag_cmd,
+ "no match tag [(1-4294967295)]",
+ NO_STR
+ MATCH_STR
+ "Match tag of route\n"
+ "Tag value\n")
+{
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_tag)
+ return rmap_match_set_hook.no_match_tag (vty, index, "tag", argv[3]->arg,
+ RMAP_EVENT_MATCH_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (set_ip_nexthop,
+ set_ip_nexthop_cmd,
+ "set ip next-hop A.B.C.D",
+ SET_STR
+ IP_STR
+ "Next hop address\n"
+ "IP address of next hop\n")
+{
+ int idx_ipv4 = 3;
+ union sockunion su;
+ int ret;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ ret = str2sockunion (argv[idx_ipv4]->arg, &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (su.sin.sin_addr.s_addr == 0 ||
+ IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
+ {
+ vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
+ "or reserved%s", VTY_NEWLINE);
return CMD_WARNING;
}
- /* Preference check. */
- pref = strtoul (argv[2], &endptr, 10);
- if (pref == ULONG_MAX || *endptr != '\0')
+ if (rmap_match_set_hook.set_ip_nexthop)
+ return rmap_match_set_hook.set_ip_nexthop(vty, index, "ip next-hop", argv[idx_ipv4]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_ip_nexthop,
+ no_set_ip_nexthop_cmd,
+ "no set ip next-hop [<peer-address|A.B.C.D>]",
+ NO_STR
+ SET_STR
+ "Next hop address\n"
+ "Use peer address (for BGP only)\n"
+ "IP address of next hop\n")
+{
+ int idx_peer = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_set_ip_nexthop)
{
- vty_out (vty, "the fourth field must be positive integer%s",
- VTY_NEWLINE);
+ if (argc <= idx_peer)
+ return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", NULL);
+ return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", argv[idx_peer]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (set_ipv6_nexthop_local,
+ set_ipv6_nexthop_local_cmd,
+ "set ipv6 next-hop local X:X::X:X",
+ SET_STR
+ IPV6_STR
+ "IPv6 next-hop address\n"
+ "IPv6 local address\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ipv6 = 4;
+ struct in6_addr addr;
+ int ret;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ ret = inet_pton (AF_INET6, argv[idx_ipv6]->arg, &addr);
+ if (!ret)
+ {
+ vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (pref == 0 || pref > 65535)
+ if (!IN6_IS_ADDR_LINKLOCAL(&addr))
{
- vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);
+ vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
+ if (rmap_match_set_hook.set_ipv6_nexthop_local)
+ return rmap_match_set_hook.set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[idx_ipv6]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_ipv6_nexthop_local,
+ no_set_ipv6_nexthop_local_cmd,
+ "no set ipv6 next-hop local [X:X::X:X]",
+ NO_STR
+ SET_STR
+ IPV6_STR
+ "IPv6 next-hop address\n"
+ "IPv6 local address\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ipv6 = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_set_ipv6_nexthop_local)
+ {
+ if (argc <= idx_ipv6)
+ return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", NULL);
+ return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[5]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (set_metric,
+ set_metric_cmd,
+ "set metric <(0-4294967295)|rtt|+rtt|-rtt|+metric|-metric>",
+ SET_STR
+ "Metric value for destination routing protocol\n"
+ "Metric value\n"
+ "Assign round trip time\n"
+ "Add round trip time\n"
+ "Subtract round trip time\n"
+ "Add metric\n"
+ "Subtract metric\n")
+{
+ int idx_number = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.set_metric)
+ return rmap_match_set_hook.set_metric (vty, index, "metric", argv[idx_number]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_metric,
+ no_set_metric_cmd,
+ "no set metric [(0-4294967295)]",
+ NO_STR
+ SET_STR
+ "Metric value for destination routing protocol\n"
+ "Metric value\n")
+{
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_set_metric)
+ {
+ if (argc <= idx_number)
+ return rmap_match_set_hook.no_set_metric (vty, index, "metric", NULL);
+ return rmap_match_set_hook.no_set_metric (vty, index, "metric", argv[idx_number]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (set_tag,
+ set_tag_cmd,
+ "set tag (1-4294967295)",
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+{
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ int idx_number = 2;
+ if (rmap_match_set_hook.set_tag)
+ return rmap_match_set_hook.set_tag (vty, index, "tag", argv[idx_number]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_tag,
+ no_set_tag_cmd,
+ "no set tag [(1-4294967295)]",
+ NO_STR
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+{
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ int idx_number = 3;
+ if (rmap_match_set_hook.no_set_tag)
+ {
+ if (argc <= idx_number)
+ return rmap_match_set_hook.no_set_tag (vty, index, "tag", NULL);
+ return rmap_match_set_hook.no_set_tag (vty, index, "tag", argv[idx_number]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+
+
+DEFUN (route_map,
+ route_map_cmd,
+ "route-map WORD <deny|permit> (1-65535)",
+ "Create route-map or enter route-map command mode\n"
+ "Route map tag\n"
+ "Route map denies set operations\n"
+ "Route map permits set operations\n"
+ "Sequence to insert to/delete from existing route-map entry\n")
+{
+ int idx_word = 1;
+ int idx_permit_deny = 2;
+ int idx_number = 3;
+ struct route_map *map;
+ struct route_map_index *index;
+ char *endptr = NULL;
+ int permit = argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY;
+ unsigned long pref = strtoul (argv[idx_number]->arg, &endptr, 10);
+ const char *mapname = argv[idx_word]->arg;
+
/* Get route map. */
- map = route_map_get (argv[0]);
+ map = route_map_get (mapname);
index = route_map_index_get (map, permit, pref);
VTY_PUSH_CONTEXT_COMPAT (RMAP_NODE, index);
@@ -1442,13 +2559,14 @@ DEFUN (no_route_map_all,
"Create route-map or enter route-map command mode\n"
"Route map tag\n")
{
+ int idx_word = 2;
+ const char *mapname = argv[idx_word]->arg;
struct route_map *map;
- map = route_map_lookup_by_name (argv[0]);
+ map = route_map_lookup_by_name (mapname);
if (map == NULL)
{
- vty_out (vty, "%% Could not find route-map %s%s",
- argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Could not find route-map %s%s", mapname, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1459,7 +2577,7 @@ DEFUN (no_route_map_all,
DEFUN (no_route_map,
no_route_map_cmd,
- "no route-map WORD (deny|permit) <1-65535>",
+ "no route-map WORD <deny|permit> (1-65535)",
NO_STR
"Create route-map or enter route-map command mode\n"
"Route map tag\n"
@@ -1467,43 +2585,22 @@ DEFUN (no_route_map,
"Route map permits set operations\n"
"Sequence to insert to/delete from existing route-map entry\n")
{
- int permit;
- unsigned long pref;
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_number = 4;
struct route_map *map;
struct route_map_index *index;
char *endptr = NULL;
-
- /* Permit check. */
- if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)
- permit = RMAP_PERMIT;
- else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)
- permit = RMAP_DENY;
- else
- {
- vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Preference. */
- pref = strtoul (argv[2], &endptr, 10);
- if (pref == ULONG_MAX || *endptr != '\0')
- {
- vty_out (vty, "the fourth field must be positive integer%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (pref == 0 || pref > 65535)
- {
- vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int permit = argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY;
+ const char *prefstr = argv[idx_number]->arg;
+ const char *mapname = argv[idx_word]->arg;
+ unsigned long pref = strtoul (prefstr, &endptr, 10);
/* Existence check. */
- map = route_map_lookup_by_name (argv[0]);
+ map = route_map_lookup_by_name (mapname);
if (map == NULL)
{
- vty_out (vty, "%% Could not find route-map %s%s",
- argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Could not find route-map %s%s", mapname, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1512,7 +2609,7 @@ DEFUN (no_route_map,
if (index == NULL)
{
vty_out (vty, "%% Could not find route-map entry %s %s%s",
- argv[0], argv[2], VTY_NEWLINE);
+ mapname, prefstr, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1556,7 +2653,7 @@ DEFUN (no_rmap_onmatch_next,
"Next clause\n")
{
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
-
+
if (index)
index->exitpolicy = RMAP_EXIT;
@@ -1565,11 +2662,16 @@ DEFUN (no_rmap_onmatch_next,
DEFUN (rmap_onmatch_goto,
rmap_onmatch_goto_cmd,
- "on-match goto <1-65535>",
+ "on-match goto (1-65535)",
"Exit policy on matches\n"
"Goto Clause number\n"
"Number\n")
{
+ int idx_number = 2;
+ char *num = NULL;
+ num = argv[idx_number]->arg;
+
+
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
int d = 0;
@@ -1583,16 +2685,15 @@ DEFUN (rmap_onmatch_goto,
return CMD_WARNING;
}
- if (argc == 1 && argv[0])
- VTY_GET_INTEGER_RANGE("route-map index", d, argv[0], 1, 65535);
+ if (num)
+ VTY_GET_INTEGER_RANGE("route-map index", d, num, 1, 65535);
else
d = index->pref + 1;
if (d <= index->pref)
{
/* Can't allow you to do that, Dave */
- vty_out (vty, "can't jump backwards in route-maps%s",
- VTY_NEWLINE);
+ vty_out (vty, "can't jump backwards in route-maps%s", VTY_NEWLINE);
return CMD_WARNING;
}
else
@@ -1619,31 +2720,28 @@ DEFUN (no_rmap_onmatch_goto,
return CMD_SUCCESS;
}
-/* Cisco/GNU Zebra compatible ALIASes for on-match next */
-ALIAS (rmap_onmatch_goto,
+/* Cisco/GNU Zebra compatibility aliases */
+/* ALIAS_FIXME */
+DEFUN (rmap_continue,
rmap_continue_cmd,
- "continue",
- "Continue on a different entry within the route-map\n")
-
-ALIAS (no_rmap_onmatch_goto,
- no_rmap_continue_cmd,
- "no continue",
- NO_STR
- "Continue on a different entry within the route-map\n")
-
-/* GNU Zebra compatible */
-ALIAS (rmap_onmatch_goto,
- rmap_continue_seq_cmd,
- "continue <1-65535>",
+ "continue (1-65535)",
"Continue on a different entry within the route-map\n"
"Route-map entry sequence number\n")
+{
+ return rmap_onmatch_goto (self, vty, argc, argv);
+}
-ALIAS (no_rmap_onmatch_goto,
- no_rmap_continue_seq,
- "no continue <1-65535>",
+/* ALIAS_FIXME */
+DEFUN (no_rmap_continue,
+ no_rmap_continue_cmd,
+ "no continue [(1-65535)]",
NO_STR
"Continue on a different entry within the route-map\n"
"Route-map entry sequence number\n")
+{
+ return no_rmap_onmatch_goto (self, vty, argc, argv);
+}
+
DEFUN (rmap_show_name,
rmap_show_name_cmd,
@@ -1652,25 +2750,20 @@ DEFUN (rmap_show_name,
"route-map information\n"
"route-map name\n")
{
- const char *name = NULL;
- if (argc)
- name = argv[0];
- return vty_show_route_map (vty, name);
+ int idx_word = 2;
+ const char *name = (argc == 3) ? argv[idx_word]->arg : NULL;
+ return vty_show_route_map (vty, name);
}
-ALIAS (rmap_onmatch_goto,
- rmap_continue_index_cmd,
- "continue <1-65535>",
- "Exit policy on matches\n"
- "Goto Clause number\n")
-
DEFUN (rmap_call,
rmap_call_cmd,
"call WORD",
"Jump to another Route-Map after match+set\n"
"Target route-map name\n")
{
+ int idx_word = 1;
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
+ const char *rmap = argv[idx_word]->arg;
if (index)
{
@@ -1681,7 +2774,7 @@ DEFUN (rmap_call,
index->map->name);
XFREE (MTYPE_ROUTE_MAP_NAME, index->nextrm);
}
- index->nextrm = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[0]);
+ index->nextrm = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap);
}
/* Execute event hook. */
@@ -1713,17 +2806,18 @@ DEFUN (no_rmap_call,
DEFUN (rmap_description,
rmap_description_cmd,
- "description .LINE",
+ "description LINE...",
"Route-map comment\n"
"Comment describing this route-map rule\n")
{
+ int idx_line = 1;
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
if (index)
{
if (index->description)
XFREE (MTYPE_TMP, index->description);
- index->description = argv_concat (argv, argc, 0);
+ index->description = argv_concat (argv, argc, idx_line);
}
return CMD_SUCCESS;
}
@@ -1876,11 +2970,10 @@ route_map_init (void)
install_element (RMAP_NODE, &no_rmap_onmatch_next_cmd);
install_element (RMAP_NODE, &rmap_onmatch_goto_cmd);
install_element (RMAP_NODE, &no_rmap_onmatch_goto_cmd);
-
- /* Install the continue stuff (ALIAS of on-match). */
install_element (RMAP_NODE, &rmap_continue_cmd);
install_element (RMAP_NODE, &no_rmap_continue_cmd);
- install_element (RMAP_NODE, &rmap_continue_index_cmd);
+
+ /* Install the continue stuff (ALIAS of on-match). */
/* Install the call stuff. */
install_element (RMAP_NODE, &rmap_call_cmd);
@@ -1892,4 +2985,44 @@ route_map_init (void)
/* Install show command */
install_element (ENABLE_NODE, &rmap_show_name_cmd);
+
+ install_element (RMAP_NODE, &match_interface_cmd);
+ install_element (RMAP_NODE, &no_match_interface_cmd);
+
+ install_element (RMAP_NODE, &match_ip_address_cmd);
+ install_element (RMAP_NODE, &no_match_ip_address_cmd);
+
+ 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, &match_ip_next_hop_cmd);
+ install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
+
+ install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
+
+ install_element (RMAP_NODE, &match_ipv6_address_cmd);
+ install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
+
+ install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
+
+ install_element (RMAP_NODE, &match_metric_cmd);
+ install_element (RMAP_NODE, &no_match_metric_cmd);
+
+ install_element (RMAP_NODE, &match_tag_cmd);
+ install_element (RMAP_NODE, &no_match_tag_cmd);
+
+ install_element (RMAP_NODE, &set_ip_nexthop_cmd);
+ install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
+
+ install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
+ install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
+
+ install_element (RMAP_NODE, &set_metric_cmd);
+ install_element (RMAP_NODE, &no_set_metric_cmd);
+
+ install_element (RMAP_NODE, &set_tag_cmd);
+ install_element (RMAP_NODE, &no_set_tag_cmd);
+
}