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

Eva Kurchatova <[email protected]>
Newsgroups org.dpdk.dev
Message-ID <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.