diff --git a/lib/routemap.c b/lib/routemap.c index b836b55aad..33c65ac333 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -87,112 +87,126 @@ struct route_map_match_set_hooks rmap_match_set_hook; /* match interface */ void route_map_match_interface_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_interface = func; } /* no match interface */ void route_map_no_match_interface_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_interface = func; } /* match ip address */ void route_map_match_ip_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ip_address = func; } /* no match ip address */ void route_map_no_match_ip_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ip_address = func; } /* match ip address prefix list */ void route_map_match_ip_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ip_address_prefix_list = func; } /* no match ip address prefix list */ void route_map_no_match_ip_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ip_address_prefix_list = func; } /* match ip next hop */ void route_map_match_ip_next_hop_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ip_next_hop = func; } /* no match ip next hop */ void route_map_no_match_ip_next_hop_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ip_next_hop = func; } /* match ip next hop prefix list */ void route_map_match_ip_next_hop_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ip_next_hop_prefix_list = func; } /* no match ip next hop prefix list */ void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func; } /* match ip next-hop type */ void route_map_match_ip_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ip_next_hop_type = func; } /* no match ip next-hop type */ void route_map_no_match_ip_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ip_next_hop_type = func; } /* match ipv6 address */ void route_map_match_ipv6_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ipv6_address = func; } /* no match ipv6 address */ void route_map_no_match_ipv6_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ipv6_address = func; } @@ -200,178 +214,183 @@ void route_map_no_match_ipv6_address_hook(int (*func)( /* match ipv6 address prefix list */ void route_map_match_ipv6_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ipv6_address_prefix_list = func; } /* no match ipv6 address prefix list */ void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ipv6_address_prefix_list = func; } /* match ipv6 next-hop type */ void route_map_match_ipv6_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_ipv6_next_hop_type = func; } /* no match ipv6 next-hop type */ void route_map_no_match_ipv6_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_ipv6_next_hop_type = func; } /* match metric */ void route_map_match_metric_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_metric = func; } /* no match metric */ void route_map_no_match_metric_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_metric = func; } /* match tag */ -void route_map_match_tag_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_match_tag_hook(int (*func)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type)) + route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.match_tag = func; } /* no match tag */ void route_map_no_match_tag_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)) + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_match_tag = func; } /* set sr-te color */ -void route_map_set_srte_color_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_set_srte_color_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.set_srte_color = func; } /* no set sr-te color */ -void route_map_no_set_srte_color_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_no_set_srte_color_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_set_srte_color = func; } /* set ip nexthop */ -void route_map_set_ip_nexthop_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_set_ip_nexthop_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.set_ip_nexthop = func; } /* no set ip nexthop */ -void route_map_no_set_ip_nexthop_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_no_set_ip_nexthop_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, + size_t errmsg_len)) { rmap_match_set_hook.no_set_ip_nexthop = func; } /* set ipv6 nexthop local */ void route_map_set_ipv6_nexthop_local_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)) + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.set_ipv6_nexthop_local = func; } /* no set ipv6 nexthop local */ void route_map_no_set_ipv6_nexthop_local_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)) + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_set_ipv6_nexthop_local = func; } /* set metric */ -void route_map_set_metric_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_set_metric_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.set_metric = func; } /* no set metric */ -void route_map_no_set_metric_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_no_set_metric_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_set_metric = func; } /* set tag */ -void route_map_set_tag_hook(int (*func)(struct vty *vty, - struct route_map_index *index, - const char *command, const char *arg)) +void route_map_set_tag_hook(int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.set_tag = func; } /* no set tag */ -void route_map_no_set_tag_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +void route_map_no_set_tag_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)) + const char *arg, + char *errmsg, size_t errmsg_len)) { rmap_match_set_hook.no_set_tag = func; } -int generic_match_add(struct vty *vty, struct route_map_index *index, +int generic_match_add(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type) + route_map_event_t type, + char *errmsg, size_t errmsg_len) { enum rmap_compile_rets ret; ret = route_map_add_match(index, command, arg, type); switch (ret) { case RMAP_RULE_MISSING: - if (vty) - vty_out(vty, "%% [%s] Can't find rule.\n", - frr_protonameinst); - else - zlog_warn("Can't find rule: %s", command); + snprintf(errmsg, errmsg_len, "%% [%s] Can't find rule.", + frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_ERROR: - 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); + snprintf(errmsg, errmsg_len, + "%% [%s] Argument form is unsupported or malformed.", + frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_SUCCESS: /* @@ -383,9 +402,10 @@ int generic_match_add(struct vty *vty, struct route_map_index *index, return CMD_SUCCESS; } -int generic_match_delete(struct vty *vty, struct route_map_index *index, +int generic_match_delete(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type) + route_map_event_t type, + char *errmsg, size_t errmsg_len) { enum rmap_compile_rets ret; int retval = CMD_SUCCESS; @@ -409,20 +429,14 @@ 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: - if (vty) - vty_out(vty, "%% [%s] Can't find rule.\n", - frr_protonameinst); - else - zlog_warn("Can't find rule: %s", command); + snprintf(errmsg, errmsg_len, "%% [%s] Can't find rule.", + frr_protonameinst); retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_ERROR: - 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); + snprintf(errmsg, errmsg_len, + "%% [%s] Argument form is unsupported or malformed.", + frr_protonameinst); retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: @@ -438,26 +452,22 @@ int generic_match_delete(struct vty *vty, struct route_map_index *index, return retval; } -int generic_set_add(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg) +int generic_set_add(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len) { enum rmap_compile_rets ret; ret = route_map_add_set(index, command, arg); switch (ret) { case RMAP_RULE_MISSING: - if (vty) - vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst); - else - zlog_warn("Can't find rule: %s", command); + snprintf(errmsg, errmsg_len, + "%% [%s] Can't find rule.", frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_ERROR: - 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); + snprintf(errmsg, errmsg_len, + "%% [%s] Argument form is unsupported or malformed.", + frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_SUCCESS: break; @@ -466,26 +476,22 @@ int generic_set_add(struct vty *vty, struct route_map_index *index, return CMD_SUCCESS; } -int generic_set_delete(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg) +int generic_set_delete(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len) { enum rmap_compile_rets ret; ret = route_map_delete_set(index, command, arg); switch (ret) { case RMAP_RULE_MISSING: - if (vty) - vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst); - else - zlog_warn("Can't find rule: %s", command); + snprintf(errmsg, errmsg_len, "%% [%s] Can't find rule.", + frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_ERROR: - 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); + snprintf(errmsg, errmsg_len, + "%% [%s] Argument form is unsupported or malformed.", + frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_SUCCESS: break; @@ -2627,47 +2633,6 @@ static unsigned int route_map_dep_data_hash_make_key(const void *p) return string_hash_make(dep_data->rname); } -DEFUN (set_srte_color, - set_srte_color_cmd, - "set sr-te color [(1-4294967295)]", - SET_STR - SRTE_STR - SRTE_COLOR_STR - "Color of the SR-TE Policies to match with\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.set_srte_color) - return rmap_match_set_hook.set_srte_color(vty, index, - "sr-te color", arg); - return CMD_SUCCESS; -} - -DEFUN (no_set_srte_color, - no_set_srte_color_cmd, - "no set sr-te color [(1-4294967295)]", - NO_STR - SET_STR - SRTE_STR - SRTE_COLOR_STR - "Color of the SR-TE Policies to match with\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_set_srte_color) - return rmap_match_set_hook.no_set_srte_color( - vty, index, "sr-te color", arg); - return CMD_SUCCESS; -} - static void *route_map_dep_hash_alloc(void *p) { char *dep_name = (char *)p; @@ -3279,8 +3244,5 @@ void route_map_init(void) install_element(RMAP_NODE, &routemap_optimization_cmd); install_element(RMAP_NODE, &no_routemap_optimization_cmd); - install_element(RMAP_NODE, &set_srte_color_cmd); - install_element(RMAP_NODE, &no_set_srte_color_cmd); - install_element(ENABLE_NODE, &show_route_map_pfx_tbl_cmd); } diff --git a/lib/routemap.h b/lib/routemap.h index f1791405db..6385193bbf 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -229,6 +229,144 @@ struct route_map { }; DECLARE_QOBJ_TYPE(route_map); +/* Route-map match conditions */ +#define IS_MATCH_INTERFACE(C) \ + (strmatch(C, "frr-route-map:interface")) +#define IS_MATCH_IPv4_ADDRESS_LIST(C) \ + (strmatch(C, "frr-route-map:ipv4-address-list")) +#define IS_MATCH_IPv6_ADDRESS_LIST(C) \ + (strmatch(C, "frr-route-map:ipv6-address-list")) +#define IS_MATCH_IPv4_NEXTHOP_LIST(C) \ + (strmatch(C, "frr-route-map:ipv4-next-hop-list")) +#define IS_MATCH_IPv4_PREFIX_LIST(C) \ + (strmatch(C, "frr-route-map:ipv4-prefix-list")) +#define IS_MATCH_IPv6_PREFIX_LIST(C) \ + (strmatch(C, "frr-route-map:ipv6-prefix-list")) +#define IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(C) \ + (strmatch(C, "frr-route-map:ipv4-next-hop-prefix-list")) +#define IS_MATCH_IPv4_NEXTHOP_TYPE(C) \ + (strmatch(C, "frr-route-map:ipv4-next-hop-type")) +#define IS_MATCH_IPv6_NEXTHOP_TYPE(C) \ + (strmatch(C, "frr-route-map:ipv6-next-hop-type")) +#define IS_MATCH_METRIC(C) \ + (strmatch(C, "frr-route-map:match-metric")) +#define IS_MATCH_TAG(C) (strmatch(C, "frr-route-map:match-tag")) +/* Zebra route-map match conditions */ +#define IS_MATCH_IPv4_PREFIX_LEN(C) \ + (strmatch(C, "frr-zebra-route-map:ipv4-prefix-length")) +#define IS_MATCH_IPv6_PREFIX_LEN(C) \ + (strmatch(C, "frr-zebra-route-map:ipv6-prefix-length")) +#define IS_MATCH_IPv4_NH_PREFIX_LEN(C) \ + (strmatch(C, "frr-zebra-route-map:ipv4-next-hop-prefix-length")) +#define IS_MATCH_SRC_PROTO(C) \ + (strmatch(C, "frr-zebra-route-map:source-protocol")) +#define IS_MATCH_SRC_INSTANCE(C) \ + (strmatch(C, "frr-zebra-route-map:source-instance")) +/* BGP route-map match conditions */ +#define IS_MATCH_LOCAL_PREF(C) \ + (strmatch(C, "frr-bgp-route-map:match-local-preference")) +#define IS_MATCH_ORIGIN(C) \ + (strmatch(C, "frr-bgp-route-map:match-origin")) +#define IS_MATCH_RPKI(C) (strmatch(C, "frr-bgp-route-map:rpki")) +#define IS_MATCH_PROBABILITY(C) \ + (strmatch(C, "frr-bgp-route-map:probability")) +#define IS_MATCH_SRC_VRF(C) \ + (strmatch(C, "frr-bgp-route-map:source-vrf")) +#define IS_MATCH_PEER(C) (strmatch(C, "frr-bgp-route-map:peer")) +#define IS_MATCH_AS_LIST(C) \ + (strmatch(C, "frr-bgp-route-map:as-path-list")) +#define IS_MATCH_MAC_LIST(C) \ + (strmatch(C, "frr-bgp-route-map:mac-address-list")) +#define IS_MATCH_EVPN_ROUTE_TYPE(C) \ + (strmatch(C, "frr-bgp-route-map:evpn-route-type")) +#define IS_MATCH_EVPN_DEFAULT_ROUTE(C) \ + (strmatch(C, "frr-bgp-route-map:evpn-default-route")) +#define IS_MATCH_EVPN_VNI(C) \ + (strmatch(C, "frr-bgp-route-map:evpn-vni")) +#define IS_MATCH_EVPN_DEFAULT_ROUTE(C) \ + (strmatch(C, "frr-bgp-route-map:evpn-default-route")) +#define IS_MATCH_EVPN_RD(C) \ + (strmatch(C, "frr-bgp-route-map:evpn-rd")) +#define IS_MATCH_ROUTE_SRC(C) \ + (strmatch(C, "frr-bgp-route-map:ip-route-source")) +#define IS_MATCH_ROUTE_SRC_PL(C) \ + (strmatch(C, "frr-bgp-route-map:ip-route-source-prefix-list")) +#define IS_MATCH_COMMUNITY(C) \ + (strmatch(C, "frr-bgp-route-map:match-community")) +#define IS_MATCH_LCOMMUNITY(C) \ + (strmatch(C, "frr-bgp-route-map:match-large-community")) +#define IS_MATCH_EXTCOMMUNITY(C) \ + (strmatch(C, "frr-bgp-route-map:match-extcommunity")) +#define IS_MATCH_IPV4_NH(C) \ + (strmatch(C, "frr-bgp-route-map:ipv4-nexthop")) +#define IS_MATCH_IPV6_NH(C) \ + (strmatch(C, "frr-bgp-route-map:ipv6-nexthop")) + +/* Route-map set actions */ +#define IS_SET_IPv4_NH(A) \ + (strmatch(A, "frr-route-map:ipv4-next-hop")) +#define IS_SET_IPv6_NH(A) \ + (strmatch(A, "frr-route-map:ipv6-next-hop")) +#define IS_SET_METRIC(A) \ + (strmatch(A, "frr-route-map:set-metric")) +#define IS_SET_TAG(A) (strmatch(A, "frr-route-map:set-tag")) +#define IS_SET_SR_TE_COLOR(A) \ + (strmatch(A, "frr-route-map:set-sr-te-color")) +/* Zebra route-map set actions */ +#define IS_SET_SRC(A) \ + (strmatch(A, "frr-zebra-route-map:src-address")) +/* OSPF route-map set actions */ +#define IS_SET_METRIC_TYPE(A) \ + (strmatch(A, "frr-ospf-route-map:metric-type")) +#define IS_SET_FORWARDING_ADDR(A) \ + (strmatch(A, "frr-ospf6-route-map:forwarding-address")) +/* BGP route-map_set actions */ +#define IS_SET_WEIGHT(A) \ + (strmatch(A, "frr-bgp-route-map:weight")) +#define IS_SET_TABLE(A) (strmatch(A, "frr-bgp-route-map:table")) +#define IS_SET_LOCAL_PREF(A) \ + (strmatch(A, "frr-bgp-route-map:set-local-preference")) +#define IS_SET_LABEL_INDEX(A) \ + (strmatch(A, "frr-bgp-route-map:label-index")) +#define IS_SET_DISTANCE(A) \ + (strmatch(A, "frr-bgp-route-map:distance")) +#define IS_SET_ORIGIN(A) \ + (strmatch(A, "frr-bgp-route-map:set-origin")) +#define IS_SET_ATOMIC_AGGREGATE(A) \ + (strmatch(A, "frr-bgp-route-map:atomic-aggregate")) +#define IS_SET_ORIGINATOR_ID(A) \ + (strmatch(A, "frr-bgp-route-map:originator-id")) +#define IS_SET_COMM_LIST_DEL(A) \ + (strmatch(A, "frr-bgp-route-map:comm-list-delete")) +#define IS_SET_LCOMM_LIST_DEL(A) \ + (strmatch(A, "frr-bgp-route-map:large-comm-list-delete")) +#define IS_SET_LCOMMUNITY(A) \ + (strmatch(A, "frr-bgp-route-map:set-large-community")) +#define IS_SET_COMMUNITY(A) \ + (strmatch(A, "frr-bgp-route-map:set-community")) +#define IS_SET_EXTCOMMUNITY_RT(A) \ + (strmatch(A, "frr-bgp-route-map:set-extcommunity-rt")) +#define IS_SET_EXTCOMMUNITY_SOO(A) \ + (strmatch(A, "frr-bgp-route-map:set-extcommunity-soo")) +#define IS_SET_AGGREGATOR(A) \ + (strmatch(A, "frr-bgp-route-map:aggregator")) +#define IS_SET_AS_PREPEND(A) \ + (strmatch(A, "frr-bgp-route-map:as-path-prepend")) +#define IS_SET_AS_EXCLUDE(A) \ + (strmatch(A, "frr-bgp-route-map:as-path-exclude")) +#define IS_SET_IPV6_NH_GLOBAL(A) \ + (strmatch(A, "frr-bgp-route-map:ipv6-nexthop-global")) +#define IS_SET_IPV6_VPN_NH(A) \ + (strmatch(A, "frr-bgp-route-map:ipv6-vpn-address")) +#define IS_SET_IPV6_PEER_ADDR(A) \ + (strmatch(A, "frr-bgp-route-map:ipv6-peer-address")) +#define IS_SET_IPV6_PREFER_GLOBAL(A) \ + (strmatch(A, "frr-bgp-route-map:ipv6-prefer-global")) +#define IS_SET_IPV4_VPN_NH(A) \ + (strmatch(A, "frr-bgp-route-map:ipv4-vpn-address")) +#define IS_SET_BGP_IPV4_NH(A) \ + (strmatch(A, "frr-bgp-route-map:set-ipv4-nexthop")) + /* Prototypes. */ extern void route_map_init(void); @@ -310,150 +448,186 @@ extern void route_map_notify_pentry_dependencies(const char *affected_name, struct prefix_list_entry *pentry, route_map_event_t event); -extern int generic_match_add(struct vty *vty, struct route_map_index *index, +extern int generic_match_add(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); - -extern int generic_match_delete(struct vty *vty, struct route_map_index *index, + route_map_event_t type, + char *errmsg, size_t errmsg_len); +extern int generic_match_delete(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); -extern int generic_set_add(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); -extern int generic_set_delete(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + route_map_event_t type, + char *errmsg, size_t errmsg_len); + +extern int generic_set_add(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); +extern int generic_set_delete(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* match interface */ extern void route_map_match_interface_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match interface */ extern void route_map_no_match_interface_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ip address */ extern void route_map_match_ip_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ip address */ extern void route_map_no_match_ip_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ip address prefix list */ extern void route_map_match_ip_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ip address prefix list */ extern void route_map_no_match_ip_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ip next hop */ extern void route_map_match_ip_next_hop_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ip next hop */ extern void route_map_no_match_ip_next_hop_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ip next hop prefix list */ extern void route_map_match_ip_next_hop_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ip next hop prefix list */ extern void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ip next hop type */ extern void route_map_match_ip_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ip next hop type */ extern void route_map_no_match_ip_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ipv6 address */ extern void route_map_match_ipv6_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ipv6 address */ extern void route_map_no_match_ipv6_address_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ipv6 address prefix list */ extern void route_map_match_ipv6_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ipv6 address prefix list */ extern void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match ipv6 next-hop type */ extern void route_map_match_ipv6_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match ipv6 next-hop type */ extern void route_map_no_match_ipv6_next_hop_type_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match metric */ extern void route_map_match_metric_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match metric */ extern void route_map_no_match_metric_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* match tag */ extern void route_map_match_tag_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* no match tag */ extern void route_map_no_match_tag_hook(int (*func)( - struct vty *vty, struct route_map_index *index, const char *command, - const char *arg, route_map_event_t type)); + struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type, + char *errmsg, size_t errmsg_len)); /* set sr-te color */ extern void route_map_set_srte_color_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* no set sr-te color */ extern void route_map_no_set_srte_color_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* set ip nexthop */ extern void route_map_set_ip_nexthop_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* no set ip nexthop */ extern void route_map_no_set_ip_nexthop_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* set ipv6 nexthop local */ extern void route_map_set_ipv6_nexthop_local_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* no set ipv6 nexthop local */ extern void route_map_no_set_ipv6_nexthop_local_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* set metric */ -extern void route_map_set_metric_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +extern void route_map_set_metric_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)); + const char *arg, + char *errmsg, + size_t errmsg_len)); /* no set metric */ extern void route_map_no_set_metric_hook( - int (*func)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg)); + int (*func)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len)); /* set tag */ -extern void route_map_set_tag_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +extern void route_map_set_tag_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)); + const char *arg, + char *errmsg, + size_t errmsg_len)); /* no set tag */ -extern void route_map_no_set_tag_hook(int (*func)(struct vty *vty, - struct route_map_index *index, +extern void route_map_no_set_tag_hook(int (*func)(struct route_map_index *index, const char *command, - const char *arg)); + const char *arg, + char *errmsg, + size_t errmsg_len)); extern void *route_map_rule_tag_compile(const char *arg); extern void route_map_rule_tag_free(void *rule); @@ -467,181 +641,200 @@ extern void route_map_counter_decrement(struct route_map *map); /* Route map hooks data structure. */ struct route_map_match_set_hooks { /* match interface */ - int (*match_interface)(struct vty *vty, struct route_map_index *index, + int (*match_interface)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match interface */ - int (*no_match_interface)(struct vty *vty, - struct route_map_index *index, + int (*no_match_interface)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match ip address */ - int (*match_ip_address)(struct vty *vty, struct route_map_index *index, + int (*match_ip_address)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ip address */ - int (*no_match_ip_address)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ip_address)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match ip address prefix list */ - int (*match_ip_address_prefix_list)(struct vty *vty, - struct route_map_index *index, + int (*match_ip_address_prefix_list)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ip address prefix list */ - int (*no_match_ip_address_prefix_list)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ip_address_prefix_list)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match ip next hop */ - int (*match_ip_next_hop)(struct vty *vty, struct route_map_index *index, + int (*match_ip_next_hop)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ip next hop */ - int (*no_match_ip_next_hop)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ip_next_hop)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match ip next hop prefix list */ - int (*match_ip_next_hop_prefix_list)(struct vty *vty, - struct route_map_index *index, + int (*match_ip_next_hop_prefix_list)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ip next hop prefix list */ - int (*no_match_ip_next_hop_prefix_list)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ip_next_hop_prefix_list)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, + size_t errmsg_len); /* 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); + int (*match_ip_next_hop_type)(struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type, + char *errmsg, + size_t errmsg_len); /* 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); + int (*no_match_ip_next_hop_type)(struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type, + char *errmsg, + size_t errmsg_len); /* match ipv6 address */ - int (*match_ipv6_address)(struct vty *vty, - struct route_map_index *index, + int (*match_ipv6_address)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ipv6 address */ - int (*no_match_ipv6_address)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ipv6_address)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match ipv6 address prefix list */ - int (*match_ipv6_address_prefix_list)(struct vty *vty, - struct route_map_index *index, + int (*match_ipv6_address_prefix_list)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ipv6 address prefix list */ - int (*no_match_ipv6_address_prefix_list)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ipv6_address_prefix_list)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, + size_t errmsg_len); /* match ipv6 next-hop type */ - int (*match_ipv6_next_hop_type)(struct vty *vty, - struct route_map_index *index, + int (*match_ipv6_next_hop_type)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match ipv6 next-hop type */ - int (*no_match_ipv6_next_hop_type)(struct vty *vty, - struct route_map_index *index, + int (*no_match_ipv6_next_hop_type)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match metric */ - int (*match_metric)(struct vty *vty, struct route_map_index *index, + int (*match_metric)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match metric */ - int (*no_match_metric)(struct vty *vty, struct route_map_index *index, + int (*no_match_metric)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* match tag */ - int (*match_tag)(struct vty *vty, struct route_map_index *index, + int (*match_tag)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* no match tag */ - int (*no_match_tag)(struct vty *vty, struct route_map_index *index, + int (*no_match_tag)(struct route_map_index *index, const char *command, const char *arg, - route_map_event_t type); + route_map_event_t type, + char *errmsg, size_t errmsg_len); /* set sr-te color */ - int (*set_srte_color)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*set_srte_color)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* no set sr-te color */ - int (*no_set_srte_color)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*no_set_srte_color)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* set ip nexthop */ - int (*set_ip_nexthop)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*set_ip_nexthop)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* no set ip nexthop */ - int (*no_set_ip_nexthop)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*no_set_ip_nexthop)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* set ipv6 nexthop local */ - int (*set_ipv6_nexthop_local)(struct vty *vty, - struct route_map_index *index, - const char *command, const char *arg); + int (*set_ipv6_nexthop_local)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* 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); + int (*no_set_ipv6_nexthop_local)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* set metric */ - int (*set_metric)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*set_metric)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* no set metric */ - int (*no_set_metric)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*no_set_metric)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* set tag */ - int (*set_tag)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*set_tag)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); /* no set tag */ - int (*no_set_tag)(struct vty *vty, struct route_map_index *index, - const char *command, const char *arg); + int (*no_set_tag)(struct route_map_index *index, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); }; extern struct route_map_match_set_hooks rmap_match_set_hook; @@ -666,15 +859,13 @@ extern struct route_map_index *route_map_index_get(struct route_map *map, extern void route_map_index_delete(struct route_map_index *index, int notify); /* routemap_northbound.c */ -typedef int (*routemap_match_hook_fun)(struct vty *vty, - struct route_map_index *rmi, +typedef int (*routemap_match_hook_fun)(struct route_map_index *rmi, const char *command, const char *arg, - route_map_event_t event); - -typedef int (*routemap_set_hook_fun)(struct vty *vty, - struct route_map_index *rmi, - const char *command, const char *arg); - + route_map_event_t event, + char *errmsg, size_t errmsg_len); +typedef int (*routemap_set_hook_fun)(struct route_map_index *rmi, + const char *command, const char *arg, + char *errmsg, size_t errmsg_len); struct routemap_hook_context { struct route_map_index *rhc_rmi; const char *rhc_rule; diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index bf61e10fe4..9a53c11a4c 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -46,9 +46,6 @@ DEFPY_YANG_NOSH( ROUTE_MAP_OP_CMD_STR ROUTE_MAP_SEQUENCE_CMD_STR) { - struct route_map_index *rmi; - struct route_map *rm; - int action_type; char xpath_action[XPATH_MAXLEN + 64]; char xpath_index[XPATH_MAXLEN + 32]; char xpath[XPATH_MAXLEN]; @@ -66,17 +63,9 @@ DEFPY_YANG_NOSH( nb_cli_enqueue_change(vty, xpath_action, NB_OP_MODIFY, action); rv = nb_cli_apply_changes(vty, NULL); - if (rv == CMD_SUCCESS) { + if (rv == CMD_SUCCESS) VTY_PUSH_XPATH(RMAP_NODE, xpath_index); - /* Add support for non-migrated route map users. */ - nb_cli_pending_commit_check(vty); - rm = route_map_get(name); - action_type = (action[0] == 'p') ? RMAP_PERMIT : RMAP_DENY; - rmi = route_map_index_get(rm, action_type, sequence); - VTY_PUSH_CONTEXT(RMAP_NODE, rmi); - } - return rv; } @@ -108,6 +97,7 @@ DEFPY_YANG( snprintf(xpath, sizeof(xpath), "/frr-route-map:lib/route-map[name='%s']/entry[sequence='%lu']", name, sequence); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); return nb_cli_apply_changes(vty, NULL); @@ -124,63 +114,12 @@ int route_map_instance_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2) void route_map_instance_show(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - const struct route_map_rule *rmr; - const struct route_map_index *rmi; const char *name = yang_dnode_get_string(dnode, "../name"); const char *action = yang_dnode_get_string(dnode, "./action"); const char *sequence = yang_dnode_get_string(dnode, "./sequence"); vty_out(vty, "route-map %s %s %s\n", name, action, sequence); - rmi = nb_running_get_entry(dnode, NULL, false); - if (rmi == NULL) { - /* - * We can't have outdated rules if route map hasn't - * been created yet. - */ - return; - } - -#define SKIP_RULE(name) if (strcmp((name), rmr->cmd->str) == 0) continue - - /* Print route map `match` for old CLI users. */ - for (rmr = rmi->match_list.head; rmr; rmr = rmr->next) { - /* Skip all matches implemented by northbound. */ - SKIP_RULE("interface"); - SKIP_RULE("ip address"); - SKIP_RULE("ip address prefix-list"); - SKIP_RULE("ip next-hop"); - SKIP_RULE("ip next-hop prefix-list"); - SKIP_RULE("ip next-hop type"); - SKIP_RULE("ipv6 address"); - SKIP_RULE("ipv6 address prefix-list"); - SKIP_RULE("ipv6 next-hop type"); - SKIP_RULE("metric"); - SKIP_RULE("tag"); - /* Zebra specific match conditions. */ - SKIP_RULE("ip address prefix-len"); - SKIP_RULE("ipv6 address prefix-len"); - SKIP_RULE("ip next-hop prefix-len"); - SKIP_RULE("source-protocol"); - SKIP_RULE("source-instance"); - - vty_out(vty, " match %s %s\n", rmr->cmd->str, - rmr->rule_str ? rmr->rule_str : ""); - } - - /* Print route map `set` for old CLI users. */ - for (rmr = rmi->set_list.head; rmr; rmr = rmr->next) { - /* Skip all sets implemented by northbound. */ - SKIP_RULE("metric"); - SKIP_RULE("tag"); - /* Zebra specific set actions. */ - SKIP_RULE("src"); - - vty_out(vty, " set %s %s\n", rmr->cmd->str, - rmr->rule_str ? rmr->rule_str : ""); - } - -#undef SKIP_RULE } void route_map_instance_show_end(struct vty *vty, struct lyd_node *dnode) @@ -195,11 +134,13 @@ DEFPY_YANG( "Match first hop interface of route\n" INTERFACE_STR) { - const char *xpath = "./match-condition[condition='interface']"; + const char *xpath = + "./match-condition[condition='frr-route-map:interface']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/interface", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/interface", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ifname); return nb_cli_apply_changes(vty, NULL); @@ -213,7 +154,8 @@ DEFPY_YANG( "Match first hop interface of route\n" INTERFACE_STR) { - const char *xpath = "./match-condition[condition='interface']"; + const char *xpath = + "./match-condition[condition='frr-route-map:interface']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -230,11 +172,13 @@ DEFPY_YANG( "IP access-list number (expanded range)\n" "IP Access-list name\n") { - const char *xpath = "./match-condition[condition='ipv4-address-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-address-list']"; char xpath_value[XPATH_MAXLEN + 32]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name); return nb_cli_apply_changes(vty, NULL); @@ -251,7 +195,8 @@ DEFPY_YANG( "IP access-list number (expanded range)\n" "IP Access-list name\n") { - const char *xpath = "./match-condition[condition='ipv4-address-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-address-list']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -268,11 +213,13 @@ DEFPY_YANG( "Match entries of prefix-lists\n" "IP prefix-list name\n") { - const char *xpath = "./match-condition[condition='ipv4-prefix-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-prefix-list']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name); return nb_cli_apply_changes(vty, NULL); @@ -288,7 +235,8 @@ DEFPY_YANG( "Match entries of prefix-lists\n" "IP prefix-list name\n") { - const char *xpath = "./match-condition[condition='ipv4-prefix-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-prefix-list']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -305,11 +253,13 @@ DEFPY_YANG( "IP access-list number (expanded range)\n" "IP Access-list name\n") { - const char *xpath = "./match-condition[condition='ipv4-next-hop-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-next-hop-list']"; char xpath_value[XPATH_MAXLEN + 32]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name); return nb_cli_apply_changes(vty, NULL); @@ -326,7 +276,8 @@ DEFPY_YANG( "IP access-list number (expanded range)\n" "IP Access-list name\n") { - const char *xpath = "./match-condition[condition='ipv4-next-hop-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-next-hop-list']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -344,11 +295,12 @@ DEFPY_YANG( "IP prefix-list name\n") { const char *xpath = - "./match-condition[condition='ipv4-next-hop-prefix-list']"; + "./match-condition[condition='frr-route-map:ipv4-next-hop-prefix-list']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name); return nb_cli_apply_changes(vty, NULL); @@ -366,7 +318,7 @@ DEFPY_YANG( "IP prefix-list name\n") { const char *xpath = - "./match-condition[condition='ipv4-next-hop-prefix-list']"; + "./match-condition[condition='frr-route-map:ipv4-next-hop-prefix-list']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -382,12 +334,13 @@ DEFPY_YANG( "Match entries by type\n" "Blackhole\n") { - const char *xpath = "./match-condition[condition='ipv4-next-hop-type']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-next-hop-type']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/ipv4-next-hop-type", - xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/ipv4-next-hop-type", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, type); return nb_cli_apply_changes(vty, NULL); @@ -401,7 +354,8 @@ DEFPY_YANG( "Match entries by type\n" "Blackhole\n") { - const char *xpath = "./match-condition[condition='ipv4-next-hop-type']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv4-next-hop-type']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -416,11 +370,13 @@ DEFPY_YANG( "Match IPv6 address of route\n" "IPv6 access-list name\n") { - const char *xpath = "./match-condition[condition='ipv6-address-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-address-list']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name); return nb_cli_apply_changes(vty, NULL); @@ -435,7 +391,8 @@ DEFPY_YANG( "Match IPv6 address of route\n" "IPv6 access-list name\n") { - const char *xpath = "./match-condition[condition='ipv6-address-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-address-list']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -451,11 +408,13 @@ DEFPY_YANG( "Match entries of prefix-lists\n" "IP prefix-list name\n") { - const char *xpath = "./match-condition[condition='ipv6-prefix-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-prefix-list']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name); return nb_cli_apply_changes(vty, NULL); @@ -472,7 +431,8 @@ DEFPY_YANG( "Match entries of prefix-lists\n" "IP prefix-list name\n") { - const char *xpath = "./match-condition[condition='ipv6-prefix-list']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-prefix-list']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -487,12 +447,13 @@ DEFPY_YANG( "Match entries by type\n" "Blackhole\n") { - const char *xpath = "./match-condition[condition='ipv6-next-hop-type']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-next-hop-type']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/ipv6-next-hop-type", - xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/ipv6-next-hop-type", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, type); return nb_cli_apply_changes(vty, NULL); @@ -506,7 +467,8 @@ DEFPY_YANG( "Match entries by type\n" "Blackhole\n") { - const char *xpath = "./match-condition[condition='ipv6-next-hop-type']"; + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-next-hop-type']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -520,11 +482,13 @@ DEFPY_YANG( "Match metric of route\n" "Metric value\n") { - const char *xpath = "./match-condition[condition='metric']"; + const char *xpath = + "./match-condition[condition='frr-route-map:match-metric']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/metric", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/metric", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, metric_str); return nb_cli_apply_changes(vty, NULL); @@ -538,7 +502,8 @@ DEFPY_YANG( "Match metric of route\n" "Metric value\n") { - const char *xpath = "./match-condition[condition='metric']"; + const char *xpath = + "./match-condition[condition='frr-route-map:match-metric']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -552,11 +517,13 @@ DEFPY_YANG( "Match tag of route\n" "Tag value\n") { - const char *xpath = "./match-condition[condition='tag']"; + const char *xpath = + "./match-condition[condition='frr-route-map:match-tag']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/tag", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/tag", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str); return nb_cli_apply_changes(vty, NULL); @@ -570,7 +537,8 @@ DEFPY_YANG( "Match tag of route\n" "Tag value\n") { - const char *xpath = "./match-condition[condition='tag']"; + const char *xpath = + "./match-condition[condition='frr-route-map:match-tag']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -580,78 +548,259 @@ DEFPY_YANG( void route_map_condition_show(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - int condition = yang_dnode_get_enum(dnode, "./condition"); + const char *condition = yang_dnode_get_string(dnode, "./condition"); + struct lyd_node *ln; + const char *acl; - switch (condition) { - case 0: /* interface */ + if (IS_MATCH_INTERFACE(condition)) { vty_out(vty, " match interface %s\n", - yang_dnode_get_string(dnode, "./interface")); - break; - case 1: /* ipv4-address-list */ - case 3: /* ipv4-next-hop-list */ - switch (condition) { - case 1: - vty_out(vty, " match ip address %s\n", - yang_dnode_get_string(dnode, "./list-name")); - break; - case 3: - vty_out(vty, " match ip next-hop %s\n", - yang_dnode_get_string(dnode, "./list-name")); - break; - } - break; - case 2: /* ipv4-prefix-list */ + yang_dnode_get_string( + dnode, "./rmap-match-condition/interface")); + } else if (IS_MATCH_IPv4_ADDRESS_LIST(condition) + || IS_MATCH_IPv4_NEXTHOP_LIST(condition)) { + acl = NULL; + if ((ln = yang_dnode_get(dnode, + "./rmap-match-condition/list-name")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + + assert(acl); + + if (IS_MATCH_IPv4_ADDRESS_LIST(condition)) + vty_out(vty, " match ip address %s\n", acl); + else + vty_out(vty, " match ip next-hop %s\n", acl); + } else if (IS_MATCH_IPv4_PREFIX_LIST(condition)) { vty_out(vty, " match ip address prefix-list %s\n", - yang_dnode_get_string(dnode, "./list-name")); - break; - case 4: /* ipv4-next-hop-prefix-list */ + yang_dnode_get_string( + dnode, "./rmap-match-condition/list-name")); + } else if (IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(condition)) { vty_out(vty, " match ip next-hop prefix-list %s\n", - yang_dnode_get_string(dnode, "./list-name")); - break; - case 5: /* ipv4-next-hop-type */ - vty_out(vty, " match ip next-hop type %s\n", - yang_dnode_get_string(dnode, "./ipv4-next-hop-type")); - break; - case 6: /* ipv6-address-list */ + yang_dnode_get_string( + dnode, "./rmap-match-condition/list-name")); + } else if (IS_MATCH_IPv6_ADDRESS_LIST(condition)) { vty_out(vty, " match ipv6 address %s\n", - yang_dnode_get_string(dnode, "./list-name")); - break; - case 7: /* ipv6-prefix-list */ + yang_dnode_get_string( + dnode, "./rmap-match-condition/list-name")); + } else if (IS_MATCH_IPv6_PREFIX_LIST(condition)) { vty_out(vty, " match ipv6 address prefix-list %s\n", - yang_dnode_get_string(dnode, "./list-name")); - break; - case 8: /* ipv6-next-hop-type */ + yang_dnode_get_string( + dnode, "./rmap-match-condition/list-name")); + } else if (IS_MATCH_IPv4_NEXTHOP_TYPE(condition)) { + vty_out(vty, " match ip next-hop type %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/ipv4-next-hop-type")); + } else if (IS_MATCH_IPv6_NEXTHOP_TYPE(condition)) { vty_out(vty, " match ipv6 next-hop type %s\n", - yang_dnode_get_string(dnode, "./ipv6-next-hop-type")); - break; - case 9: /* metric */ + yang_dnode_get_string( + dnode, + "./rmap-match-condition/ipv6-next-hop-type")); + } else if (IS_MATCH_METRIC(condition)) { vty_out(vty, " match metric %s\n", - yang_dnode_get_string(dnode, "./metric")); - break; - case 10: /* tag */ + yang_dnode_get_string(dnode, + "./rmap-match-condition/metric")); + } else if (IS_MATCH_TAG(condition)) { vty_out(vty, " match tag %s\n", - yang_dnode_get_string(dnode, "./tag")); - break; - case 100: /* ipv4-prefix-length */ + yang_dnode_get_string(dnode, + "./rmap-match-condition/tag")); + } else if (IS_MATCH_IPv4_PREFIX_LEN(condition)) { vty_out(vty, " match ip address prefix-len %s\n", - yang_dnode_get_string(dnode,"./frr-zebra:ipv4-prefix-length")); - break; - case 101: /* ipv6-prefix-length */ + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length")); + } else if (IS_MATCH_IPv6_PREFIX_LEN(condition)) { vty_out(vty, " match ipv6 address prefix-len %s\n", - yang_dnode_get_string(dnode, "./frr-zebra:ipv6-prefix-length")); - break; - case 102: /* ipv4-next-hop-prefix-length */ + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-zebra-route-map:ipv6-prefix-length")); + } else if (IS_MATCH_IPv4_NH_PREFIX_LEN(condition)) { vty_out(vty, " match ip next-hop prefix-len %s\n", - yang_dnode_get_string(dnode, "./frr-zebra:ipv4-prefix-length")); - break; - case 103: /* source-protocol */ + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length")); + } else if (IS_MATCH_SRC_PROTO(condition)) { vty_out(vty, " match source-protocol %s\n", - yang_dnode_get_string(dnode, "./frr-zebra:source-protocol")); - break; - case 104: /* source-instance */ + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-zebra-route-map:source-protocol")); + } else if (IS_MATCH_SRC_INSTANCE(condition)) { vty_out(vty, " match source-instance %s\n", - yang_dnode_get_string(dnode, "./frr-zebra:source-instance")); - break; + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-zebra-route-map:source-instance")); + } else if (IS_MATCH_LOCAL_PREF(condition)) { + vty_out(vty, " match local-preference %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:local-preference")); + } else if (IS_MATCH_ORIGIN(condition)) { + vty_out(vty, " match origin %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:origin")); + } else if (IS_MATCH_RPKI(condition)) { + vty_out(vty, " match rpki %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:rpki")); + } else if (IS_MATCH_PROBABILITY(condition)) { + vty_out(vty, " match probability %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:probability")); + } else if (IS_MATCH_SRC_VRF(condition)) { + vty_out(vty, " match source-vrf %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:source-vrf")); + } else if (IS_MATCH_PEER(condition)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:peer-ipv4-address")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + else if ( + (ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:peer-ipv6-address")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + else if ( + (ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:peer-interface")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + else if (yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:peer-local") + != NULL) + acl = "local"; + + vty_out(vty, " match peer %s\n", acl); + } else if (IS_MATCH_AS_LIST(condition)) { + vty_out(vty, " match as-path %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:list-name")); + } else if (IS_MATCH_EVPN_ROUTE_TYPE(condition)) { + vty_out(vty, " match evpn route-type %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:evpn-route-type")); + } else if (IS_MATCH_EVPN_DEFAULT_ROUTE(condition)) { + vty_out(vty, " match evpn default-route\n"); + } else if (IS_MATCH_EVPN_VNI(condition)) { + vty_out(vty, " match evpn vni %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:evpn-vni")); + } else if (IS_MATCH_EVPN_DEFAULT_ROUTE(condition)) { + vty_out(vty, " match evpn default-route %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:evpn-default-route")); + } else if (IS_MATCH_EVPN_RD(condition)) { + vty_out(vty, " match evpn rd %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:route-distinguisher")); + } else if (IS_MATCH_MAC_LIST(condition)) { + vty_out(vty, " match mac address %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:list-name")); + } else if (IS_MATCH_ROUTE_SRC(condition)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:list-name")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + + assert(acl); + + vty_out(vty, " match ip route-source %s\n", acl); + } else if (IS_MATCH_ROUTE_SRC_PL(condition)) { + vty_out(vty, " match ip route-source prefix-list %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:list-name")); + } else if (IS_MATCH_ROUTE_SRC(condition)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:list-name")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + + assert(acl); + + vty_out(vty, " match ip route-source %s\n", acl); + } else if (IS_MATCH_COMMUNITY(condition)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name")) + != NULL) { + acl = yang_dnode_get_string(ln, NULL); + + if (true + == yang_dnode_get_bool( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match")) + vty_out(vty, + " match community %s exact-match\n", + acl); + else + vty_out(vty, " match community %s\n", acl); + } + + assert(acl); + } else if (IS_MATCH_LCOMMUNITY(condition)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name")) + != NULL) { + acl = yang_dnode_get_string(ln, NULL); + + if (true + == yang_dnode_get_bool( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match")) + vty_out(vty, + " match large-community %s exact-match\n", + acl); + else + vty_out(vty, " match large-community %s\n", + acl); + } + + assert(acl); + } else if (IS_MATCH_EXTCOMMUNITY(condition)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + + assert(acl); + + vty_out(vty, " match extcommunity %s\n", acl); + } else if (IS_MATCH_IPV4_NH(condition)) { + vty_out(vty, " match ip next-hop %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:ipv4-address")); + } else if (IS_MATCH_IPV6_NH(condition)) { + vty_out(vty, " match ipv6 next-hop %s\n", + yang_dnode_get_string( + dnode, + "./rmap-match-condition/frr-bgp-route-map:ipv6-address")); } } @@ -663,11 +812,13 @@ DEFPY_YANG( "Next hop address\n" "IP address of next hop\n") { - const char *xpath = "./set-action[action='ipv4-next-hop']"; + const char *xpath = + "./set-action[action='frr-route-map:ipv4-next-hop']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/ipv4-address", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/ipv4-address", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, addr_str); return nb_cli_apply_changes(vty, NULL); @@ -682,7 +833,8 @@ DEFPY_YANG( "Next hop address\n" "IP address of next hop\n") { - const char *xpath = "./set-action[action='ipv4-next-hop']"; + const char *xpath = + "./set-action[action='frr-route-map:ipv4-next-hop']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -698,11 +850,13 @@ DEFPY_YANG( "IPv6 local address\n" "IPv6 address of next hop\n") { - const char *xpath = "./set-action[action='ipv6-next-hop']"; + const char *xpath = + "./set-action[action='frr-route-map:ipv6-next-hop']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/ipv6-address", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/ipv6-address", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, addr_str); return nb_cli_apply_changes(vty, NULL); @@ -718,7 +872,8 @@ DEFPY_YANG( "IPv6 local address\n" "IPv6 address of next hop\n") { - const char *xpath = "./set-action[action='ipv6-next-hop']"; + const char *xpath = + "./set-action[action='frr-route-map:ipv6-next-hop']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); @@ -735,33 +890,34 @@ DEFPY_YANG( "Add round trip time\n" "Subtract round trip time\n") { - const char *xpath = "./set-action[action='metric']"; + const char *xpath = "./set-action[action='frr-route-map:set-metric']"; char xpath_value[XPATH_MAXLEN]; char value[64]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (rtt) { snprintf(xpath_value, sizeof(xpath_value), - "%s/use-round-trip-time", xpath); + "%s/rmap-set-action/use-round-trip-time", xpath); snprintf(value, sizeof(value), "true"); } else if (artt) { snprintf(xpath_value, sizeof(xpath_value), - "%s/add-round-trip-time", xpath); + "%s/rmap-set-action/add-round-trip-time", xpath); snprintf(value, sizeof(value), "true"); } else if (srtt) { snprintf(xpath_value, sizeof(xpath_value), - "%s/subtract-round-trip-time", xpath); + "%s/rmap-set-action/subtract-round-trip-time", xpath); snprintf(value, sizeof(value), "true"); } else if (metric_str && metric_str[0] == '+') { - snprintf(xpath_value, sizeof(xpath_value), "%s/add-metric", - xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/add-metric", xpath); snprintf(value, sizeof(value), "%s", ++metric_str); } else if (metric_str && metric_str[0] == '-') { - snprintf(xpath_value, sizeof(xpath_value), "%s/subtract-metric", - xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/subtract-metric", xpath); snprintf(value, sizeof(value), "%s", ++metric_str); } else { - snprintf(xpath_value, sizeof(xpath_value), "%s/value", xpath); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/value", xpath); snprintf(value, sizeof(value), "%s", metric_str); } nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value); @@ -777,7 +933,7 @@ DEFPY_YANG( "Metric value for destination routing protocol\n" "Metric value\n") { - const char *xpath = "./set-action[action='metric']"; + const char *xpath = "./set-action[action='frr-route-map:set-metric']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); return nb_cli_apply_changes(vty, NULL); @@ -790,11 +946,12 @@ DEFPY_YANG( "Tag value for routing protocol\n" "Tag value\n") { - const char *xpath = "./set-action[action='tag']"; + const char *xpath = "./set-action[action='frr-route-map:set-tag']"; char xpath_value[XPATH_MAXLEN]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), "%s/tag", xpath); + snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/tag", + xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str); return nb_cli_apply_changes(vty, NULL); @@ -808,58 +965,289 @@ DEFPY_YANG( "Tag value for routing protocol\n" "Tag value\n") { - const char *xpath = "./set-action[action='tag']"; + const char *xpath = "./set-action[action='frr-route-map:set-tag']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); return nb_cli_apply_changes(vty, NULL); } +DEFUN_YANG (set_srte_color, + set_srte_color_cmd, + "set sr-te color (1-4294967295)", + SET_STR + SRTE_STR + SRTE_COLOR_STR + "Color of the SR-TE Policies to match with\n") +{ + const char *xpath = + "./set-action[action='frr-route-map:set-sr-te-color']"; + char xpath_value[XPATH_MAXLEN]; + int idx = 0; + + char *arg = argv_find(argv, argc, "(1-4294967295)", &idx) + ? argv[idx]->arg + : NULL; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/policy", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, arg); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG (no_set_srte_color, + no_set_srte_color_cmd, + "no set sr-te color [(1-4294967295)]", + NO_STR + SET_STR + SRTE_STR + SRTE_COLOR_STR + "Color of the SR-TE Policies to match with\n") +{ + const char *xpath = + "./set-action[action='frr-route-map:set-sr-te-color']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + + void route_map_action_show(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - int action = yang_dnode_get_enum(dnode, "./action"); + const char *action = yang_dnode_get_string(dnode, "./action"); + struct lyd_node *ln; + const char *acl; - switch (action) { - case 0: /* ipv4-next-hop */ + if (IS_SET_IPv4_NH(action)) { vty_out(vty, " set ip next-hop %s\n", - yang_dnode_get_string(dnode, "./ipv4-address")); - break; - case 1: /* ipv6-next-hop */ + yang_dnode_get_string( + dnode, "./rmap-set-action/ipv4-address")); + } else if (IS_SET_IPv6_NH(action)) { vty_out(vty, " set ipv6 next-hop local %s\n", - yang_dnode_get_string(dnode, "./ipv6-address")); - break; - case 2: /* metric */ - if (yang_dnode_get(dnode, "./use-round-trip-time")) { + yang_dnode_get_string( + dnode, "./rmap-set-action/ipv6-address")); + } else if (IS_SET_METRIC(action)) { + if (yang_dnode_get(dnode, + "./rmap-set-action/use-round-trip-time")) { vty_out(vty, " set metric rtt\n"); - } else if (yang_dnode_get(dnode, "./add-round-trip-time")) { + } else if (yang_dnode_get( + dnode, + "./rmap-set-action/add-round-trip-time")) { vty_out(vty, " set metric +rtt\n"); - } else if (yang_dnode_get(dnode, "./subtract-round-trip-time")) { + } else if ( + yang_dnode_get( + dnode, + "./rmap-set-action/subtract-round-trip-time")) { vty_out(vty, " set metric -rtt\n"); - } else if (yang_dnode_get(dnode, "./add-metric")) { + } else if (yang_dnode_get(dnode, + "./rmap-set-action/add-metric")) { vty_out(vty, " set metric +%s\n", - yang_dnode_get_string(dnode, "./add-metric")); - } else if (yang_dnode_get(dnode, "./subtract-metric")) { + yang_dnode_get_string( + dnode, "./rmap-set-action/add-metric")); + } else if (yang_dnode_get( + dnode, + "./rmap-set-action/subtract-metric")) { vty_out(vty, " set metric -%s\n", - yang_dnode_get_string(dnode, - "./subtract-metric")); + yang_dnode_get_string( + dnode, + "./rmap-set-action/subtract-metric")); } else { vty_out(vty, " set metric %s\n", - yang_dnode_get_string(dnode, "./value")); + yang_dnode_get_string( + dnode, "./rmap-set-action/value")); } - break; - case 3: /* tag */ + } else if (IS_SET_TAG(action)) { vty_out(vty, " set tag %s\n", - yang_dnode_get_string(dnode, "./tag")); - break; - case 100: /* source */ - if (yang_dnode_exists(dnode, "./frr-zebra:source-v4")) + yang_dnode_get_string(dnode, "./rmap-set-action/tag")); + } else if (IS_SET_SR_TE_COLOR(action)) { + vty_out(vty, " set sr-te color %s\n", + yang_dnode_get_string(dnode, + "./rmap-set-action/policy")); + } else if (IS_SET_SRC(action)) { + if (yang_dnode_exists( + dnode, + "./rmap-set-action/frr-zebra-route-map:ipv4-src-address")) vty_out(vty, " set src %s\n", - yang_dnode_get_string(dnode, "./frr-zebra:source-v4")); + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-zebra-route-map:ipv4-src-address")); else vty_out(vty, " set src %s\n", - yang_dnode_get_string(dnode, "./frr-zebra:source-v6")); - break; + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-zebra-route-map:ipv6-src-address")); + } else if (IS_SET_METRIC_TYPE(action)) { + vty_out(vty, " set metric-type %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-ospf-route-map:metric-type")); + } else if (IS_SET_FORWARDING_ADDR(action)) { + vty_out(vty, " set forwarding-address %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-ospf6-route-map:ipv6-address")); + } else if (IS_SET_WEIGHT(action)) { + vty_out(vty, " set weight %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:weight")); + } else if (IS_SET_TABLE(action)) { + vty_out(vty, " set table %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:table")); + } else if (IS_SET_LOCAL_PREF(action)) { + vty_out(vty, " set local-preference %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:local-pref")); + } else if (IS_SET_LABEL_INDEX(action)) { + vty_out(vty, " set label-index %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:label-index")); + } else if (IS_SET_DISTANCE(action)) { + vty_out(vty, " set distance %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:distance")); + } else if (IS_SET_ORIGIN(action)) { + vty_out(vty, " set origin %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:origin")); + } else if (IS_SET_ATOMIC_AGGREGATE(action)) { + vty_out(vty, " set atomic-aggregate\n"); + } else if (IS_SET_ORIGINATOR_ID(action)) { + vty_out(vty, " set originator-id %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:originator-id")); + } else if (IS_SET_COMM_LIST_DEL(action)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-set-action/frr-bgp-route-map:comm-list-name")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + + assert(acl); + + vty_out(vty, " set comm-list %s delete\n", acl); + } else if (IS_SET_LCOMM_LIST_DEL(action)) { + acl = NULL; + if ((ln = yang_dnode_get( + dnode, + "./rmap-set-action/frr-bgp-route-map:comm-list-name")) + != NULL) + acl = yang_dnode_get_string(ln, NULL); + + assert(acl); + + vty_out(vty, " set large-comm-list %s delete\n", acl); + } else if (IS_SET_LCOMMUNITY(action)) { + if (yang_dnode_exists( + dnode, + "./rmap-set-action/frr-bgp-route-map:large-community-string")) + vty_out(vty, " set large-community %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:large-community-string")); + else { + if (true + == yang_dnode_get_bool( + dnode, + "./rmap-set-action/frr-bgp-route-map:large-community-none")) + vty_out(vty, " set large-community none\n"); + } + } else if (IS_SET_COMMUNITY(action)) { + if (yang_dnode_exists( + dnode, + "./rmap-set-action/frr-bgp-route-map:community-string")) + vty_out(vty, " set community %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:community-string")); + else { + if (true + == yang_dnode_get_bool( + dnode, + "./rmap-set-action/frr-bgp-route-map:community-none")) + vty_out(vty, " set community none\n"); + } + } else if (IS_SET_EXTCOMMUNITY_RT(action)) { + vty_out(vty, " set extcommunity rt %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:extcommunity-rt")); + } else if (IS_SET_EXTCOMMUNITY_SOO(action)) { + vty_out(vty, " set extcommunity soo %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:extcommunity-soo")); + } else if (IS_SET_AGGREGATOR(action)) { + vty_out(vty, " set aggregator as %s %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn"), + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address")); + } else if (IS_SET_AS_EXCLUDE(action)) { + vty_out(vty, " set as-path exclude %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:exclude-as-path")); + } else if (IS_SET_AS_PREPEND(action)) { + if (yang_dnode_exists( + dnode, + "./rmap-set-action/frr-bgp-route-map:prepend-as-path")) + vty_out(vty, " set as-path prepend %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:prepend-as-path")); + else { + vty_out(vty, " set as-path prepend last-as %u\n", + yang_dnode_get_uint8( + dnode, + "./rmap-set-action/frr-bgp-route-map:last-as")); + } + } else if (IS_SET_IPV6_NH_GLOBAL(action)) { + vty_out(vty, " set ipv6 next-hop global %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:ipv6-address")); + } else if (IS_SET_IPV6_VPN_NH(action)) { + vty_out(vty, " set ipv6 vpn next-hop %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:ipv6-address")); + } else if (IS_SET_IPV6_PEER_ADDR(action)) { + if (true + == yang_dnode_get_bool( + dnode, + "./rmap-set-action/frr-bgp-route-map:preference")) + vty_out(vty, " set ipv6 next-hop peer-address\n"); + } else if (IS_SET_IPV6_PREFER_GLOBAL(action)) { + if (true + == yang_dnode_get_bool( + dnode, + "./rmap-set-action/frr-bgp-route-map:preference")) + vty_out(vty, " set ipv6 next-hop prefer-global\n"); + } else if (IS_SET_IPV4_VPN_NH(action)) { + vty_out(vty, " set ipv4 vpn next-hop %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:ipv4-address")); + } else if (IS_SET_BGP_IPV4_NH(action)) { + vty_out(vty, " set ip next-hop %s\n", + yang_dnode_get_string( + dnode, + "./rmap-set-action/frr-bgp-route-map:ipv4-nexthop")); } } @@ -1122,4 +1510,7 @@ void route_map_cli_init(void) install_element(RMAP_NODE, &set_tag_cmd); install_element(RMAP_NODE, &no_set_tag_cmd); + + install_element(RMAP_NODE, &set_srte_color_cmd); + install_element(RMAP_NODE, &no_set_srte_color_cmd); } diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c index 8546284c3e..410eb51f5e 100644 --- a/lib/routemap_northbound.c +++ b/lib/routemap_northbound.c @@ -45,8 +45,9 @@ int lib_route_map_entry_match_destroy(struct nb_cb_destroy_args *args) if (rhc->rhc_mhook == NULL) return NB_OK; - rv = rhc->rhc_mhook(NULL, rhc->rhc_rmi, rhc->rhc_rule, NULL, - rhc->rhc_event); + rv = rhc->rhc_mhook(rhc->rhc_rmi, rhc->rhc_rule, NULL, + rhc->rhc_event, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) return NB_ERR_INCONSISTENCY; @@ -65,7 +66,8 @@ int lib_route_map_entry_set_destroy(struct nb_cb_destroy_args *args) if (rhc->rhc_shook == NULL) return NB_OK; - rv = rhc->rhc_shook(NULL, rhc->rhc_rmi, rhc->rhc_rule, NULL); + rv = rhc->rhc_shook(rhc->rhc_rmi, rhc->rhc_rule, NULL, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) return NB_ERR_INCONSISTENCY; @@ -498,9 +500,10 @@ static int lib_route_map_entry_match_condition_interface_modify( rhc->rhc_rule = "interface"; rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - rv = rmap_match_set_hook.match_interface(NULL, rhc->rhc_rmi, + rv = rmap_match_set_hook.match_interface(rhc->rhc_rmi, "interface", ifname, - RMAP_EVENT_MATCH_ADDED); + RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_mhook = NULL; return NB_ERR_INCONSISTENCY; @@ -523,7 +526,7 @@ static int lib_route_map_entry_match_condition_list_name_modify( { struct routemap_hook_context *rhc; const char *acl; - int condition; + const char *condition; int rv; if (args->event != NB_EV_APPLY) @@ -532,19 +535,19 @@ static int lib_route_map_entry_match_condition_list_name_modify( /* Check for hook installation, otherwise we can just stop. */ acl = yang_dnode_get_string(args->dnode, NULL); rhc = nb_running_get_entry(args->dnode, NULL, true); - condition = yang_dnode_get_enum(args->dnode, "../condition"); - switch (condition) { - case 1: /* ipv4-address-list */ + condition = yang_dnode_get_string(args->dnode, "../../condition"); + + if (IS_MATCH_IPv4_ADDRESS_LIST(condition)) { if (rmap_match_set_hook.match_ip_address == NULL) return NB_OK; rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_address; rhc->rhc_rule = "ip address"; rhc->rhc_event = RMAP_EVENT_FILTER_DELETED; rv = rmap_match_set_hook.match_ip_address( - NULL, rhc->rhc_rmi, "ip address", acl, - RMAP_EVENT_FILTER_ADDED); - break; - case 2: /* ipv4-prefix-list */ + rhc->rhc_rmi, "ip address", acl, + RMAP_EVENT_FILTER_ADDED, + args->errmsg, args->errmsg_len); + } else if (IS_MATCH_IPv4_PREFIX_LIST(condition)) { if (rmap_match_set_hook.match_ip_address_prefix_list == NULL) return NB_OK; rhc->rhc_mhook = @@ -552,20 +555,20 @@ static int lib_route_map_entry_match_condition_list_name_modify( rhc->rhc_rule = "ip address prefix-list"; rhc->rhc_event = RMAP_EVENT_PLIST_DELETED; rv = rmap_match_set_hook.match_ip_address_prefix_list( - NULL, rhc->rhc_rmi, "ip address prefix-list", acl, - RMAP_EVENT_PLIST_ADDED); - break; - case 3: /* ipv4-next-hop-list */ + rhc->rhc_rmi, "ip address prefix-list", acl, + RMAP_EVENT_PLIST_ADDED, + args->errmsg, args->errmsg_len); + } else if (IS_MATCH_IPv4_NEXTHOP_LIST(condition)) { if (rmap_match_set_hook.match_ip_next_hop == NULL) return NB_OK; rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop; rhc->rhc_rule = "ip next-hop"; rhc->rhc_event = RMAP_EVENT_FILTER_DELETED; rv = rmap_match_set_hook.match_ip_next_hop( - NULL, rhc->rhc_rmi, "ip next-hop", acl, - RMAP_EVENT_FILTER_ADDED); - break; - case 4: /* ipv4-next-hop-prefix-list */ + rhc->rhc_rmi, "ip next-hop", acl, + RMAP_EVENT_FILTER_ADDED, + args->errmsg, args->errmsg_len); + } else if (IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(condition)) { if (rmap_match_set_hook.match_ip_next_hop_prefix_list == NULL) return NB_OK; rhc->rhc_mhook = @@ -573,20 +576,20 @@ static int lib_route_map_entry_match_condition_list_name_modify( rhc->rhc_rule = "ip next-hop prefix-list"; rhc->rhc_event = RMAP_EVENT_PLIST_DELETED; rv = rmap_match_set_hook.match_ip_next_hop_prefix_list( - NULL, rhc->rhc_rmi, "ip next-hop prefix-list", acl, - RMAP_EVENT_PLIST_ADDED); - break; - case 6: /* ipv6-address-list */ + rhc->rhc_rmi, "ip next-hop prefix-list", acl, + RMAP_EVENT_PLIST_ADDED, + args->errmsg, args->errmsg_len); + } else if (IS_MATCH_IPv6_ADDRESS_LIST(condition)) { if (rmap_match_set_hook.match_ipv6_address == NULL) return NB_OK; rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_address; rhc->rhc_rule = "ipv6 address"; rhc->rhc_event = RMAP_EVENT_FILTER_DELETED; rv = rmap_match_set_hook.match_ipv6_address( - NULL, rhc->rhc_rmi, "ipv6 address", acl, - RMAP_EVENT_FILTER_ADDED); - break; - case 7: /* ipv6-prefix-list */ + rhc->rhc_rmi, "ipv6 address", acl, + RMAP_EVENT_FILTER_ADDED, + args->errmsg, args->errmsg_len); + } else if (IS_MATCH_IPv6_PREFIX_LIST(condition)) { if (rmap_match_set_hook.match_ipv6_address_prefix_list == NULL) return NB_OK; rhc->rhc_mhook = @@ -594,13 +597,12 @@ static int lib_route_map_entry_match_condition_list_name_modify( rhc->rhc_rule = "ipv6 address prefix-list"; rhc->rhc_event = RMAP_EVENT_PLIST_DELETED; rv = rmap_match_set_hook.match_ipv6_address_prefix_list( - NULL, rhc->rhc_rmi, "ipv6 address prefix-list", acl, - RMAP_EVENT_PLIST_ADDED); - break; - default: + rhc->rhc_rmi, "ipv6 address prefix-list", acl, + RMAP_EVENT_PLIST_ADDED, + args->errmsg, args->errmsg_len); + } else rv = CMD_ERR_NO_MATCH; - break; - } + if (rv != CMD_SUCCESS) { rhc->rhc_mhook = NULL; return NB_ERR_INCONSISTENCY; @@ -642,8 +644,9 @@ static int lib_route_map_entry_match_condition_ipv4_next_hop_type_modify( rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; rv = rmap_match_set_hook.match_ip_next_hop_type( - NULL, rhc->rhc_rmi, "ip next-hop type", type, - RMAP_EVENT_MATCH_ADDED); + rhc->rhc_rmi, "ip next-hop type", type, + RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_mhook = NULL; return NB_ERR_INCONSISTENCY; @@ -685,8 +688,9 @@ static int lib_route_map_entry_match_condition_ipv6_next_hop_type_modify( rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; rv = rmap_match_set_hook.match_ipv6_next_hop_type( - NULL, rhc->rhc_rmi, "ipv6 next-hop type", type, - RMAP_EVENT_MATCH_ADDED); + rhc->rhc_rmi, "ipv6 next-hop type", type, + RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_mhook = NULL; return NB_ERR_INCONSISTENCY; @@ -727,8 +731,9 @@ static int lib_route_map_entry_match_condition_metric_modify( rhc->rhc_rule = "metric"; rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - rv = rmap_match_set_hook.match_metric(NULL, rhc->rhc_rmi, "metric", - type, RMAP_EVENT_MATCH_ADDED); + rv = rmap_match_set_hook.match_metric(rhc->rhc_rmi, "metric", + type, RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_mhook = NULL; return NB_ERR_INCONSISTENCY; @@ -769,8 +774,9 @@ lib_route_map_entry_match_condition_tag_modify(struct nb_cb_modify_args *args) rhc->rhc_rule = "tag"; rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - rv = rmap_match_set_hook.match_tag(NULL, rhc->rhc_rmi, "tag", tag, - RMAP_EVENT_MATCH_ADDED); + rv = rmap_match_set_hook.match_tag(rhc->rhc_rmi, "tag", tag, + RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_mhook = NULL; return NB_ERR_INCONSISTENCY; @@ -850,8 +856,9 @@ static int lib_route_map_entry_set_action_ipv4_address_modify( rhc->rhc_shook = rmap_match_set_hook.no_set_ip_nexthop; rhc->rhc_rule = "ip next-hop"; - rv = rmap_match_set_hook.set_ip_nexthop(NULL, rhc->rhc_rmi, - "ip next-hop", address); + rv = rmap_match_set_hook.set_ip_nexthop(rhc->rhc_rmi, "ip next-hop", + address, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_shook = NULL; return NB_ERR_INCONSISTENCY; @@ -909,7 +916,8 @@ static int lib_route_map_entry_set_action_ipv6_address_modify( rhc->rhc_rule = "ipv6 next-hop local"; rv = rmap_match_set_hook.set_ipv6_nexthop_local( - NULL, rhc->rhc_rmi, "ipv6 next-hop local", address); + rhc->rhc_rmi, "ipv6 next-hop local", address, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_shook = NULL; return NB_ERR_INCONSISTENCY; @@ -928,7 +936,8 @@ static int lib_route_map_entry_set_action_ipv6_address_destroy( * XPath: /frr-route-map:lib/route-map/entry/set-action/value */ static int set_action_modify(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource, const char *value) + union nb_resource *resource, const char *value, + char *errmsg, size_t errmsg_len) { struct routemap_hook_context *rhc; int rv; @@ -952,8 +961,10 @@ static int set_action_modify(enum nb_event event, const struct lyd_node *dnode, rhc->rhc_shook = rmap_match_set_hook.no_set_metric; rhc->rhc_rule = "metric"; - rv = rmap_match_set_hook.set_metric(NULL, rhc->rhc_rmi, "metric", - value); + rv = rmap_match_set_hook.set_metric(rhc->rhc_rmi, "metric", + value, + errmsg, errmsg_len + ); if (rv != CMD_SUCCESS) { rhc->rhc_shook = NULL; return NB_ERR_INCONSISTENCY; @@ -968,7 +979,7 @@ lib_route_map_entry_set_action_value_modify(struct nb_cb_modify_args *args) const char *metric = yang_dnode_get_string(args->dnode, NULL); return set_action_modify(args->event, args->dnode, args->resource, - metric); + metric, args->errmsg, args->errmsg_len); } static int @@ -995,7 +1006,8 @@ lib_route_map_entry_set_action_add_metric_modify(struct nb_cb_modify_args *args) snprintf(metric_str, sizeof(metric_str), "+%s", yang_dnode_get_string(args->dnode, NULL)); return set_action_modify(args->event, args->dnode, args->resource, - metric_str); + metric_str, + args->errmsg, args->errmsg_len); } static int lib_route_map_entry_set_action_add_metric_destroy( @@ -1022,7 +1034,8 @@ static int lib_route_map_entry_set_action_subtract_metric_modify( snprintf(metric_str, sizeof(metric_str), "-%s", yang_dnode_get_string(args->dnode, NULL)); return set_action_modify(args->event, args->dnode, args->resource, - metric_str); + metric_str, + args->errmsg, args->errmsg_len); } static int lib_route_map_entry_set_action_subtract_metric_destroy( @@ -1038,7 +1051,8 @@ static int lib_route_map_entry_set_action_use_round_trip_time_modify( struct nb_cb_modify_args *args) { return set_action_modify(args->event, args->dnode, args->resource, - "rtt"); + "rtt", + args->errmsg, args->errmsg_len); } static int lib_route_map_entry_set_action_use_round_trip_time_destroy( @@ -1054,7 +1068,8 @@ static int lib_route_map_entry_set_action_add_round_trip_time_modify( struct nb_cb_modify_args *args) { return set_action_modify(args->event, args->dnode, args->resource, - "+rtt"); + "+rtt", + args->errmsg, args->errmsg_len); } static int lib_route_map_entry_set_action_add_round_trip_time_destroy( @@ -1070,7 +1085,7 @@ static int lib_route_map_entry_set_action_subtract_round_trip_time_modify( struct nb_cb_modify_args *args) { return set_action_modify(args->event, args->dnode, args->resource, - "-rtt"); + "-rtt", args->errmsg, args->errmsg_len); } static int lib_route_map_entry_set_action_subtract_round_trip_time_destroy( @@ -1109,7 +1124,8 @@ lib_route_map_entry_set_action_tag_modify(struct nb_cb_modify_args *args) rhc->rhc_shook = rmap_match_set_hook.no_set_tag; rhc->rhc_rule = "tag"; - rv = rmap_match_set_hook.set_tag(NULL, rhc->rhc_rmi, "tag", tag); + rv = rmap_match_set_hook.set_tag(rhc->rhc_rmi, "tag", tag, + args->errmsg, args->errmsg_len); if (rv != CMD_SUCCESS) { rhc->rhc_shook = NULL; return NB_ERR_INCONSISTENCY; @@ -1124,6 +1140,52 @@ lib_route_map_entry_set_action_tag_destroy(struct nb_cb_destroy_args *args) return lib_route_map_entry_set_destroy(args); } +/* + * XPath: /frr-route-map:lib/route-map/entry/set-action/policy + */ +static int +lib_route_map_entry_set_action_policy_modify(struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *policy; + int rv; + + /* + * NOTE: validate if 'action' is 'tag', currently it is not + * necessary because this is the only implemented action. Other + * actions might have different validations. + */ + if (args->event != NB_EV_APPLY) + return NB_OK; + + /* Check for hook function. */ + if (rmap_match_set_hook.set_srte_color == NULL) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + policy = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_shook = rmap_match_set_hook.no_set_tag; + rhc->rhc_rule = "sr-te color"; + + rv = rmap_match_set_hook.set_tag(rhc->rhc_rmi, "sr-te color", policy, + args->errmsg, args->errmsg_len); + if (rv != CMD_SUCCESS) { + rhc->rhc_shook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int +lib_route_map_entry_set_action_policy_destroy(struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_set_destroy(args); +} + /* clang-format off */ const struct frr_yang_module_info frr_route_map_info = { .name = "frr-route-map", @@ -1190,42 +1252,42 @@ const struct frr_yang_module_info frr_route_map_info = { } }, { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/interface", + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/interface", .cbs = { .modify = lib_route_map_entry_match_condition_interface_modify, .destroy = lib_route_map_entry_match_condition_interface_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/list-name", + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/list-name", .cbs = { .modify = lib_route_map_entry_match_condition_list_name_modify, .destroy = lib_route_map_entry_match_condition_list_name_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/ipv4-next-hop-type", + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/ipv4-next-hop-type", .cbs = { .modify = lib_route_map_entry_match_condition_ipv4_next_hop_type_modify, .destroy = lib_route_map_entry_match_condition_ipv4_next_hop_type_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/ipv6-next-hop-type", + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/ipv6-next-hop-type", .cbs = { .modify = lib_route_map_entry_match_condition_ipv6_next_hop_type_modify, .destroy = lib_route_map_entry_match_condition_ipv6_next_hop_type_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/metric", + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/metric", .cbs = { .modify = lib_route_map_entry_match_condition_metric_modify, .destroy = lib_route_map_entry_match_condition_metric_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/tag", + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/tag", .cbs = { .modify = lib_route_map_entry_match_condition_tag_modify, .destroy = lib_route_map_entry_match_condition_tag_destroy, @@ -1240,68 +1302,76 @@ const struct frr_yang_module_info frr_route_map_info = { } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/ipv4-address", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/ipv4-address", .cbs = { .modify = lib_route_map_entry_set_action_ipv4_address_modify, .destroy = lib_route_map_entry_set_action_ipv4_address_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/ipv6-address", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/ipv6-address", .cbs = { .modify = lib_route_map_entry_set_action_ipv6_address_modify, .destroy = lib_route_map_entry_set_action_ipv6_address_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/value", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/value", .cbs = { .modify = lib_route_map_entry_set_action_value_modify, .destroy = lib_route_map_entry_set_action_value_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/add-metric", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-metric", .cbs = { .modify = lib_route_map_entry_set_action_add_metric_modify, .destroy = lib_route_map_entry_set_action_add_metric_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/subtract-metric", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/subtract-metric", .cbs = { .modify = lib_route_map_entry_set_action_subtract_metric_modify, .destroy = lib_route_map_entry_set_action_subtract_metric_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/use-round-trip-time", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/use-round-trip-time", .cbs = { .modify = lib_route_map_entry_set_action_use_round_trip_time_modify, .destroy = lib_route_map_entry_set_action_use_round_trip_time_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/add-round-trip-time", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-round-trip-time", .cbs = { .modify = lib_route_map_entry_set_action_add_round_trip_time_modify, .destroy = lib_route_map_entry_set_action_add_round_trip_time_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/subtract-round-trip-time", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/subtract-round-trip-time", .cbs = { .modify = lib_route_map_entry_set_action_subtract_round_trip_time_modify, .destroy = lib_route_map_entry_set_action_subtract_round_trip_time_destroy, } }, { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/tag", + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/tag", .cbs = { .modify = lib_route_map_entry_set_action_tag_modify, .destroy = lib_route_map_entry_set_action_tag_destroy, } }, + { + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/policy", + .cbs = { + .modify = lib_route_map_entry_set_action_policy_modify, + .destroy = lib_route_map_entry_set_action_policy_destroy, + } + }, + { .xpath = NULL, },