Skip to content

Commit

Permalink
Merge pull request #18198 from cscarpitta/feature/srv6_staticd_ua
Browse files Browse the repository at this point in the history
staticd: Add support for SRv6 uA behavior
  • Loading branch information
riw777 authored Feb 26, 2025
2 parents 1016090 + 35b40cc commit 9a939d6
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 10 deletions.
11 changes: 7 additions & 4 deletions doc/user/static.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,18 @@ SRv6 Static SIDs Commands
Move from srv6 node to static-sids node. In this static-sids node, user can
configure static SRv6 SIDs.

.. clicmd:: sid X:X::X:X/M locator NAME behavior <uN|uDT4|uDT6|uDT46> [vrf VRF]
.. clicmd:: sid X:X::X:X/M locator NAME behavior <uN|uA|uDT4|uDT6|uDT46> [vrf VRF] [interface IFNAME [nexthop X:X::X:X]]

Specify the locator sid manually. Configuring a local sid in a purely static mode
by specifying the sid value would generate a unique SID.
This feature will support the configuration of static SRv6 decapsulation on the system.

It supports four parameter options, corresponding to the following functions:
uN, uDT4, uDT6, uDT46
It supports the following behaviors: uN, uA, uDT4, uDT6, uDT46.

When configuring the local sid, if the action is set to 'uN', no vrf should be set.
While for any other action, it is necessary to specify a specific vrf.
For uDT4, uDT6 and uDT46, it is necessary to specify a specific vrf.
The uA behavior requires the outgoing interface and optionally the IPv6 address of the Layer 3 adjacency
to which the packet should be forwarded.

::

Expand All @@ -228,6 +229,7 @@ SRv6 Static SIDs Commands
router(config-srv6-sids)# sid fcbb:bbbb:1:fe01::/64 locator LOC1 behavior uDT6 vrf Vrf1
router(config-srv6-sids)# sid fcbb:bbbb:1:fe02::/64 locator LOC1 behavior uDT4 vrf Vrf1
router(config-srv6-sids)# sid fcbb:bbbb:1:fe03::/64 locator LOC1 behavior uDT46 vrf Vrf2
router(config-srv6-sids)# sid fcbb:bbbb:1:fe04::/64 locator LOC1 behavior uA interface eth0 nexthop 2001::2

router(config-srv6-locator)# show run
...
Expand All @@ -237,5 +239,6 @@ SRv6 Static SIDs Commands
sid fcbb:bbbb:1:fe01::/64 locator LOC1 behavior uDT6 vrf Vrf1
sid fcbb:bbbb:1:fe02::/64 locator LOC1 behavior uDT4 vrf Vrf1
sid fcbb:bbbb:1:fe03::/64 locator LOC1 behavior uDT46 vrf Vrf2
sid fcbb:bbbb:1:fe04::/64 locator LOC1 behavior uA interface eth0 nexthop 2001::2
!
...
1 change: 1 addition & 0 deletions lib/srv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ struct srv6_sid_ctx {
struct in_addr nh4;
struct in6_addr nh6;
vrf_id_t vrf_id;
ifindex_t ifindex;
};

static inline const char *seg6_mode2str(enum seg6_mode_t mode)
Expand Down
21 changes: 21 additions & 0 deletions staticd/static_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,27 @@ const struct frr_yang_module_info frr_staticd_info = {
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_vrf_name_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/paths",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/paths/interface",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/paths/next-hop",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/locator-name",
.cbs = {
Expand Down
16 changes: 16 additions & 0 deletions staticd/static_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routi
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_vrf_name_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_locator_name_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_locator_name_destroy(
Expand Down Expand Up @@ -183,6 +195,10 @@ int routing_control_plane_protocols_name_validate(

#define FRR_STATIC_SRV6_SID_LOCATOR_NAME_XPATH "/locator-name"

#define FRR_STATIC_SRV6_SID_INTERFACE_XPATH "/paths[path-index=%u]/interface"

#define FRR_STATIC_SRV6_SID_NEXTHOP_XPATH "/paths[path-index=%u]/next-hop"

#ifdef __cplusplus
}
#endif
Expand Down
107 changes: 107 additions & 0 deletions staticd/static_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,113 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routi
return NB_OK;
}

/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/paths
*/
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_create(
struct nb_cb_create_args *args)
{
/* Actual setting is done in apply_finish */
return NB_OK;
}

int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_destroy(
struct nb_cb_destroy_args *args)
{
return NB_OK;
}

/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/paths/interface
*/
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_modify(
struct nb_cb_modify_args *args)
{
struct static_srv6_sid *sid;
const char *ifname;

if (args->event != NB_EV_APPLY)
return NB_OK;

sid = nb_running_get_entry(args->dnode, NULL, true);

/* Release and uninstall existing SID, if any, before requesting the new one */
if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) {
static_zebra_release_srv6_sid(sid);
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID);
}

if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA)) {
static_zebra_srv6_sid_uninstall(sid);
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA);
}

ifname = yang_dnode_get_string(args->dnode, "../interface");
snprintf(sid->attributes.ifname, sizeof(sid->attributes.ifname), "%s", ifname);

return NB_OK;
}

int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_destroy(
struct nb_cb_destroy_args *args)
{
return NB_OK;
}

/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/paths/next-hop
*/
int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_modify(
struct nb_cb_modify_args *args)
{
struct static_srv6_sid *sid;
struct ipaddr nexthop;

switch (args->event) {
case NB_EV_VALIDATE:
zlog_info("validating nexthop %pI6", &nexthop.ipaddr_v6);
yang_dnode_get_ip(&nexthop, args->dnode, "../next-hop");
if (!IS_IPADDR_V6(&nexthop)) {
snprintf(args->errmsg, args->errmsg_len,
"%% Nexthop must be an IPv6 address");
return NB_ERR_VALIDATION;
}
break;
case NB_EV_ABORT:
case NB_EV_PREPARE:
break;
case NB_EV_APPLY:
sid = nb_running_get_entry(args->dnode, NULL, true);

/* Release and uninstall existing SID, if any, before requesting the new one */
if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) {
static_zebra_release_srv6_sid(sid);
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID);
}

if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA)) {
static_zebra_srv6_sid_uninstall(sid);
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA);
}

yang_dnode_get_ip(&nexthop, args->dnode, "../next-hop");
sid->attributes.nh6 = nexthop.ipaddr_v6;

break;
}

return NB_OK;
}

int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_destroy(
struct nb_cb_destroy_args *args)
{
return NB_OK;
}

/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/vrf-name
Expand Down
46 changes: 44 additions & 2 deletions staticd/static_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -1199,13 +1199,18 @@ DEFUN_NOSH (static_srv6_sids, static_srv6_sids_cmd,
}

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>",
"sid X:X::X:X/M locator NAME$locator_name behavior <uN | uA interface INTERFACE$interface [nexthop X:X::X:X$nh6] | 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"
"Behavior uA\n"
"Configure the interface\n"
"Interface name\n"
"Configure the nexthop\n"
"IPv6 address of the nexthop\n"
"Apply the code to an uDT6 SID\n"
"Configure VRF name\n"
"Specify VRF name\n"
Expand All @@ -1223,7 +1228,10 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd,
char xpath_sid[XPATH_MAXLEN];
char xpath_behavior[XPATH_MAXLEN];
char xpath_vrf_name[XPATH_MAXLEN];
char xpath_ifname[XPATH_MAXLEN];
char xpath_nexthop[XPATH_MAXLEN];
char xpath_locator_name[XPATH_MAXLEN];
char ab_xpath[XPATH_MAXLEN];

if (argv_find(argv, argc, "uN", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID;
Expand All @@ -1236,6 +1244,8 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd,
} else if (argv_find(argv, argc, "uDT46", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID;
vrf_name = argv[idx + 2]->arg;
} else if (argv_find(argv, argc, "uA", &idx)) {
behavior = SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID;
}

snprintf(xpath_srv6, sizeof(xpath_srv6), FRR_STATIC_SRV6_INFO_KEY_XPATH,
Expand All @@ -1259,6 +1269,22 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd,
nb_cli_enqueue_change(vty, xpath_vrf_name, NB_OP_MODIFY, vrf_name);
}

if (interface) {
snprintf(ab_xpath, sizeof(ab_xpath), FRR_STATIC_SRV6_SID_INTERFACE_XPATH, 0);
strlcpy(xpath_ifname, xpath_sid, sizeof(xpath_ifname));
strlcat(xpath_ifname, ab_xpath, sizeof(xpath_ifname));

nb_cli_enqueue_change(vty, xpath_ifname, NB_OP_MODIFY, interface);
}

if (nh6_str) {
snprintf(ab_xpath, sizeof(ab_xpath), FRR_STATIC_SRV6_SID_NEXTHOP_XPATH, 0);
strlcpy(xpath_nexthop, xpath_sid, sizeof(xpath_nexthop));
strlcat(xpath_nexthop, ab_xpath, sizeof(xpath_nexthop));

nb_cli_enqueue_change(vty, xpath_nexthop, NB_OP_MODIFY, nh6_str);
}

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));
Expand All @@ -1269,14 +1295,19 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd,
}

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 sid X:X::X:X/M [locator NAME$locator_name] [behavior <uN | uA interface INTERFACE$interface [nexthop X:X::X:X$nh6] | 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"
"Behavior uA\n"
"Configure the interface\n"
"Interface name\n"
"Configure the nexthop\n"
"IPv6 address of the nexthop\n"
"Apply the code to an uDT6 SID\n"
"Configure VRF name\n"
"Specify VRF name\n"
Expand Down Expand Up @@ -1685,6 +1716,7 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
{
enum srv6_endpoint_behavior_codepoint srv6_behavior;
struct prefix_ipv6 sid_value;
struct ipaddr nexthop;

yang_dnode_get_ipv6p(&sid_value, sid, "sid");

Expand Down Expand Up @@ -1756,6 +1788,16 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
if (yang_dnode_exists(sid, "vrf-name"))
vty_out(vty, " vrf %s", yang_dnode_get_string(sid, "vrf-name"));

if (yang_dnode_exists(sid, "paths[path-index=0]/interface")) {
vty_out(vty, " interface %s",
yang_dnode_get_string(sid, "paths[path-index=0]/interface"));

if (yang_dnode_exists(sid, "paths[path-index=0]/next-hop")) {
yang_dnode_get_ip(&nexthop, sid, "paths[path-index=0]/next-hop");
vty_out(vty, " nexthop %pI6", &nexthop.ipaddr_v6);
}
}

vty_out(vty, "\n");
}

Expand Down
Loading

0 comments on commit 9a939d6

Please sign in to comment.