Commit 1e02d758 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'seg6-add-next-c-sid-support-for-srv6-end-x-behavior'

Andrea Mayer says:

====================
seg6: add NEXT-C-SID support for SRv6 End.X behavior

In the Segment Routing (SR) architecture a list of instructions, called
segments, can be added to the packet headers to influence the forwarding and
processing of the packets in an SR enabled network.

Considering the Segment Routing over IPv6 data plane (SRv6) [1], the segment
identifiers (SIDs) are IPv6 addresses (128 bits) and the segment list (SID
List) is carried in the Segment Routing Header (SRH). A segment may correspond
to a "behavior" that is executed by a node when the packet is received.
The Linux kernel currently supports a large subset of the behaviors described
in [2] (e.g., End, End.X, End.T and so on).

In some SRv6 scenarios, the number of segments carried by the SID List may
increase dramatically, reducing the MTU (Maximum Transfer Unit) size and/or
limiting the processing power of legacy hardware devices (due to longer IPv6
headers).

The NEXT-C-SID mechanism [3] extends the SRv6 architecture by providing several
ways to efficiently represent the SID List.
By leveraging the NEXT-C-SID, it is possible to encode several SRv6 segments
within a single 128 bit SID address (also referenced as Compressed SID
Container). In this way, the length of the SID List can be drastically reduced.

The NEXT-C-SID mechanism is built upon the "flavors" framework defined in [2].
This framework is already supported by the Linux SRv6 subsystem and is used to
modify and/or extend a subset of existing behaviors.

In this patchset, we extend the SRv6 End.X behavior in order to support the
NEXT-C-SID mechanism.

In details, the patchset is made of:
 - patch 1/2: add NEXT-C-SID support for SRv6 End.X behavior;
 - patch 2/2: add selftest for NEXT-C-SID in SRv6 End.X behavior.

From the user space perspective, we do not need to change the iproute2 code to
support the NEXT-C-SID flavor for the SRv6 End.X behavior. However, we will
update the man page considering the NEXT-C-SID flavor applied to the SRv6 End.X
behavior in a separate patch.

[1] - https://datatracker.ietf.org/doc/html/rfc8754
[2] - https://datatracker.ietf.org/doc/html/rfc8986
[3] - https://datatracker.ietf.org/doc/html/draft-ietf-spring-srv6-srh-compression
====================

Link: https://lore.kernel.org/r/20230812180926.16689-1-andrea.mayer@uniroma2.itSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents c65dffc6 1c53717c
......@@ -109,15 +109,19 @@ struct bpf_lwt_prog {
#define next_csid_chk_lcnode_fn_bits(flen) \
next_csid_chk_lcblock_bits(flen)
/* flag indicating that flavors are set up for a given End* behavior */
#define SEG6_F_LOCAL_FLAVORS SEG6_F_ATTR(SEG6_LOCAL_FLAVORS)
#define SEG6_F_LOCAL_FLV_OP(flvname) BIT(SEG6_LOCAL_FLV_OP_##flvname)
#define SEG6_F_LOCAL_FLV_NEXT_CSID SEG6_F_LOCAL_FLV_OP(NEXT_CSID)
#define SEG6_F_LOCAL_FLV_PSP SEG6_F_LOCAL_FLV_OP(PSP)
/* Supported RFC8986 Flavor operations are reported in this bitmask */
#define SEG6_LOCAL_FLV8986_SUPP_OPS SEG6_F_LOCAL_FLV_PSP
/* Supported Flavor operations are reported in this bitmask */
#define SEG6_LOCAL_FLV_SUPP_OPS (SEG6_F_LOCAL_FLV_OP(NEXT_CSID) | \
#define SEG6_LOCAL_END_FLV_SUPP_OPS (SEG6_F_LOCAL_FLV_NEXT_CSID | \
SEG6_LOCAL_FLV8986_SUPP_OPS)
#define SEG6_LOCAL_END_X_FLV_SUPP_OPS SEG6_F_LOCAL_FLV_NEXT_CSID
struct seg6_flavors_info {
/* Flavor operations */
......@@ -411,9 +415,72 @@ static int end_next_csid_core(struct sk_buff *skb, struct seg6_local_lwt *slwt)
return input_action_end_finish(skb, slwt);
}
static int input_action_end_x_finish(struct sk_buff *skb,
struct seg6_local_lwt *slwt)
{
seg6_lookup_nexthop(skb, &slwt->nh6, 0);
return dst_input(skb);
}
static int input_action_end_x_core(struct sk_buff *skb,
struct seg6_local_lwt *slwt)
{
struct ipv6_sr_hdr *srh;
srh = get_and_validate_srh(skb);
if (!srh)
goto drop;
advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
return input_action_end_x_finish(skb, slwt);
drop:
kfree_skb(skb);
return -EINVAL;
}
static int end_x_next_csid_core(struct sk_buff *skb,
struct seg6_local_lwt *slwt)
{
const struct seg6_flavors_info *finfo = &slwt->flv_info;
struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
if (seg6_next_csid_is_arg_zero(daddr, finfo))
return input_action_end_x_core(skb, slwt);
/* update DA */
seg6_next_csid_advance_arg(daddr, finfo);
return input_action_end_x_finish(skb, slwt);
}
static bool seg6_next_csid_enabled(__u32 fops)
{
return fops & BIT(SEG6_LOCAL_FLV_OP_NEXT_CSID);
return fops & SEG6_F_LOCAL_FLV_NEXT_CSID;
}
/* Processing of SRv6 End, End.X, and End.T behaviors can be extended through
* the flavors framework. These behaviors must report the subset of (flavor)
* operations they currently implement. In this way, if a user specifies a
* flavor combination that is not supported by a given End* behavior, the
* kernel refuses to instantiate the tunnel reporting the error.
*/
static int seg6_flv_supp_ops_by_action(int action, __u32 *fops)
{
switch (action) {
case SEG6_LOCAL_ACTION_END:
*fops = SEG6_LOCAL_END_FLV_SUPP_OPS;
break;
case SEG6_LOCAL_ACTION_END_X:
*fops = SEG6_LOCAL_END_X_FLV_SUPP_OPS;
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
/* We describe the packet state in relation to the absence/presence of the SRH
......@@ -746,21 +813,14 @@ static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt)
/* regular endpoint, and forward to specified nexthop */
static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt)
{
struct ipv6_sr_hdr *srh;
srh = get_and_validate_srh(skb);
if (!srh)
goto drop;
advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
seg6_lookup_nexthop(skb, &slwt->nh6, 0);
const struct seg6_flavors_info *finfo = &slwt->flv_info;
__u32 fops = finfo->flv_ops;
return dst_input(skb);
/* check for the presence of NEXT-C-SID since it applies first */
if (seg6_next_csid_enabled(fops))
return end_x_next_csid_core(skb, slwt);
drop:
kfree_skb(skb);
return -EINVAL;
return input_action_end_x_core(skb, slwt);
}
static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt)
......@@ -1404,13 +1464,14 @@ static struct seg6_action_desc seg6_action_table[] = {
.action = SEG6_LOCAL_ACTION_END,
.attrs = 0,
.optattrs = SEG6_F_LOCAL_COUNTERS |
SEG6_F_ATTR(SEG6_LOCAL_FLAVORS),
SEG6_F_LOCAL_FLAVORS,
.input = input_action_end,
},
{
.action = SEG6_LOCAL_ACTION_END_X,
.attrs = SEG6_F_ATTR(SEG6_LOCAL_NH6),
.optattrs = SEG6_F_LOCAL_COUNTERS,
.optattrs = SEG6_F_LOCAL_COUNTERS |
SEG6_F_LOCAL_FLAVORS,
.input = input_action_end_x,
},
{
......@@ -2070,7 +2131,8 @@ static int parse_nla_flavors(struct nlattr **attrs, struct seg6_local_lwt *slwt,
{
struct seg6_flavors_info *finfo = &slwt->flv_info;
struct nlattr *tb[SEG6_LOCAL_FLV_MAX + 1];
unsigned long fops;
int action = slwt->action;
__u32 fops, supp_fops;
int rc;
rc = nla_parse_nested_deprecated(tb, SEG6_LOCAL_FLV_MAX,
......@@ -2086,7 +2148,8 @@ static int parse_nla_flavors(struct nlattr **attrs, struct seg6_local_lwt *slwt,
return -EINVAL;
fops = nla_get_u32(tb[SEG6_LOCAL_FLV_OPERATION]);
if (fops & ~SEG6_LOCAL_FLV_SUPP_OPS) {
rc = seg6_flv_supp_ops_by_action(action, &supp_fops);
if (rc < 0 || (fops & ~supp_fops)) {
NL_SET_ERR_MSG(extack, "Unsupported Flavor operation(s)");
return -EOPNOTSUPP;
}
......@@ -2618,6 +2681,11 @@ int __init seg6_local_init(void)
*/
BUILD_BUG_ON(SEG6_LOCAL_MAX + 1 > BITS_PER_TYPE(unsigned long));
/* Check whether the number of defined flavors exceeds the maximum
* allowed value.
*/
BUILD_BUG_ON(SEG6_LOCAL_FLV_OP_MAX + 1 > BITS_PER_TYPE(__u32));
/* If the default NEXT-C-SID Locator-Block/Node Function lengths (in
* bits) have been changed with invalid values, kernel build stops
* here.
......
......@@ -40,6 +40,7 @@ TEST_PROGS += srv6_end_dt6_l3vpn_test.sh
TEST_PROGS += srv6_hencap_red_l3vpn_test.sh
TEST_PROGS += srv6_hl2encap_red_l2vpn_test.sh
TEST_PROGS += srv6_end_next_csid_l3vpn_test.sh
TEST_PROGS += srv6_end_x_next_csid_l3vpn_test.sh
TEST_PROGS += srv6_end_flavors_test.sh
TEST_PROGS += vrf_strict_mode_test.sh
TEST_PROGS += arp_ndisc_evict_nocarrier.sh
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment