staticd: Add CLI for SRv6 static SIDs

Signed-off-by: Yuqing Zhao <galadriel.zyq@alibaba-inc.com>
This commit is contained in:
Yuqing Zhao 2025-01-13 11:13:07 +01:00
parent 4d958078b8
commit 69a49c7359
2 changed files with 221 additions and 0 deletions

View file

@ -236,6 +236,24 @@ int routing_control_plane_protocols_name_validate(
FRR_S_ROUTE_SRC_INFO_KEY_NO_DISTANCE_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
/* srv6 */
#define FRR_STATIC_SRV6_INFO_KEY_XPATH \
"/frr-routing:routing/control-plane-protocols/" \
"control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \
"frr-staticd:staticd/segment-routing/srv6"
/* srv6/static-sids */
#define FRR_STATIC_SRV6_SID_KEY_XPATH \
FRR_STATIC_SRV6_INFO_KEY_XPATH \
"/static-sids/" \
"sid[sid='%s']"
#define FRR_STATIC_SRV6_SID_BEHAVIOR_XPATH "/behavior"
#define FRR_STATIC_SRV6_SID_VRF_NAME_XPATH "/vrf-name"
#define FRR_STATIC_SRV6_SID_LOCATOR_NAME_XPATH "/locator-name"
#ifdef __cplusplus
}
#endif

View file

@ -27,6 +27,8 @@
#include "static_debug.h"
#include "staticd/static_vty_clippy.c"
#include "static_nb.h"
#include "static_srv6.h"
#include "static_zebra.h"
#define STATICD_STR "Static route daemon\n"
@ -1201,8 +1203,167 @@ DEFPY_YANG(ipv6_route_vrf, ipv6_route_vrf_cmd,
return static_route_nb_run(vty, &args);
}
DEFUN_NOSH (static_segment_routing, static_segment_routing_cmd,
"segment-routing",
"Segment Routing\n")
{
VTY_PUSH_CONTEXT_NULL(SEGMENT_ROUTING_NODE);
return CMD_SUCCESS;
}
DEFUN_NOSH (static_srv6, static_srv6_cmd,
"srv6",
"Segment Routing SRv6\n")
{
VTY_PUSH_CONTEXT_NULL(SRV6_NODE);
return CMD_SUCCESS;
}
DEFUN_YANG_NOSH (no_static_srv6, no_static_srv6_cmd,
"no srv6",
NO_STR
"Segment Routing SRv6\n")
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath), FRR_STATIC_SRV6_INFO_KEY_XPATH, "frr-staticd:staticd",
"staticd", VRF_DEFAULT_NAME);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, "%s", xpath);
}
DEFUN_NOSH (static_srv6_sids, static_srv6_sids_cmd,
"static-sids",
"Segment Routing SRv6 SIDs\n")
{
VTY_PUSH_CONTEXT_NULL(SRV6_SIDS_NODE);
return CMD_SUCCESS;
}
DEFPY_YANG(srv6_sid, srv6_sid_cmd,
"sid X:X::X:X/M locator NAME$locator_name behavior <uN | uDT6 vrf VIEWVRFNAME | uDT4 vrf VIEWVRFNAME | uDT46 vrf VIEWVRFNAME>",
"Configure SRv6 SID\n"
"Specify SRv6 SID\n"
"Locator name\n"
"Specify Locator name\n"
"Specify SRv6 SID behavior\n"
"Apply the code to a uN SID\n"
"Apply the code to an uDT6 SID\n"
"Configure VRF name\n"
"Specify VRF name\n"
"Apply the code to an uDT4 SID\n"
"Configure VRF name\n"
"Specify VRF name\n"
"Apply the code to an uDT46 SID\n"
"Configure VRF name\n"
"Specify VRF name\n")
{
enum srv6_endpoint_behavior_codepoint behavior = SRV6_ENDPOINT_BEHAVIOR_RESERVED;
int idx = 0;
const char *vrf_name = NULL;
char xpath_srv6[XPATH_MAXLEN];
char xpath_sid[XPATH_MAXLEN];
char xpath_behavior[XPATH_MAXLEN];
char xpath_vrf_name[XPATH_MAXLEN];
char xpath_locator_name[XPATH_MAXLEN];
if (argv_find(argv, argc, "uN", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID;
} else if (argv_find(argv, argc, "uDT6", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID;
vrf_name = argv[idx + 2]->arg;
} else if (argv_find(argv, argc, "uDT4", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID;
vrf_name = argv[idx + 2]->arg;
} else if (argv_find(argv, argc, "uDT46", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID;
vrf_name = argv[idx + 2]->arg;
}
snprintf(xpath_srv6, sizeof(xpath_srv6), FRR_STATIC_SRV6_INFO_KEY_XPATH,
"frr-staticd:staticd", "staticd", VRF_DEFAULT_NAME);
snprintf(xpath_sid, sizeof(xpath_sid), FRR_STATIC_SRV6_SID_KEY_XPATH, "frr-staticd:staticd",
"staticd", VRF_DEFAULT_NAME, sid_str);
strlcpy(xpath_behavior, xpath_sid, sizeof(xpath_behavior));
strlcat(xpath_behavior, FRR_STATIC_SRV6_SID_BEHAVIOR_XPATH, sizeof(xpath_behavior));
nb_cli_enqueue_change(vty, xpath_sid, NB_OP_CREATE, sid_str);
nb_cli_enqueue_change(vty, xpath_behavior, NB_OP_MODIFY,
srv6_endpoint_behavior_codepoint2str(behavior));
if (vrf_name) {
strlcpy(xpath_vrf_name, xpath_sid, sizeof(xpath_vrf_name));
strlcat(xpath_vrf_name, FRR_STATIC_SRV6_SID_VRF_NAME_XPATH, sizeof(xpath_vrf_name));
nb_cli_enqueue_change(vty, xpath_vrf_name, NB_OP_MODIFY, vrf_name);
}
strlcpy(xpath_locator_name, xpath_sid, sizeof(xpath_locator_name));
strlcat(xpath_locator_name, FRR_STATIC_SRV6_SID_LOCATOR_NAME_XPATH,
sizeof(xpath_locator_name));
nb_cli_enqueue_change(vty, xpath_locator_name, NB_OP_MODIFY, locator_name);
return nb_cli_apply_changes(vty, "%s", xpath_sid);
}
DEFPY_YANG(no_srv6_sid, no_srv6_sid_cmd,
"no sid X:X::X:X/M [locator NAME$locator_name] [behavior <uN | uDT6 vrf VIEWVRFNAME | uDT4 vrf VIEWVRFNAME | uDT46 vrf VIEWVRFNAME>]",
NO_STR
"Configure SRv6 SID\n"
"Specify SRv6 SID\n"
"Locator name\n"
"Specify Locator name\n"
"Specify SRv6 SID behavior\n"
"Apply the code to a uN SID\n"
"Apply the code to an uDT6 SID\n"
"Configure VRF name\n"
"Specify VRF name\n"
"Apply the code to an uDT4 SID\n"
"Configure VRF name\n"
"Specify VRF name\n"
"Apply the code to an uDT46 SID\n"
"Configure VRF name\n"
"Specify VRF name\n")
{
char xpath[XPATH_MAXLEN + 37];
snprintf(xpath, sizeof(xpath), FRR_STATIC_SRV6_INFO_KEY_XPATH, "frr-staticd:staticd",
"staticd", VRF_DEFAULT_NAME);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
#ifdef INCLUDE_MGMTD_CMDDEFS_ONLY
static struct cmd_node sr_node = {
.name = "sr",
.node = SEGMENT_ROUTING_NODE,
.parent_node = CONFIG_NODE,
.prompt = "%s(config-sr)# ",
};
static struct cmd_node srv6_node = {
.name = "srv6",
.node = SRV6_NODE,
.parent_node = SEGMENT_ROUTING_NODE,
.prompt = "%s(config-srv6)# ",
};
static struct cmd_node srv6_sids_node = {
.name = "srv6-sids",
.node = SRV6_SIDS_NODE,
.parent_node = SRV6_NODE,
.prompt = "%s(config-srv6-sids)# ",
};
static void static_cli_show(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
@ -1594,6 +1755,33 @@ const struct frr_yang_module_info frr_staticd_cli_info = {
.cli_cmp = static_nexthop_cli_cmp,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing",
.cbs = {
.cli_show = static_segment_routing_cli_show,
.cli_show_end = static_segment_routing_cli_show_end,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6",
.cbs = {
.cli_show = static_srv6_cli_show,
.cli_show_end = static_srv6_cli_show_end,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/local-sids",
.cbs = {
.cli_show = static_sids_cli_show,
.cli_show_end = static_sids_cli_show_end,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/local-sids/sid",
.cbs = {
.cli_show = static_srv6_sid_cli_show,
}
},
{
.xpath = NULL,
},
@ -1670,6 +1858,21 @@ void static_vty_init(void)
install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
install_element(CONFIG_NODE, &ipv6_route_cmd);
install_element(VRF_NODE, &ipv6_route_vrf_cmd);
install_node(&sr_node);
install_node(&srv6_node);
install_node(&srv6_sids_node);
install_default(SEGMENT_ROUTING_NODE);
install_default(SRV6_NODE);
install_default(SRV6_SIDS_NODE);
install_element(CONFIG_NODE, &static_segment_routing_cmd);
install_element(SEGMENT_ROUTING_NODE, &static_srv6_cmd);
install_element(SEGMENT_ROUTING_NODE, &no_static_srv6_cmd);
install_element(SRV6_NODE, &static_srv6_sids_cmd);
install_element(SRV6_SIDS_NODE, &srv6_sid_cmd);
install_element(SRV6_SIDS_NODE, &no_srv6_sid_cmd);
#endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */
#ifndef INCLUDE_MGMTD_CMDDEFS_ONLY