[PATCH] net: fix cksum calculation for odd-sized segment

Eva Kurchatova eva.kurchatova at virtuozzo.com
Thu Aug 13 22:22:35 CEST 2026


The rte_raw_cksum_mbuf() performs rte_bswap16() on return value from
__rte_raw_cksum() for odd-sized segments. However, __rte_raw_cksum()
returns a 32-bit accumulator whose upper 16 bits may still contain
carries that must be folded. Truncating those upper bits by passing to
rte_bswap16() will produce an invalid checksum if they are non-zero.

This is surely a rare encounter in practice, as most NICs have hardware
checksum offloads, and even then encountering an odd-sized SG segment
is not common, but currently such a case would miscompute the checksum.

I found this issue by accident when comparing RVVM networking stack
packet checksuming to DPDK, and noticed that this looked incorrect.

Fix this by folding the odd-sized segment checksum before bswap16.

Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
---
 lib/net/rte_cksum.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/net/rte_cksum.h b/lib/net/rte_cksum.h
index a8e8927952..391f998ee5 100644
--- a/lib/net/rte_cksum.h
+++ b/lib/net/rte_cksum.h
@@ -157,7 +157,7 @@ rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len,
 	for (;;) {
 		tmp = __rte_raw_cksum(buf, seglen, 0);
 		if (done & 1)
-			tmp = rte_bswap16((uint16_t)tmp);
+			tmp = rte_bswap16(__rte_raw_cksum_reduce(tmp));
 		sum += tmp;
 		done += seglen;
 		if (done == len)
-- 
2.55.0



More information about the dev mailing list