summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/user/static.rst12
-rw-r--r--staticd/static_nb.c14
-rw-r--r--staticd/static_nb.h10
-rw-r--r--staticd/static_nb_config.c98
-rw-r--r--staticd/static_routes.c3
-rw-r--r--staticd/static_routes.h5
-rw-r--r--staticd/static_vty.c83
-rw-r--r--staticd/static_zebra.c4
-rw-r--r--yang/frr-nexthop.yang10
-rw-r--r--zebra/zebra_nb.c6
-rw-r--r--zebra/zebra_nb.h3
-rw-r--r--zebra/zebra_nb_state.c16
12 files changed, 240 insertions, 24 deletions
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
@@ -76,6 +76,13 @@ const struct frr_yang_module_info frr_staticd_info = {
}
},
{
+ .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 = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create,
@@ -154,6 +161,13 @@ const struct frr_yang_module_info frr_staticd_info = {
}
},
{
+ .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 = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create,
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
@@ -1124,6 +1182,44 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr
/*
* 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
*/
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
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
@@ -553,6 +553,12 @@ const struct frr_yang_module_info frr_zebra_info = {
}
},
{
+ .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 = {
.get_next = lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_next,
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
@@ -808,6 +808,22 @@ 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
+ */
+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
*/
const void *