staticd: add vtysh srv6 multiple segs SIDs

Append staticd vty with multiple segs SIDs.

Signed-off-by: Dmytro Shytyi <dmytro.shytyi@6wind.com>
This commit is contained in:
Dmytro Shytyi 2023-07-26 18:44:23 +02:00
parent b13b5f85f9
commit d91a38a4db

View 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);