]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/routemap.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[mirror_frr.git] / lib / routemap.c
index c0e01488b28a1890baa5433160a124e9fec16bc2..a604c5921cd2b5ff454351a0fed75678d4fc0d96 100644 (file)
@@ -50,177 +50,6 @@ 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 ip next-hop type */
-       int (*match_ip_next_hop_type)(struct vty *vty,
-                                            struct route_map_index *index,
-                                            const char *command,
-                                            const char *arg,
-                                            route_map_event_t type);
-
-       /* no match ip next-hop type */
-       int (*no_match_ip_next_hop_type)(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 ipv6 next-hop type */
-       int (*match_ipv6_next_hop_type)(struct vty *vty,
-                                             struct route_map_index *index,
-                                             const char *command,
-                                             const char *arg,
-                                             route_map_event_t type);
-
-       /* no match ipv6 next-hop type */
-       int (*no_match_ipv6_next_hop_type)(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 */
@@ -479,15 +308,21 @@ int generic_match_add(struct vty *vty, struct route_map_index *index,
        ret = route_map_add_match(index, command, arg, type);
        switch (ret) {
        case RMAP_RULE_MISSING:
-               vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
+               if (vty)
+                       vty_out(vty, "%% [%s] Can't find rule.\n",
+                               frr_protonameinst);
+               else
+                       zlog_warn("Can't find rule: %s", command);
                return CMD_WARNING_CONFIG_FAILED;
-               break;
        case RMAP_COMPILE_ERROR:
-               vty_out(vty,
-                       "%% [%s] Argument form is unsupported or malformed.\n",
-                       frr_protonameinst);
+               if (vty)
+                       vty_out(vty,
+                               "%% [%s] Argument form is unsupported or malformed.\n",
+                               frr_protonameinst);
+               else
+                       zlog_warn("Argument form is unsupported or malformed: "
+                                 "%s %s", command, arg);
                return CMD_WARNING_CONFIG_FAILED;
-               break;
        case RMAP_COMPILE_SUCCESS:
                /*
                 * Nothing to do here move along
@@ -524,13 +359,21 @@ int generic_match_delete(struct vty *vty, struct route_map_index *index,
        ret = route_map_delete_match(index, command, dep_name, type);
        switch (ret) {
        case RMAP_RULE_MISSING:
-               vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
+               if (vty)
+                       vty_out(vty, "%% [%s] Can't find rule.\n",
+                               frr_protonameinst);
+               else
+                       zlog_warn("Can't find rule: %s", command);
                retval = CMD_WARNING_CONFIG_FAILED;
                break;
        case RMAP_COMPILE_ERROR:
-               vty_out(vty,
-                       "%% [%s] Argument form is unsupported or malformed.\n",
-                       frr_protonameinst);
+               if (vty)
+                       vty_out(vty,
+                               "%% [%s] Argument form is unsupported or malformed.\n",
+                               frr_protonameinst);
+               else
+                       zlog_warn("Argument form is unsupported or malformed: "
+                                 "%s %s", command, arg);
                retval = CMD_WARNING_CONFIG_FAILED;
                break;
        case RMAP_COMPILE_SUCCESS:
@@ -554,15 +397,20 @@ int generic_set_add(struct vty *vty, struct route_map_index *index,
        ret = route_map_add_set(index, command, arg);
        switch (ret) {
        case RMAP_RULE_MISSING:
-               vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
+               if (vty)
+                       vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
+               else
+                       zlog_warn("Can't find rule: %s", command);
                return CMD_WARNING_CONFIG_FAILED;
-               break;
        case RMAP_COMPILE_ERROR:
-               vty_out(vty,
-                       "%% [%s] Argument form is unsupported or malformed.\n",
-                       frr_protonameinst);
+               if (vty)
+                       vty_out(vty,
+                               "%% [%s] Argument form is unsupported or malformed.\n",
+                               frr_protonameinst);
+               else
+                       zlog_warn("Argument form is unsupported or malformed: "
+                                 "%s %s", command, arg);
                return CMD_WARNING_CONFIG_FAILED;
-               break;
        case RMAP_COMPILE_SUCCESS:
                break;
        }
@@ -578,15 +426,20 @@ int generic_set_delete(struct vty *vty, struct route_map_index *index,
        ret = route_map_delete_set(index, command, arg);
        switch (ret) {
        case RMAP_RULE_MISSING:
-               vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
+               if (vty)
+                       vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
+               else
+                       zlog_warn("Can't find rule: %s", command);
                return CMD_WARNING_CONFIG_FAILED;
-               break;
        case RMAP_COMPILE_ERROR:
-               vty_out(vty,
-                       "%% [%s] Argument form is unsupported or malformed.\n",
-                       frr_protonameinst);
+               if (vty)
+                       vty_out(vty,
+                               "%% [%s] Argument form is unsupported or malformed.\n",
+                               frr_protonameinst);
+               else
+                       zlog_warn("Argument form is unsupported or malformed: "
+                                 "%s %s", command, arg);
                return CMD_WARNING_CONFIG_FAILED;
-               break;
        case RMAP_COMPILE_SUCCESS:
                break;
        }
@@ -595,34 +448,8 @@ int generic_set_delete(struct vty *vty, struct route_map_index *index,
 }
 
 
-/* Route map rule. This rule has both `match' rule and `set' rule. */
-struct route_map_rule {
-       /* Rule type. */
-       const struct route_map_rule_cmd *cmd;
-
-       /* For pretty printing. */
-       char *rule_str;
-
-       /* Pre-compiled match rule. */
-       void *value;
-
-       /* Linked list. */
-       struct route_map_rule *next;
-       struct route_map_rule *prev;
-};
-
-/* Making route map list. */
-struct route_map_list {
-       struct route_map *head;
-       struct route_map *tail;
-
-       void (*add_hook)(const char *);
-       void (*delete_hook)(const char *);
-       void (*event_hook)(const char *);
-};
-
 /* Master list of route map. */
-static struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
+struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
 struct hash *route_map_master_hash = NULL;
 
 static unsigned int route_map_hash_key_make(const void *p)
@@ -683,7 +510,7 @@ struct route_map_dep_data {
 };
 
 /* Hashes maintaining dependency between various sublists used by route maps */
-struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
+static struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
 
 static unsigned int route_map_dep_hash_make_key(const void *p);
 static void route_map_clear_all_references(char *rmap_name);
@@ -691,8 +518,6 @@ static void route_map_rule_delete(struct route_map_rule_list *,
                                  struct route_map_rule *);
 static bool rmap_debug;
 
-static void route_map_index_delete(struct route_map_index *, int);
-
 /* New route map allocation. Please note route map's name must be
    specified. */
 static struct route_map *route_map_new(const char *name)
@@ -784,7 +609,7 @@ static void route_map_free_map(struct route_map *map)
 }
 
 /* Route map delete from list. */
-static void route_map_delete(struct route_map *map)
+void route_map_delete(struct route_map *map)
 {
        struct route_map_index *index;
        char *name;
@@ -883,7 +708,7 @@ static int route_map_clear_updated(struct route_map *map)
 
 /* Lookup route map.  If there isn't route map create one and return
    it. */
-static struct route_map *route_map_get(const char *name)
+struct route_map *route_map_get(const char *name)
 {
        struct route_map *map;
 
@@ -958,14 +783,6 @@ static const char *route_map_result_str(route_map_result_t res)
        return "invalid";
 }
 
-static int route_map_empty(struct route_map *map)
-{
-       if (map->head == NULL && map->tail == NULL)
-               return 1;
-       else
-               return 0;
-}
-
 /* show route-map */
 static void vty_show_route_map_entry(struct vty *vty, struct route_map *map)
 {
@@ -1092,12 +909,13 @@ static struct route_map_index *route_map_index_new(void)
 
        new = XCALLOC(MTYPE_ROUTE_MAP_INDEX, sizeof(struct route_map_index));
        new->exitpolicy = RMAP_EXIT; /* Default to Cisco-style */
+       TAILQ_INIT(&new->rhclist);
        QOBJ_REG(new, route_map_index);
        return new;
 }
 
 /* Free route map index. */
-static void route_map_index_delete(struct route_map_index *index, int notify)
+void route_map_index_delete(struct route_map_index *index, int notify)
 {
        struct route_map_rule *rule;
 
@@ -1107,6 +925,10 @@ static void route_map_index_delete(struct route_map_index *index, int notify)
                zlog_debug("Deleting route-map %s sequence %d",
                           index->map->name, index->pref);
 
+       /* Free route map northbound hook contexts. */
+       while (!TAILQ_EMPTY(&index->rhclist))
+               routemap_hook_context_free(TAILQ_FIRST(&index->rhclist));
+
        /* Free route match. */
        while ((rule = index->match_list.head) != NULL)
                route_map_rule_delete(&index->match_list, rule);
@@ -1202,7 +1024,7 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref)
 }
 
 /* Get route map index. */
-static struct route_map_index *
+struct route_map_index *
 route_map_index_get(struct route_map *map, enum route_map_type type, int pref)
 {
        struct route_map_index *index;
@@ -1335,7 +1157,7 @@ const char *route_map_get_match_arg(struct route_map_index *index,
                if (rule->cmd == cmd && rule->rule_str != NULL)
                        return (rule->rule_str);
 
-       return (NULL);
+       return NULL;
 }
 
 static route_map_event_t get_route_map_delete_event(route_map_event_t type)
@@ -2063,7 +1885,6 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name,
                        hash_free(dep->dep_rmap_hash);
                        XFREE(MTYPE_ROUTE_MAP_NAME, dep->dep_name);
                        XFREE(MTYPE_ROUTE_MAP_DEP, dep);
-                       dep = NULL;
                }
                break;
        case RMAP_EVENT_SET_ADDED:
@@ -2209,871 +2030,6 @@ void route_map_notify_dependencies(const char *affected_name,
 
 
 /* VTY related functions. */
-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 [WORD]",
-       NO_STR
-       MATCH_STR
-       "Match first hop interface of route\n"
-       "Interface name\n")
-{
-       char *iface = (argc == 4) ? argv[3]->arg : NULL;
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-
-       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) {
-               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_ip_next_hop_type, match_ip_next_hop_type_cmd,
-      "match ip next-hop type <blackhole>",
-      MATCH_STR IP_STR
-      "Match next-hop address of route\n"
-      "Match entries by type\n"
-      "Blackhole\n")
-{
-       int idx_word = 4;
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-
-       if (rmap_match_set_hook.match_ip_next_hop_type)
-               return rmap_match_set_hook.match_ip_next_hop_type(
-                       vty, index, "ip next-hop type", argv[idx_word]->arg,
-                       RMAP_EVENT_MATCH_ADDED);
-       return CMD_SUCCESS;
-}
-
-DEFUN(no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
-      "no match ip next-hop type [<blackhole>]",
-      NO_STR MATCH_STR IP_STR
-      "Match next-hop address of route\n"
-      "Match entries by type\n"
-      "Blackhole\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 type", NULL,
-                               RMAP_EVENT_MATCH_DELETED);
-               return rmap_match_set_hook.no_match_ip_next_hop(
-                       vty, index, "ip next-hop type", argv[idx_word]->arg,
-                       RMAP_EVENT_MATCH_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_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
-      "match ipv6 next-hop type <blackhole>",
-      MATCH_STR IPV6_STR
-      "Match next-hop address of route\n"
-      "Match entries by type\n"
-      "Blackhole\n")
-{
-       int idx_word = 4;
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-
-       if (rmap_match_set_hook.match_ipv6_next_hop_type)
-               return rmap_match_set_hook.match_ipv6_next_hop_type(
-                       vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
-                       RMAP_EVENT_MATCH_ADDED);
-       return CMD_SUCCESS;
-}
-
-DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
-      "no match ipv6 next-hop type [<blackhole>]",
-      NO_STR MATCH_STR IPV6_STR
-      "Match address of route\n"
-      "Match entries by type\n"
-      "Blackhole\n")
-{
-       int idx_word = 5;
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-
-       if (rmap_match_set_hook.no_match_ipv6_next_hop_type)
-               return rmap_match_set_hook.no_match_ipv6_next_hop_type(
-                       vty, index, "ipv6 next-hop type",
-                       (argc <= idx_word) ? NULL : argv[idx_word]->arg,
-                       RMAP_EVENT_MATCH_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);
-
-       int idx = 0;
-       char *arg = argv_find(argv, argc, "(1-4294967295)", &idx)
-                           ? argv[idx]->arg
-                           : NULL;
-
-       if (rmap_match_set_hook.no_match_tag)
-               return rmap_match_set_hook.no_match_tag(
-                       vty, index, "tag", 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\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       if (su.sin.sin_addr.s_addr == 0
-           || IPV4_CLASS_DE(ntohl(su.sin.sin_addr.s_addr))) {
-               vty_out(vty,
-                       "%% nexthop address cannot be 0.0.0.0, multicast or reserved\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       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 [A.B.C.D]",
-       NO_STR
-       SET_STR
-       IP_STR
-       "Next hop address\n"
-       "IP address of next hop\n")
-{
-       int idx = 0;
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       const char *arg = NULL;
-
-       if (argv_find(argv, argc, "A.B.C.D", &idx))
-               arg = argv[idx]->arg;
-
-       if (rmap_match_set_hook.no_set_ip_nexthop)
-               return rmap_match_set_hook.no_set_ip_nexthop(
-                       vty, index, "ip next-hop", 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\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       if (!IN6_IS_ADDR_LINKLOCAL(&addr)) {
-               vty_out(vty, "%% Invalid link-local nexthop address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       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);
-
-       const char *pass = (argv[idx_number]->type == RANGE_TKN)
-                                  ? argv[idx_number]->arg
-                                  : argv[idx_number]->text;
-
-       if (rmap_match_set_hook.set_metric)
-               return rmap_match_set_hook.set_metric(vty, index, "metric",
-                                                     pass);
-       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_NOSH (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(mapname);
-       index = route_map_index_get(map, permit, pref);
-
-       VTY_PUSH_CONTEXT(RMAP_NODE, index);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_route_map_all,
-       no_route_map_all_cmd,
-       "no route-map WORD",
-       NO_STR
-       "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(mapname);
-       if (map == NULL) {
-               vty_out(vty, "%% Could not find route-map %s\n", mapname);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       route_map_delete(map);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_route_map,
-       no_route_map_cmd,
-       "no route-map WORD <deny|permit> (1-65535)",
-       NO_STR
-       "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 = 2;
-       int idx_permit_deny = 3;
-       int idx_number = 4;
-       struct route_map *map;
-       struct route_map_index *index;
-       char *endptr = NULL;
-       int permit = strmatch(argv[idx_permit_deny]->text, "permit")
-                            ? 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(mapname);
-       if (map == NULL) {
-               vty_out(vty, "%% Could not find route-map %s\n", mapname);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Lookup route map index. */
-       index = route_map_index_lookup(map, permit, pref);
-       if (index == NULL) {
-               vty_out(vty, "%% Could not find route-map entry %s %s\n",
-                       mapname, prefstr);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Delete index from route map. */
-       route_map_index_delete(index, 1);
-
-       /* If this route rule is the last one, delete route map itself. */
-       if (route_map_empty(map))
-               route_map_delete(map);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (rmap_onmatch_next,
-       rmap_onmatch_next_cmd,
-       "on-match next",
-       "Exit policy on matches\n"
-       "Next clause\n")
-{
-       struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-
-       if (index) {
-               if (index->type == RMAP_DENY) {
-                       /* Under a deny clause, match means it's finished. No
-                        * need to set next */
-                       vty_out(vty,
-                               "on-match next not supported under route-map deny\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               index->exitpolicy = RMAP_NEXT;
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_rmap_onmatch_next,
-       no_rmap_onmatch_next_cmd,
-       "no on-match next",
-       NO_STR
-       "Exit policy on matches\n"
-       "Next clause\n")
-{
-       struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-
-       if (index)
-               index->exitpolicy = RMAP_EXIT;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (rmap_onmatch_goto,
-       rmap_onmatch_goto_cmd,
-       "on-match goto (1-65535)",
-       "Exit policy on matches\n"
-       "Goto Clause number\n"
-       "Number\n")
-{
-       int idx = 0;
-       char *num = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg
-                                                            : NULL;
-
-       struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-       int d = 0;
-
-       if (index) {
-               if (index->type == RMAP_DENY) {
-                       /* Under a deny clause, match means it's finished. No
-                        * need to go anywhere */
-                       vty_out(vty,
-                               "on-match goto not supported under route-map deny\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-
-               if (num)
-                       d = strtoul(num, NULL, 10);
-               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\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               } else {
-                       index->exitpolicy = RMAP_GOTO;
-                       index->nextpref = d;
-               }
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_rmap_onmatch_goto,
-       no_rmap_onmatch_goto_cmd,
-       "no on-match goto",
-       NO_STR
-       "Exit policy on matches\n"
-       "Goto Clause number\n")
-{
-       struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-
-       if (index)
-               index->exitpolicy = RMAP_EXIT;
-
-       return CMD_SUCCESS;
-}
-
-/* Cisco/GNU Zebra compatibility aliases */
-/* ALIAS_FIXME */
-DEFUN (rmap_continue,
-       rmap_continue_cmd,
-       "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_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);
-}
-
 static void clear_route_map_helper(struct route_map *map)
 {
        struct route_map_index *index;
@@ -3136,89 +2092,6 @@ DEFUN (rmap_show_unused,
        return vty_show_unused_route_map(vty);
 }
 
-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;
-
-       assert(index);
-
-       /* If "call" is invoked with the same route-map name as
-        * the one previously configured then, ignore the duplicate
-        * configuration.
-        */
-       if (index->nextrm && (strcmp(index->nextrm, rmap) == 0))
-               return CMD_SUCCESS;
-
-       if (index->nextrm) {
-               route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
-                                         index->nextrm, index->map->name);
-               XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
-       }
-       index->nextrm = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
-
-       /* Execute event hook. */
-       route_map_upd8_dependency(RMAP_EVENT_CALL_ADDED, index->nextrm,
-                                 index->map->name);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_rmap_call,
-       no_rmap_call_cmd,
-       "no call",
-       NO_STR
-       "Jump to another Route-Map after match+set\n")
-{
-       struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-
-       if (index->nextrm) {
-               route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
-                                         index->nextrm, index->map->name);
-               XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
-               index->nextrm = NULL;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (rmap_description,
-       rmap_description_cmd,
-       "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, idx_line);
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_rmap_description,
-       no_rmap_description_cmd,
-       "no description",
-       NO_STR
-       "Route-map comment\n")
-{
-       struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-
-       if (index) {
-               if (index->description)
-                       XFREE(MTYPE_TMP, index->description);
-               index->description = NULL;
-       }
-       return CMD_SUCCESS;
-}
-
 DEFUN (debug_rmap,
        debug_rmap_cmd,
        "debug route-map",
@@ -3244,59 +2117,6 @@ DEFUN (no_debug_rmap,
 static struct cmd_node rmap_debug_node = {RMAP_DEBUG_NODE, "", 1};
 
 /* Configuration write function. */
-static int route_map_config_write(struct vty *vty)
-{
-       struct route_map *map;
-       struct route_map_index *index;
-       struct route_map_rule *rule;
-       int first = 1;
-       int write = 0;
-       struct listnode *ln;
-       struct list *maplist = list_new();
-
-       for (map = route_map_master.head; map; map = map->next)
-               listnode_add(maplist, map);
-
-       list_sort(maplist, sort_route_map);
-
-       for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
-               for (index = map->head; index; index = index->next) {
-                       if (!first)
-                               vty_out(vty, "!\n");
-                       else
-                               first = 0;
-
-                       vty_out(vty, "route-map %s %s %d\n", map->name,
-                               route_map_type_str(index->type), index->pref);
-
-                       if (index->description)
-                               vty_out(vty, " description %s\n",
-                                       index->description);
-
-                       for (rule = index->match_list.head; rule;
-                            rule = rule->next)
-                               vty_out(vty, " match %s %s\n", rule->cmd->str,
-                                       rule->rule_str ? rule->rule_str : "");
-
-                       for (rule = index->set_list.head; rule;
-                            rule = rule->next)
-                               vty_out(vty, " set %s %s\n", rule->cmd->str,
-                                       rule->rule_str ? rule->rule_str : "");
-                       if (index->nextrm)
-                               vty_out(vty, " call %s\n", index->nextrm);
-                       if (index->exitpolicy == RMAP_GOTO)
-                               vty_out(vty, " on-match goto %d\n",
-                                       index->nextpref);
-                       if (index->exitpolicy == RMAP_NEXT)
-                               vty_out(vty, " on-match next\n");
-
-                       write++;
-               }
-
-       list_delete(&maplist);
-       return write;
-}
-
 static int rmap_config_write_debug(struct vty *vty)
 {
        int write = 0;
@@ -3309,9 +2129,6 @@ static int rmap_config_write_debug(struct vty *vty)
        return write;
 }
 
-/* Route map node structure. */
-static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# ", 1};
-
 /* Common route map rules */
 
 void *route_map_rule_tag_compile(const char *arg)
@@ -3370,14 +2187,6 @@ void route_map_finish(void)
        route_map_master_hash = NULL;
 }
 
-static void rmap_autocomplete(vector comps, struct cmd_token *token)
-{
-       struct route_map *map;
-
-       for (map = route_map_master.head; map; map = map->next)
-               vector_set(comps, XSTRDUP(MTYPE_COMPLETION, map->name));
-}
-
 /* Increment the use_count counter while attaching the route map */
 void route_map_counter_increment(struct route_map *map)
 {
@@ -3395,14 +2204,6 @@ void route_map_counter_decrement(struct route_map *map)
        }
 }
 
-static const struct cmd_variable_handler rmap_var_handlers[] = {
-       {/* "route-map WORD" */
-        .varname = "route_map",
-        .completions = rmap_autocomplete},
-       {.tokenname = "ROUTEMAP_NAME", .completions = rmap_autocomplete},
-       {.tokenname = "RMAP_NAME", .completions = rmap_autocomplete},
-       {.completions = NULL}};
-
 /* Initialization of route map vector. */
 void route_map_init(void)
 {
@@ -3420,43 +2221,17 @@ void route_map_init(void)
                        8, route_map_dep_hash_make_key, route_map_dep_hash_cmp,
                        "Route Map Dep Hash");
 
-       cmd_variable_handler_register(rmap_var_handlers);
-
        rmap_debug = false;
 
-       /* Install route map top node. */
-       install_node(&rmap_node, route_map_config_write);
+       route_map_cli_init();
 
+       /* Install route map top node. */
        install_node(&rmap_debug_node, rmap_config_write_debug);
 
        /* Install route map commands. */
-       install_default(RMAP_NODE);
-       install_element(CONFIG_NODE, &route_map_cmd);
-       install_element(CONFIG_NODE, &no_route_map_cmd);
-       install_element(CONFIG_NODE, &no_route_map_all_cmd);
-
        install_element(CONFIG_NODE, &debug_rmap_cmd);
        install_element(CONFIG_NODE, &no_debug_rmap_cmd);
 
-       /* Install the on-match stuff */
-       install_element(RMAP_NODE, &route_map_cmd);
-       install_element(RMAP_NODE, &rmap_onmatch_next_cmd);
-       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_element(RMAP_NODE, &rmap_continue_cmd);
-       install_element(RMAP_NODE, &no_rmap_continue_cmd);
-
-       /* Install the continue stuff (ALIAS of on-match). */
-
-       /* Install the call stuff. */
-       install_element(RMAP_NODE, &rmap_call_cmd);
-       install_element(RMAP_NODE, &no_rmap_call_cmd);
-
-       /* Install description commands. */
-       install_element(RMAP_NODE, &rmap_description_cmd);
-       install_element(RMAP_NODE, &no_rmap_description_cmd);
-
        /* Install show command */
        install_element(ENABLE_NODE, &rmap_clear_counters_cmd);
 
@@ -3465,49 +2240,4 @@ void route_map_init(void)
 
        install_element(ENABLE_NODE, &debug_rmap_cmd);
        install_element(ENABLE_NODE, &no_debug_rmap_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_ip_next_hop_type_cmd);
-       install_element(RMAP_NODE, &no_match_ip_next_hop_type_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_ipv6_next_hop_type_cmd);
-       install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_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);
 }