]> git.puffer.fish Git - matthieu/frr.git/commitdiff
staticd: add vtysh srv6 multiple segs SIDs
authorDmytro Shytyi <dmytro.shytyi@6wind.com>
Wed, 26 Jul 2023 16:44:23 +0000 (18:44 +0200)
committerDmytro Shytyi <dmytro.shytyi@6wind.com>
Wed, 20 Sep 2023 13:07:15 +0000 (15:07 +0200)
Append staticd vty with multiple segs SIDs.

Signed-off-by: Dmytro Shytyi <dmytro.shytyi@6wind.com>
staticd/static_vty.c

index 16e4cb7d83bcc6bb3f1fee458b884ce15fa3f8be..b07878f063e1c9e2931e76ef1fcb0e099098f53b 100644 (file)
@@ -47,6 +47,7 @@ struct static_route_args {
        const char *source;
        const char *gateway;
        const char *interface_name;
+       const char *segs;
        const char *flag;
        const char *tag;
        const char *distance;
@@ -73,12 +74,16 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
        char xpath_nexthop[XPATH_MAXLEN];
        char xpath_mpls[XPATH_MAXLEN];
        char xpath_label[XPATH_MAXLEN];
+       char xpath_segs[XPATH_MAXLEN];
+       char xpath_seg[XPATH_MAXLEN];
        char ab_xpath[XPATH_MAXLEN];
        char buf_prefix[PREFIX_STRLEN];
        char buf_src_prefix[PREFIX_STRLEN] = {};
        char buf_nh_type[PREFIX_STRLEN] = {};
        char buf_tag[PREFIX_STRLEN];
        uint8_t label_stack_id = 0;
+       uint8_t segs_stack_id = 0;
+
        const char *buf_gate_str;
        uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
        route_tag_t tag = 0;
@@ -345,7 +350,39 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
                        nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
                                              NULL);
                }
+               if (args->segs) {
+                       /* copy of seg string (start) */
+                       char *ostr;
+                       /* pointer to next segment */
+                       char *nump;
 
+                       strlcpy(xpath_segs, xpath_nexthop, sizeof(xpath_segs));
+                       strlcat(xpath_segs, FRR_STATIC_ROUTE_NH_SRV6_SEGS_XPATH,
+                               sizeof(xpath_segs));
+
+                       nb_cli_enqueue_change(vty, xpath_segs, NB_OP_DESTROY,
+                                             NULL);
+
+                       ostr = XSTRDUP(MTYPE_TMP, args->segs);
+                       while ((nump = strsep(&ostr, "/")) != NULL) {
+                               snprintf(ab_xpath, sizeof(ab_xpath),
+                                        FRR_STATIC_ROUTE_NH_SRV6_KEY_SEG_XPATH,
+                                        segs_stack_id);
+                               strlcpy(xpath_seg, xpath_segs,
+                                       sizeof(xpath_seg));
+                               strlcat(xpath_seg, ab_xpath, sizeof(xpath_seg));
+                               nb_cli_enqueue_change(vty, xpath_seg,
+                                                     NB_OP_MODIFY, nump);
+                               segs_stack_id++;
+                       }
+                       XFREE(MTYPE_TMP, ostr);
+               } else {
+                       strlcpy(xpath_segs, xpath_nexthop, sizeof(xpath_segs));
+                       strlcat(xpath_segs, FRR_STATIC_ROUTE_NH_SRV6_SEGS_XPATH,
+                               sizeof(xpath_segs));
+                       nb_cli_enqueue_change(vty, xpath_segs, NB_OP_DESTROY,
+                                             NULL);
+               }
                if (args->bfd) {
                        char xpath_bfd[XPATH_MAXLEN];
 
@@ -951,9 +988,8 @@ DEFPY_YANG(ipv6_route_blackhole_vrf,
        return static_route_nb_run(vty, &args);
 }
 
-DEFPY_YANG(ipv6_route_address_interface,
-      ipv6_route_address_interface_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+DEFPY_YANG(ipv6_route_address_interface, ipv6_route_address_interface_cmd,
+          "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
           X:X::X:X$gate                                    \
           <INTERFACE|Null0>$ifname                         \
           [{                                               \
@@ -966,33 +1002,28 @@ DEFPY_YANG(ipv6_route_address_interface,
            |onlink$onlink                                 \
            |color (1-4294967295)                          \
            |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
+               |segments WORD                                                             \
           }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Null interface\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR
-      "Treat the nexthop as directly attached to the interface\n"
-      "SR-TE color\n"
-      "The SR-TE color to configure\n"
-      BFD_INTEGRATION_STR
-      BFD_INTEGRATION_MULTI_HOP_STR
-      BFD_INTEGRATION_SOURCE_STR
-      BFD_INTEGRATION_SOURCEV4_STR
-      BFD_PROFILE_STR
-      BFD_PROFILE_NAME_STR)
+          NO_STR IPV6_STR
+          "Establish static routes\n"
+          "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+          "IPv6 source-dest route\n"
+          "IPv6 source prefix\n"
+          "IPv6 gateway address\n"
+          "IPv6 gateway interface name\n"
+          "Null interface\n"
+          "Set tag for this route\n"
+          "Tag value\n"
+          "Distance value for this prefix\n" VRF_CMD_HELP_STR MPLS_LABEL_HELPSTR
+          "Table to configure\n"
+          "The table number to configure\n" VRF_CMD_HELP_STR
+          "Treat the nexthop as directly attached to the interface\n"
+          "SR-TE color\n"
+          "The SR-TE color to configure\n" BFD_INTEGRATION_STR
+                  BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR
+                          BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR
+                                  BFD_PROFILE_NAME_STR "Value of segs\n"
+          "Segs (SIDs)\n")
 {
        struct static_route_args args = {
                .delete = !!no,
@@ -1014,14 +1045,15 @@ DEFPY_YANG(ipv6_route_address_interface,
                .bfd_multi_hop = !!bfd_multi_hop,
                .bfd_source = bfd_source_str,
                .bfd_profile = bfd_profile,
+               .segs = segments,
        };
 
        return static_route_nb_run(vty, &args);
 }
 
 DEFPY_YANG(ipv6_route_address_interface_vrf,
-      ipv6_route_address_interface_vrf_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+          ipv6_route_address_interface_vrf_cmd,
+          "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
           X:X::X:X$gate                                    \
           <INTERFACE|Null0>$ifname                         \
           [{                                               \
@@ -1033,32 +1065,28 @@ DEFPY_YANG(ipv6_route_address_interface_vrf,
            |onlink$onlink                                 \
            |color (1-4294967295)                          \
            |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
+               |segments WORD                                                             \
           }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Null interface\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR
-      "Treat the nexthop as directly attached to the interface\n"
-      "SR-TE color\n"
-      "The SR-TE color to configure\n"
-      BFD_INTEGRATION_STR
-      BFD_INTEGRATION_MULTI_HOP_STR
-      BFD_INTEGRATION_SOURCE_STR
-      BFD_INTEGRATION_SOURCEV4_STR
-      BFD_PROFILE_STR
-      BFD_PROFILE_NAME_STR)
+          NO_STR IPV6_STR
+          "Establish static routes\n"
+          "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+          "IPv6 source-dest route\n"
+          "IPv6 source prefix\n"
+          "IPv6 gateway address\n"
+          "IPv6 gateway interface name\n"
+          "Null interface\n"
+          "Set tag for this route\n"
+          "Tag value\n"
+          "Distance value for this prefix\n" MPLS_LABEL_HELPSTR
+          "Table to configure\n"
+          "The table number to configure\n" VRF_CMD_HELP_STR
+          "Treat the nexthop as directly attached to the interface\n"
+          "SR-TE color\n"
+          "The SR-TE color to configure\n" BFD_INTEGRATION_STR
+                  BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR
+                          BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR
+                                  BFD_PROFILE_NAME_STR "Value of segs\n"
+          "Segs (SIDs)\n")
 {
        struct static_route_args args = {
                .delete = !!no,
@@ -1080,14 +1108,14 @@ DEFPY_YANG(ipv6_route_address_interface_vrf,
                .bfd_multi_hop = !!bfd_multi_hop,
                .bfd_source = bfd_source_str,
                .bfd_profile = bfd_profile,
+               .segs = segments,
        };
 
        return static_route_nb_run(vty, &args);
 }
 
-DEFPY_YANG(ipv6_route,
-      ipv6_route_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+DEFPY_YANG(ipv6_route, ipv6_route_cmd,
+          "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
           <X:X::X:X$gate|<INTERFACE|Null0>$ifname>         \
           [{                                               \
             tag (1-4294967295)                             \
@@ -1098,32 +1126,26 @@ DEFPY_YANG(ipv6_route,
             |nexthop-vrf NAME                              \
             |color (1-4294967295)                          \
            |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
+                       |segments WORD                                                             \
           }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Null interface\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR
-      "SR-TE color\n"
-      "The SR-TE color to configure\n"
-      BFD_INTEGRATION_STR
-      BFD_INTEGRATION_MULTI_HOP_STR
-      BFD_INTEGRATION_SOURCE_STR
-      BFD_INTEGRATION_SOURCEV4_STR
-      BFD_PROFILE_STR
-      BFD_PROFILE_NAME_STR)
+          NO_STR IPV6_STR
+          "Establish static routes\n"
+          "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+          "IPv6 source-dest route\n"
+          "IPv6 source prefix\n"
+          "IPv6 gateway address\n"
+          "IPv6 gateway interface name\n"
+          "Null interface\n"
+          "Set tag for this route\n"
+          "Tag value\n"
+          "Distance value for this prefix\n" VRF_CMD_HELP_STR MPLS_LABEL_HELPSTR
+          "Table to configure\n"
+          "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n"
+          "The SR-TE color to configure\n" BFD_INTEGRATION_STR
+                  BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR
+                          BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR
+                                  BFD_PROFILE_NAME_STR "Value of segs\n"
+          "Segs (SIDs)\n")
 {
        struct static_route_args args = {
                .delete = !!no,
@@ -1144,14 +1166,15 @@ DEFPY_YANG(ipv6_route,
                .bfd_multi_hop = !!bfd_multi_hop,
                .bfd_source = bfd_source_str,
                .bfd_profile = bfd_profile,
+               .segs = segments,
+
        };
 
        return static_route_nb_run(vty, &args);
 }
 
-DEFPY_YANG(ipv6_route_vrf,
-      ipv6_route_vrf_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+DEFPY_YANG(ipv6_route_vrf, ipv6_route_vrf_cmd,
+          "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
           <X:X::X:X$gate|<INTERFACE|Null0>$ifname>                 \
           [{                                               \
             tag (1-4294967295)                             \
@@ -1161,31 +1184,26 @@ DEFPY_YANG(ipv6_route_vrf,
             |nexthop-vrf NAME                              \
            |color (1-4294967295)                          \
            |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
+               |segments WORD                                                             \
           }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Null interface\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR
-      "SR-TE color\n"
-      "The SR-TE color to configure\n"
-      BFD_INTEGRATION_STR
-      BFD_INTEGRATION_MULTI_HOP_STR
-      BFD_INTEGRATION_SOURCE_STR
-      BFD_INTEGRATION_SOURCEV4_STR
-      BFD_PROFILE_STR
-      BFD_PROFILE_NAME_STR)
+          NO_STR IPV6_STR
+          "Establish static routes\n"
+          "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+          "IPv6 source-dest route\n"
+          "IPv6 source prefix\n"
+          "IPv6 gateway address\n"
+          "IPv6 gateway interface name\n"
+          "Null interface\n"
+          "Set tag for this route\n"
+          "Tag value\n"
+          "Distance value for this prefix\n" MPLS_LABEL_HELPSTR
+          "Table to configure\n"
+          "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n"
+          "The SR-TE color to configure\n" BFD_INTEGRATION_STR
+                  BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR
+                          BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR
+                                  BFD_PROFILE_NAME_STR "Value of segs\n"
+          "Segs (SIDs)\n")
 {
        struct static_route_args args = {
                .delete = !!no,
@@ -1206,6 +1224,7 @@ DEFPY_YANG(ipv6_route_vrf,
                .bfd_multi_hop = !!bfd_multi_hop,
                .bfd_source = bfd_source_str,
                .bfd_profile = bfd_profile,
+               .segs = segments,
        };
 
        return static_route_nb_run(vty, &args);
@@ -1252,6 +1271,39 @@ static int mpls_label_iter_cb(const struct lyd_node *dnode, void *arg)
        return YANG_ITER_CONTINUE;
 }
 
+struct srv6_seg_iter {
+       struct vty *vty;
+       bool first;
+};
+
+static int srv6_seg_iter_cb(const struct lyd_node *dnode, void *arg)
+{
+       struct srv6_seg_iter *iter = arg;
+       char buffer[INET6_ADDRSTRLEN];
+       struct in6_addr cli_seg;
+
+       if (yang_dnode_exists(dnode, "./seg")) {
+               if (iter->first) {
+                       yang_dnode_get_ipv6(&cli_seg, dnode, "./seg");
+                       if (inet_ntop(AF_INET6, &cli_seg, buffer,
+                                     INET6_ADDRSTRLEN) == NULL) {
+                               return 1;
+                       }
+                       vty_out(iter->vty, " segments %s", buffer);
+               } else {
+                       yang_dnode_get_ipv6(&cli_seg, dnode, "./seg");
+                       if (inet_ntop(AF_INET6, &cli_seg, buffer,
+                                     INET6_ADDRSTRLEN) == NULL) {
+                               return 1;
+                       }
+                       vty_out(iter->vty, "/%s", buffer);
+               }
+               iter->first = false;
+       }
+
+       return YANG_ITER_CONTINUE;
+}
+
 static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route,
                             const struct lyd_node *src,
                             const struct lyd_node *path,
@@ -1266,6 +1318,7 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route,
        uint32_t tag;
        uint8_t distance;
        struct mpls_label_iter iter;
+       struct srv6_seg_iter seg_iter;
        const char *nexthop_vrf;
        uint32_t table_id;
        bool onlink;
@@ -1342,6 +1395,11 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route,
        yang_dnode_iterate(mpls_label_iter_cb, &iter, nexthop,
                           "./mpls-label-stack/entry");
 
+       seg_iter.vty = vty;
+       seg_iter.first = true;
+       yang_dnode_iterate(srv6_seg_iter_cb, &seg_iter, nexthop,
+                          "./srv6-segs-stack/entry");
+
        nexthop_vrf = yang_dnode_get_string(nexthop, "./vrf");
        if (strcmp(vrf, nexthop_vrf))
                vty_out(vty, " nexthop-vrf %s", nexthop_vrf);