forked from Mirror/frr
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:
parent
b13b5f85f9
commit
d91a38a4db
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue