Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so nexthops have a ifindex already. I don't understand enough about SRv6 to say if that would be ok or not to use?
For SRv6 what is the actual definition of a nexthop? Does it possibly include a ifindex already? What if they disagree?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Donald, many thanks for the review.

nh4 and nh6 are not nexthop objects. It is the IP address of the next hop.
This is how it is also defined in the IETF SRv6 YANG model https://datatracker.ietf.org/doc/html/draft-ietf-spring-srv6-yang-04

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the commit message to clarify this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would removing nh4 / nh6 vrf_id and ifindex, replacing with struct nexthop make anything clearer or easier to do? I wonder why we have this specialized structure here, when we something generic like struct nexthop could work?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Donald,

Many thanks for your comments.

I’m already working on revisiting all the SRv6 data structures that have been added in the last years. I will open a refactoring PR for this.
I will definitely include your feedback in my refactoring PR.

I’m also doing some performance improvements. As part of the refactoring, I will also include these enhancements.

};

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
Loading