[PATCH net] selftests: net: Fix checksums in xdp_native

Nimrod Oren posted 1 patch 1 month ago
There is a newer version of this series
.../selftests/net/lib/xdp_native.bpf.c        | 54 ++++++++++---------
1 file changed, 29 insertions(+), 25 deletions(-)
[PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Nimrod Oren 1 month ago
Data adjustment cases failed with "Data exchange failed" when using IPv4
because the program did not update the IP and UDP checksums in the IPv4
branch. The issue was masked when both IPv4 and IPv6 were configured,
since the test harness prefers IPv6.

Fixes: 0b65cfcef9c5 ("selftests: drv-net: Test tail-adjustment support")
Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Nimrod Oren <noren@nvidia.com>
---
 .../selftests/net/lib/xdp_native.bpf.c        | 54 ++++++++++---------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/tools/testing/selftests/net/lib/xdp_native.bpf.c b/tools/testing/selftests/net/lib/xdp_native.bpf.c
index 64f05229ab24..eaecfa58b967 100644
--- a/tools/testing/selftests/net/lib/xdp_native.bpf.c
+++ b/tools/testing/selftests/net/lib/xdp_native.bpf.c
@@ -268,6 +268,16 @@ static int xdp_mode_tx_handler(struct xdp_md *ctx, __u16 port)
 	return XDP_PASS;
 }
 
+static __always_inline __u16 csum_fold_helper(__u32 csum)
+{
+	return ~((csum & 0xffff) + (csum >> 16));
+}
+
+static __always_inline __u16 csum_fold_udp_helper(__u32 csum)
+{
+	return csum_fold_helper(csum) ? : 0xffff;
+}
+
 static void *update_pkt(struct xdp_md *ctx, __s16 offset, __u32 *udp_csum)
 {
 	void *data_end = (void *)(long)ctx->data_end;
@@ -281,21 +291,22 @@ static void *update_pkt(struct xdp_md *ctx, __s16 offset, __u32 *udp_csum)
 
 	if (eth->h_proto == bpf_htons(ETH_P_IP)) {
 		struct iphdr *iph = data + sizeof(*eth);
-		__u16 total_len;
 
 		if (iph + 1 > (struct iphdr *)data_end)
 			return NULL;
 
-		iph->tot_len = bpf_htons(bpf_ntohs(iph->tot_len) + offset);
-
 		udph = (void *)eth + sizeof(*iph) + sizeof(*eth);
 		if (!udph || udph + 1 > (struct udphdr *)data_end)
 			return NULL;
 
-		len_new = bpf_htons(bpf_ntohs(udph->len) + offset);
+		len = iph->tot_len;
+		len_new = bpf_htons(bpf_ntohs(len) + offset);
+		iph->tot_len = len_new;
+		iph->check = csum_fold_helper(
+			bpf_csum_diff(&len, sizeof(len), &len_new,
+				      sizeof(len_new), ~((__u32)iph->check)));
 	} else if (eth->h_proto  == bpf_htons(ETH_P_IPV6)) {
 		struct ipv6hdr *ipv6h = data + sizeof(*eth);
-		__u16 payload_len;
 
 		if (ipv6h + 1 > (struct ipv6hdr *)data_end)
 			return NULL;
@@ -304,33 +315,27 @@ static void *update_pkt(struct xdp_md *ctx, __s16 offset, __u32 *udp_csum)
 		if (!udph || udph + 1 > (struct udphdr *)data_end)
 			return NULL;
 
-		*udp_csum = ~((__u32)udph->check);
-
 		len = ipv6h->payload_len;
 		len_new = bpf_htons(bpf_ntohs(len) + offset);
 		ipv6h->payload_len = len_new;
-
-		*udp_csum = bpf_csum_diff(&len, sizeof(len), &len_new,
-					  sizeof(len_new), *udp_csum);
-
-		len = udph->len;
-		len_new = bpf_htons(bpf_ntohs(udph->len) + offset);
-		*udp_csum = bpf_csum_diff(&len, sizeof(len), &len_new,
-					  sizeof(len_new), *udp_csum);
 	} else {
 		return NULL;
 	}
 
+	len = udph->len;
+	len_new = bpf_htons(bpf_ntohs(len) + offset);
+
+	*udp_csum = ~((__u32)udph->check);
+	*udp_csum = bpf_csum_diff(&len, sizeof(len), &len_new,
+				  sizeof(len_new), *udp_csum);
+	*udp_csum = bpf_csum_diff(&len, sizeof(len), &len_new,
+				  sizeof(len_new), *udp_csum);
+
 	udph->len = len_new;
 
 	return udph;
 }
 
-static __u16 csum_fold_helper(__u32 csum)
-{
-	return ~((csum & 0xffff) + (csum >> 16)) ? : 0xffff;
-}
-
 static int xdp_adjst_tail_shrnk_data(struct xdp_md *ctx, __u16 offset,
 				     unsigned long hdr_len)
 {
@@ -359,7 +364,7 @@ static int xdp_adjst_tail_shrnk_data(struct xdp_md *ctx, __u16 offset,
 		return -1;
 
 	udp_csum = bpf_csum_diff((__be32 *)tmp_buff, offset, 0, 0, udp_csum);
-	udph->check = (__u16)csum_fold_helper(udp_csum);
+	udph->check = (__u16)csum_fold_udp_helper(udp_csum);
 
 	if (bpf_xdp_adjust_tail(ctx, 0 - offset) < 0)
 		return -1;
@@ -403,7 +408,7 @@ static int xdp_adjst_tail_grow_data(struct xdp_md *ctx, __u16 offset)
 		return -1;
 
 	udp_csum = bpf_csum_diff(0, 0, (__be32 *)tmp_buff, offset, udp_csum);
-	udph->check = (__u16)csum_fold_helper(udp_csum);
+	udph->check = (__u16)csum_fold_udp_helper(udp_csum);
 
 	buff_len = bpf_xdp_get_buff_len(ctx);
 
@@ -484,8 +489,7 @@ static int xdp_adjst_head_shrnk_data(struct xdp_md *ctx, __u64 hdr_len,
 		return -1;
 
 	udp_csum = bpf_csum_diff((__be32 *)tmp_buff, offset, 0, 0, udp_csum);
-
-	udph->check = (__u16)csum_fold_helper(udp_csum);
+	udph->check = (__u16)csum_fold_udp_helper(udp_csum);
 
 	if (bpf_xdp_load_bytes(ctx, 0, tmp_buff, MAX_ADJST_OFFSET) < 0)
 		return -1;
@@ -542,7 +546,7 @@ static int xdp_adjst_head_grow_data(struct xdp_md *ctx, __u64 hdr_len,
 		return -1;
 
 	udp_csum = bpf_csum_diff(0, 0, (__be32 *)data_buff, offset, udp_csum);
-	udph->check = (__u16)csum_fold_helper(udp_csum);
+	udph->check = (__u16)csum_fold_udp_helper(udp_csum);
 
 	if (hdr_len > MAX_ADJST_OFFSET || hdr_len == 0)
 		return -1;
-- 
2.45.0
Re: [PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Jakub Kicinski 4 weeks ago
On Wed, 13 May 2026 10:23:55 +0300 Nimrod Oren wrote:
> Data adjustment cases failed with "Data exchange failed" when using IPv4
> because the program did not update the IP and UDP checksums in the IPv4
> branch. The issue was masked when both IPv4 and IPv6 were configured,
> since the test harness prefers IPv6.

Oops, maybe we should run against both IP version after all?
Re: [PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Nimrod Oren 3 weeks, 5 days ago

On 15/05/2026 4:38, Jakub Kicinski wrote:
> On Wed, 13 May 2026 10:23:55 +0300 Nimrod Oren wrote:
>> Data adjustment cases failed with "Data exchange failed" when using IPv4
>> because the program did not update the IP and UDP checksums in the IPv4
>> branch. The issue was masked when both IPv4 and IPv6 were configured,
>> since the test harness prefers IPv6.
> 
> Oops, maybe we should run against both IP version after all?

I can send a follow-up to run all xdp.py cases against both IP versions
when both are configured. Or are you suggesting this as a broader change
for all drivers/net/*.py selftests?
Re: [PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Jakub Kicinski 3 weeks, 3 days ago
On Sun, 17 May 2026 14:27:15 +0300 Nimrod Oren wrote:
> On 15/05/2026 4:38, Jakub Kicinski wrote:
> > On Wed, 13 May 2026 10:23:55 +0300 Nimrod Oren wrote:  
> >> Data adjustment cases failed with "Data exchange failed" when using IPv4
> >> because the program did not update the IP and UDP checksums in the IPv4
> >> branch. The issue was masked when both IPv4 and IPv6 were configured,
> >> since the test harness prefers IPv6.  
> > 
> > Oops, maybe we should run against both IP version after all?  
> 
> I can send a follow-up to run all xdp.py cases against both IP versions
> when both are configured.

Follow up sounds good. This patch needs a respin for the issues
Sashiko pointed out, to be clear.

> Or are you suggesting this as a broader change for all
> drivers/net/*.py selftests?

Just XDP
Re: [PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Nimrod Oren 3 weeks, 3 days ago
On 19/05/2026 0:31, Jakub Kicinski wrote:
> This patch needs a respin for the issues Sashiko pointed out, to be 
> clear.
Replied to Sashiko earlier (my reply went to sashiko-reviews and bpf
but not netdev - oops).

All issues are pre-existing and harmless, so I don't think they should
be addressed in a net fix.
Re: [PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Jakub Kicinski 3 weeks, 2 days ago
On Tue, 19 May 2026 10:04:03 +0300 Nimrod Oren wrote:
> On 19/05/2026 0:31, Jakub Kicinski wrote:
> > This patch needs a respin for the issues Sashiko pointed out, to be 
> > clear.  
> Replied to Sashiko earlier (my reply went to sashiko-reviews and bpf
> but not netdev - oops).

Yeah, it's a bit buggy in how it collects the CCs.

> All issues are pre-existing and harmless, so I don't think they should
> be addressed in a net fix.

Please fix the csum thing.
Re: [PATCH net] selftests: net: Fix checksums in xdp_native
Posted by Jakub Kicinski 3 weeks, 2 days ago
On Tue, 19 May 2026 16:26:51 -0700 Jakub Kicinski wrote:
> > All issues are pre-existing and harmless, so I don't think they should
> > be addressed in a net fix.  
> 
> Please fix the csum thing.

Well, that's not very accurate. I mean carrying the overflow.
It's trivial.