From: Sebastien Merle Date: Fri, 14 Feb 2020 14:49:25 +0000 (+0000) Subject: staticd: add support for SR Policies X-Git-Tag: base_7.5~87^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=065276ae1f437c54b33ebcc2201bf105bae39dda;p=matthieu%2Ffrr.git staticd: add support for SR Policies Configuration example: ip route 9.9.9.9/32 6.6.6.6 color 123 The SR Policy to be chosen is uniquely identified by the policy endpoint (6.6.6.6) and the SR-TE color (123). Traffic will be augmented with an MPLS label stack according to the active candidate path of that particular policy. Co-authored-by: GalaxyGorilla Signed-off-by: Sebastien Merle --- diff --git a/doc/user/static.rst b/doc/user/static.rst index 09bdc9cbea..6302d1b148 100644 --- a/doc/user/static.rst +++ b/doc/user/static.rst @@ -128,3 +128,15 @@ but this time, the route command will apply to the VRF. ip route 10.0.0.0/24 10.0.0.2 exit-vrf + +SR-TE Route Commands +==================== + +It is possible to specify a route using a SR-TE policy configured in Zebra. + +e.g. to use the SR-TE policy with endpoint 6.6.6.6 and color 123 to reach the +network 9.9.9.9/24: + +.. code-block:: frr + + ip route 9.9.9.9/24 6.6.6.6 color 123 diff --git a/staticd/static_nb.c b/staticd/static_nb.c index 419a6a5366..51704426f0 100644 --- a/staticd/static_nb.c +++ b/staticd/static_nb.c @@ -75,6 +75,13 @@ const struct frr_yang_module_info frr_staticd_info = { .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy, } }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srte-color", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify, + .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy, + } + }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry", .cbs = { @@ -153,6 +160,13 @@ const struct frr_yang_module_info frr_staticd_info = { .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy, } }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify, + .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy, + } + }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry", .cbs = { diff --git a/staticd/static_nb.h b/staticd/static_nb.h index e46c156265..d145c31f77 100644 --- a/staticd/static_nb.h +++ b/staticd/static_nb.h @@ -45,6 +45,10 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy( struct nb_cb_destroy_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy( + struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create( struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy( @@ -85,6 +89,10 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy( struct nb_cb_destroy_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy( + struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create( struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy( @@ -140,6 +148,8 @@ int routing_control_plane_protocols_name_validate( #define FRR_STATIC_ROUTE_NH_ONLINK_XPATH "/onlink" +#define FRR_STATIC_ROUTE_NH_COLOR_XPATH "/srte-color" + #define FRR_STATIC_ROUTE_NH_BH_XPATH "/bh-type" #define FRR_STATIC_ROUTE_NH_LABEL_XPATH "/mpls-label-stack" diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c index 40c4d85fb6..e89832069c 100644 --- a/staticd/static_nb_config.c +++ b/staticd/static_nb_config.c @@ -162,7 +162,7 @@ static bool static_nexthop_create(struct nb_cb_create_args *args, yang_dnode_get_string(args->dnode, "./gateway")); nh = static_add_nexthop(rn, pn, info->safi, info->svrf, nh_type, - &ipaddr, ifname, nh_vrf); + &ipaddr, ifname, nh_vrf, 0); if (!nh) { char buf[SRCDEST2STR_BUFFER]; @@ -302,6 +302,26 @@ static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args) return NB_OK; } +static int static_nexthop_color_modify(struct nb_cb_modify_args *args) +{ + struct static_nexthop *nh; + + nh = nb_running_get_entry(args->dnode, NULL, true); + nh->color = yang_dnode_get_uint32(args->dnode, NULL); + + return NB_OK; +} + +static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args) +{ + struct static_nexthop *nh; + + nh = nb_running_unset_entry(args->dnode); + nh->color = 0; + + return NB_OK; +} + static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args) { struct static_nexthop *nh; @@ -705,6 +725,44 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa } return NB_OK; } + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srte-color + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (static_nexthop_color_modify(args) != NB_OK) + return NB_ERR; + + break; + } + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (static_nexthop_color_destroy(args) != NB_OK) + return NB_ERR; + break; + } + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry @@ -1122,6 +1180,44 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr return NB_OK; } +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (static_nexthop_color_modify(args) != NB_OK) + return NB_ERR; + + break; + } + return NB_OK; +} + + +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (static_nexthop_color_destroy(args) != NB_OK) + return NB_ERR; + break; + } + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry diff --git a/staticd/static_routes.c b/staticd/static_routes.c index 3836109e36..d9f2faabaf 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -200,7 +200,7 @@ struct static_nexthop * static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi, struct static_vrf *svrf, static_types type, struct ipaddr *ipaddr, const char *ifname, - const char *nh_vrf) + const char *nh_vrf, uint32_t color) { struct static_nexthop *nh; struct static_vrf *nh_svrf; @@ -218,6 +218,7 @@ static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi, nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop)); nh->type = type; + nh->color = color; nh->nh_vrf_id = nh_svrf->vrf->vrf_id; strlcpy(nh->nh_vrfname, nh_svrf->vrf->name, sizeof(nh->nh_vrfname)); diff --git a/staticd/static_routes.h b/staticd/static_routes.h index 89ef544023..e5c10d18a4 100644 --- a/staticd/static_routes.h +++ b/staticd/static_routes.h @@ -132,6 +132,9 @@ struct static_nexthop { * are specified. */ bool onlink; + + /* SR-TE color */ + uint32_t color; }; DECLARE_DLIST(static_nexthop_list, struct static_nexthop, list); @@ -156,7 +159,7 @@ extern struct static_nexthop * static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi, struct static_vrf *svrf, static_types type, struct ipaddr *ipaddr, const char *ifname, - const char *nh_vrf); + const char *nh_vrf, uint32_t color); extern void static_install_nexthop(struct route_node *rn, struct static_path *pn, struct static_nexthop *nh, safi_t safi, diff --git a/staticd/static_vty.c b/staticd/static_vty.c index ac18f6adf4..ba1a8f9a25 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -51,7 +51,8 @@ static int static_route_leak(struct vty *vty, const char *svrf, const char *gate_str, const char *ifname, const char *flag_str, const char *tag_str, const char *distance_str, const char *label_str, - const char *table_str, bool onlink) + const char *table_str, bool onlink, + const char *color_str) { int ret; struct prefix p, src; @@ -249,6 +250,16 @@ static int static_route_leak(struct vty *vty, const char *svrf, nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, "false"); } + if (type == STATIC_IPV4_GATEWAY + || type == STATIC_IPV6_GATEWAY + || type == STATIC_IPV4_GATEWAY_IFNAME + || type == STATIC_IPV6_GATEWAY_IFNAME) { + strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath)); + strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_COLOR_XPATH, + sizeof(ab_xpath)); + nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, + color_str); + } if (label_str) { /* copy of label string (start) */ char *ostr; @@ -330,7 +341,7 @@ static int static_route(struct vty *vty, afi_t afi, safi_t safi, return static_route_leak(vty, vrf_name, vrf_name, afi, safi, negate, dest_str, mask_str, src_str, gate_str, ifname, flag_str, tag_str, distance_str, label_str, - table_str, false); + table_str, false, NULL); } /* Write static route configuration. */ @@ -441,6 +452,12 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi, if (nh->onlink) vty_out(vty, " onlink"); + /* + * SR-TE color + */ + if (nh->color != 0) + vty_out(vty, " color %u", nh->color); + vty_out(vty, "\n"); write = 1; @@ -550,7 +567,7 @@ DEFPY_YANG(ip_route_blackhole_vrf, return static_route_leak(vty, vrfname, vrfname, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, NULL, NULL, flag, tag_str, distance_str, label, table_str, - false); + false, NULL); } DEFPY_YANG(ip_route_address_interface, @@ -567,6 +584,7 @@ DEFPY_YANG(ip_route_address_interface, |table (1-4294967295) \ |nexthop-vrf NAME \ |onlink$onlink \ + |color (1-4294967295) \ }]", NO_STR IP_STR "Establish static routes\n" @@ -584,7 +602,9 @@ DEFPY_YANG(ip_route_address_interface, "Table to configure\n" "The table number to configure\n" VRF_CMD_HELP_STR - "Treat the nexthop as directly attached to the interface\n") + "Treat the nexthop as directly attached to the interface\n" + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -604,7 +624,7 @@ DEFPY_YANG(ip_route_address_interface, return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, gate_str, ifname, flag, tag_str, distance_str, label, table_str, - !!onlink); + !!onlink, color_str); } DEFPY_YANG(ip_route_address_interface_vrf, @@ -620,7 +640,8 @@ DEFPY_YANG(ip_route_address_interface_vrf, |table (1-4294967295) \ |nexthop-vrf NAME \ |onlink$onlink \ - }]", + |color (1-4294967295) \ + }]", NO_STR IP_STR "Establish static routes\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" @@ -636,7 +657,9 @@ DEFPY_YANG(ip_route_address_interface_vrf, "Table to configure\n" "The table number to configure\n" VRF_CMD_HELP_STR - "Treat the nexthop as directly attached to the interface\n") + "Treat the nexthop as directly attached to the interface\n" + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -663,7 +686,7 @@ DEFPY_YANG(ip_route_address_interface_vrf, return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, gate_str, ifname, flag, tag_str, distance_str, label, table_str, - !!onlink); + !!onlink, color_str); } DEFPY_YANG(ip_route, @@ -678,6 +701,7 @@ DEFPY_YANG(ip_route, |label WORD \ |table (1-4294967295) \ |nexthop-vrf NAME \ + |color (1-4294967295) \ }]", NO_STR IP_STR "Establish static routes\n" @@ -694,7 +718,9 @@ DEFPY_YANG(ip_route, MPLS_LABEL_HELPSTR "Table to configure\n" "The table number to configure\n" - VRF_CMD_HELP_STR) + VRF_CMD_HELP_STR + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -715,7 +741,7 @@ DEFPY_YANG(ip_route, return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, gate_str, ifname, flag, tag_str, distance_str, label, table_str, - false); + false, color_str); } DEFPY_YANG(ip_route_vrf, @@ -729,6 +755,7 @@ DEFPY_YANG(ip_route_vrf, |label WORD \ |table (1-4294967295) \ |nexthop-vrf NAME \ + |color (1-4294967295) \ }]", NO_STR IP_STR "Establish static routes\n" @@ -744,7 +771,9 @@ DEFPY_YANG(ip_route_vrf, MPLS_LABEL_HELPSTR "Table to configure\n" "The table number to configure\n" - VRF_CMD_HELP_STR) + VRF_CMD_HELP_STR + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -772,7 +801,7 @@ DEFPY_YANG(ip_route_vrf, return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, gate_str, ifname, flag, tag_str, distance_str, label, table_str, - false); + false, color_str); } DEFPY_YANG(ipv6_route_blackhole, @@ -859,7 +888,7 @@ DEFPY_YANG(ipv6_route_blackhole_vrf, return static_route_leak(vty, vrfname, vrfname, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, NULL, NULL, flag, tag_str, distance_str, label, table_str, - false); + false, NULL); } DEFPY_YANG(ipv6_route_address_interface, @@ -875,6 +904,7 @@ DEFPY_YANG(ipv6_route_address_interface, |table (1-4294967295) \ |nexthop-vrf NAME \ |onlink$onlink \ + |color (1-4294967295) \ }]", NO_STR IPV6_STR @@ -893,7 +923,9 @@ DEFPY_YANG(ipv6_route_address_interface, "Table to configure\n" "The table number to configure\n" VRF_CMD_HELP_STR - "Treat the nexthop as directly attached to the interface\n") + "Treat the nexthop as directly attached to the interface\n" + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -914,7 +946,7 @@ DEFPY_YANG(ipv6_route_address_interface, return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, gate_str, ifname, flag, tag_str, distance_str, label, table_str, - !!onlink); + !!onlink, color_str); } DEFPY_YANG(ipv6_route_address_interface_vrf, @@ -929,6 +961,7 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, |table (1-4294967295) \ |nexthop-vrf NAME \ |onlink$onlink \ + |color (1-4294967295) \ }]", NO_STR IPV6_STR @@ -946,7 +979,9 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, "Table to configure\n" "The table number to configure\n" VRF_CMD_HELP_STR - "Treat the nexthop as directly attached to the interface\n") + "Treat the nexthop as directly attached to the interface\n" + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -973,7 +1008,7 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, gate_str, ifname, flag, tag_str, distance_str, label, - table_str, !!onlink); + table_str, !!onlink, color_str); } DEFPY_YANG(ipv6_route, @@ -987,6 +1022,7 @@ DEFPY_YANG(ipv6_route, |label WORD \ |table (1-4294967295) \ |nexthop-vrf NAME \ + |color (1-4294967295) \ }]", NO_STR IPV6_STR @@ -1004,7 +1040,9 @@ DEFPY_YANG(ipv6_route, MPLS_LABEL_HELPSTR "Table to configure\n" "The table number to configure\n" - VRF_CMD_HELP_STR) + VRF_CMD_HELP_STR + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -1024,7 +1062,7 @@ DEFPY_YANG(ipv6_route, return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, gate_str, ifname, flag, tag_str, distance_str, label, table_str, - false); + false, color_str); } DEFPY_YANG(ipv6_route_vrf, @@ -1037,6 +1075,7 @@ DEFPY_YANG(ipv6_route_vrf, |label WORD \ |table (1-4294967295) \ |nexthop-vrf NAME \ + |color (1-4294967295) \ }]", NO_STR IPV6_STR @@ -1053,7 +1092,9 @@ DEFPY_YANG(ipv6_route_vrf, MPLS_LABEL_HELPSTR "Table to configure\n" "The table number to configure\n" - VRF_CMD_HELP_STR) + VRF_CMD_HELP_STR + "SR-TE color\n" + "The SR-TE color to configure\n") { const char *nh_vrf; const char *flag = NULL; @@ -1080,7 +1121,7 @@ DEFPY_YANG(ipv6_route_vrf, return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, gate_str, ifname, flag, tag_str, distance_str, label, - table_str, false); + table_str, false, color_str); } DEFPY_YANG(debug_staticd, debug_staticd_cmd, diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index d8a4b7f0cb..1bdbb69d00 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -431,6 +431,10 @@ extern void static_zebra_route_add(struct route_node *rn, api_nh->vrf_id = nh->nh_vrf_id; if (nh->onlink) SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK); + if (nh->color != 0) { + SET_FLAG(api.message, ZAPI_MESSAGE_SRTE); + api_nh->srte_color = nh->color; + } nh->state = STATIC_SENT_TO_ZEBRA; diff --git a/yang/frr-nexthop.yang b/yang/frr-nexthop.yang index c918a7cbfd..0cb0f93ee4 100644 --- a/yang/frr-nexthop.yang +++ b/yang/frr-nexthop.yang @@ -188,6 +188,16 @@ module frr-nexthop { "Nexthop is directly connected."; } + leaf srte-color { + when "../nh-type = 'ip4' or + ../nh-type = 'ip6' or + ../nh-type = 'ip4-ifindex' or + ../nh-type = 'ip6-ifindex'"; + type uint32; + description + "The nexthop SR-TE color"; + } + uses rt-types:mpls-label-stack { description "Nexthop's MPLS label stack."; diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c index a25d08f267..1fc1faff67 100644 --- a/zebra/zebra_nb.c +++ b/zebra/zebra_nb.c @@ -552,6 +552,12 @@ const struct frr_yang_module_info frr_zebra_info = { .get_elem = lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem, } }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/srte-color", + .cbs = { + .get_elem = lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_color_get_elem, + } + }, { .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry", .cbs = { diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index 80aeb02d2d..e68b819767 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -275,6 +275,9 @@ lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_bh_type_get_elem( struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem( struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_color_get_elem( + struct nb_cb_get_elem_args *args); const void * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_next( struct nb_cb_get_next_args *args); diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c index 19ad3769eb..21c89f64ed 100644 --- a/zebra/zebra_nb_state.c +++ b/zebra/zebra_nb_state.c @@ -806,6 +806,22 @@ lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem( return NULL; } +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/srte-color + */ +struct yang_data * +lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_color_get_elem( + struct nb_cb_get_elem_args *args) +{ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE)) + return yang_data_new_uint32(args->xpath, nexthop->srte_color); + + return NULL; +} + /* * XPath: * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry