summaryrefslogtreecommitdiffstats
path: root/staticd
diff options
context:
space:
mode:
authorDmytro Shytyi <dmytro.shytyi@6wind.com>2023-07-26 18:44:23 +0200
committerDmytro Shytyi <dmytro.shytyi@6wind.com>2023-09-20 15:07:15 +0200
commitd91a38a4db39ddf756ce03c41ced78b3e6c70992 (patch)
treecec5c5320d60c606f8b986a249fcb7fb9b6cb926 /staticd
parentstaticd: northbound srv6 hooks for segs stack yang model (diff)
downloadfrr-d91a38a4db39ddf756ce03c41ced78b3e6c70992.tar.xz
frr-d91a38a4db39ddf756ce03c41ced78b3e6c70992.zip
staticd: add vtysh srv6 multiple segs SIDs
Append staticd vty with multiple segs SIDs. Signed-off-by: Dmytro Shytyi <dmytro.shytyi@6wind.com>
Diffstat (limited to 'staticd')
-rw-r--r--staticd/static_vty.c280
1 files changed, 169 insertions, 111 deletions
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index 16e4cb7d8..b07878f06 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -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);