]> git.puffer.fish Git - matthieu/frr.git/commitdiff
staticd: add support for SR Policies
authorSebastien Merle <sebastien@netdef.org>
Fri, 14 Feb 2020 14:49:25 +0000 (14:49 +0000)
committerSebastien Merle <sebastien@netdef.org>
Wed, 12 Aug 2020 11:28:48 +0000 (13:28 +0200)
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 <sascha@netdef.org>
Signed-off-by: Sebastien Merle <sebastien@netdef.org>
12 files changed:
doc/user/static.rst
staticd/static_nb.c
staticd/static_nb.h
staticd/static_nb_config.c
staticd/static_routes.c
staticd/static_routes.h
staticd/static_vty.c
staticd/static_zebra.c
yang/frr-nexthop.yang
zebra/zebra_nb.c
zebra/zebra_nb.h
zebra/zebra_nb_state.c

index 09bdc9cbea0ea238c0d71cd517514abb74b4fd2c..6302d1b148f152e2b40dfbb2ca796fff6aa63a82 100644 (file)
@@ -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
index 419a6a53668b256c5547ae515054eb36bdeead49..51704426f0d1dd0c585dbc81bbc8a4733d99b4e0 100644 (file)
@@ -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 = {
index e46c156265f7ecd2267f2369f9a2d01eff19377b..d145c31f77556977dccf62bfafe5740dd1f2e618 100644 (file)
@@ -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"
index 40c4d85fb688c3cf44ed3644be19a7caeb0a9e63..e89832069c6489526e1225313fb995e4967f48fc 100644 (file)
@@ -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
index 3836109e36a6d3cd0dad3ca28d1ea7ee9699d853..d9f2faabaf7225e1e4ae839630491b5958ec0adc 100644 (file)
@@ -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));
index 89ef54402335f5b7f71f126932d7a5db7485579f..e5c10d18a418d7bc6df3c33b910fcfbe85501965 100644 (file)
@@ -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,
index ac18f6adf467b3231299c5cf928350651bc97e3d..ba1a8f9a257965de6468dac096a3bfcad702c885 100644 (file)
@@ -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,
index d8a4b7f0cbbf4c9687396928064117b683eb2ca5..1bdbb69d00ad2a987c7b10f383d60cf07a7c2d90 100644 (file)
@@ -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;
 
index c918a7cbfdc38fc170aaf06db72146c557318859..0cb0f93ee41504c8e6bb90f0e0d3728e915f82a5 100644 (file)
@@ -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.";
index a25d08f26766aa689eb32ca5608b4ca91c2516f1..1fc1faff67cb46bbbea0eb8686e9662712cc1722 100644 (file)
@@ -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 = {
index 80aeb02d2de76cc640dbb791bfd89da94beab728..e68b819767fad4f0276592d2c890b3aeb4fddda8 100644 (file)
@@ -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);
index 19ad3769eb5145cff8ad92adc245e8154d838e9a..21c89f64ed6f370d43a525778415cd4ce5a0b174 100644 (file)
@@ -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