X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=lib%2Froutemap.c;h=a604c5921cd2b5ff454351a0fed75678d4fc0d96;hb=f94ed830df98218447f00b97f856de811bfcc4a2;hp=14fec0283cafebcb98f9e6559f3b61a5a0172afd;hpb=abe5af17744fa1775430aed978ac058dd011a4e1;p=mirror_frr.git diff --git a/lib/routemap.c b/lib/routemap.c index 14fec0283..a604c5921 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -50,178 +50,7 @@ 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); -}; - -static struct route_map_match_set_hooks rmap_match_set_hook; +struct route_map_match_set_hooks rmap_match_set_hook; /* match interface */ void route_map_match_interface_hook(int (*func)( @@ -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,35 +448,9 @@ 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}; -static struct hash *route_map_master_hash = 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) { @@ -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 ", - 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 []", - 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 ", - 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 []", - 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 (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 (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); }