[v3] lib/net: fix tcp/udp cksum with padding data

Message ID 20231212021619.2038881-1-kaiwenx.deng@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v3] lib/net: fix tcp/udp cksum with padding data |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/github-robot: build success github build: passed
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-compile-amd64-testing success Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/intel-Functional success Functional PASS

Commit Message

Kaiwen Deng Dec. 12, 2023, 2:16 a.m. UTC
  IEEE 802 packets may have a minimum size limit. The data fields
should be padded when necessary. In some cases, the padding data
is not zero.

In 'rte_ipv4_udptcp_cksum_mbuf()', as payload length
"mbuf->pkt_len - l4_off" is used, which includes padding and if
padding is not zero it will end up producing wrong checksum.

This patch will use IP header to get the payload size to calculate
tcp/udp checksum.

Fixes: d178f693bbfe ("net: add UDP/TCP checksum in mbuf segments")
Cc: stable@dpdk.org

Signed-off-by: Kaiwen Deng <kaiwenx.deng@intel.com>
---
 lib/net/rte_ip.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
  

Comments

Morten Brørup Dec. 12, 2023, 8:10 a.m. UTC | #1
> From: Kaiwen Deng [mailto:kaiwenx.deng@intel.com]
> Sent: Tuesday, 12 December 2023 03.16
> 
> IEEE 802 packets may have a minimum size limit. The data fields
> should be padded when necessary. In some cases, the padding data
> is not zero.
> 
> In 'rte_ipv4_udptcp_cksum_mbuf()', as payload length
> "mbuf->pkt_len - l4_off" is used, which includes padding and if
> padding is not zero it will end up producing wrong checksum.
> 
> This patch will use IP header to get the payload size to calculate
> tcp/udp checksum.
> 
> Fixes: d178f693bbfe ("net: add UDP/TCP checksum in mbuf segments")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Kaiwen Deng <kaiwenx.deng@intel.com>
> ---
>  lib/net/rte_ip.h | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
> index 6fa98a5a0f..c503a2b57f 100644
> --- a/lib/net/rte_ip.h
> +++ b/lib/net/rte_ip.h
> @@ -423,7 +423,10 @@ __rte_ipv4_udptcp_cksum_mbuf(const struct rte_mbuf
> *m,
>  	if (l4_off > m->pkt_len)
>  		return 0;

It's not directly related, but while you are at it, please also add unlikely to the above check:

-	if (l4_off > m->pkt_len)
-		return 0;
+	if (unlikely(l4_off > m->pkt_len))
+		return 0; /* invalid params, return a dummy value */

> 
> -	if (rte_raw_cksum_mbuf(m, l4_off, m->pkt_len - l4_off,
> &raw_cksum))
> +	uint16_t len = rte_be_to_cpu_16(ipv4_hdr->total_length) -
> +				(uint16_t)rte_ipv4_hdr_len(ipv4_hdr);
> +
> +	if (rte_raw_cksum_mbuf(m, l4_off, len, &raw_cksum))

Please declare "uint16_t len;" with the other variables at the top of the function, and only set its value here. (It's allowed to declare here, but please follow this function's existing convention of where variables are declared.)

>  		return 0;
> 
>  	cksum = raw_cksum + rte_ipv4_phdr_cksum(ipv4_hdr, 0);
> @@ -666,7 +669,9 @@ __rte_ipv6_udptcp_cksum_mbuf(const struct rte_mbuf
> *m,
>  	if (l4_off > m->pkt_len)
>  		return 0;

Again not directly related, but please also add unlikely to this comparison:

-	if (l4_off > m->pkt_len)
-		return 0;
+	if (unlikely(l4_off > m->pkt_len))
+		return 0; /* invalid params, return a dummy value */

> 
> -	if (rte_raw_cksum_mbuf(m, l4_off, m->pkt_len - l4_off,
> &raw_cksum))
> +	uint16_t len = rte_be_to_cpu_16(ipv6_hdr->payload_len);
> +
> +	if (rte_raw_cksum_mbuf(m, l4_off, len, &raw_cksum))

No need for "len" variable here, just use rte_be_to_cpu_16(ipv6_hdr->payload_len) directly:

-	if (rte_raw_cksum_mbuf(m, l4_off, m->pkt_len - l4_off, &raw_cksum))
+	if (rte_raw_cksum_mbuf(m, l4_off, rte_be_to_cpu_16(ipv6_hdr->payload_len), &raw_cksum))

>  		return 0;
> 
>  	cksum = raw_cksum + rte_ipv6_phdr_cksum(ipv6_hdr, 0);
> --
> 2.34.1
  

Patch

diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 6fa98a5a0f..c503a2b57f 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -423,7 +423,10 @@  __rte_ipv4_udptcp_cksum_mbuf(const struct rte_mbuf *m,
 	if (l4_off > m->pkt_len)
 		return 0;
 
-	if (rte_raw_cksum_mbuf(m, l4_off, m->pkt_len - l4_off, &raw_cksum))
+	uint16_t len = rte_be_to_cpu_16(ipv4_hdr->total_length) -
+				(uint16_t)rte_ipv4_hdr_len(ipv4_hdr);
+
+	if (rte_raw_cksum_mbuf(m, l4_off, len, &raw_cksum))
 		return 0;
 
 	cksum = raw_cksum + rte_ipv4_phdr_cksum(ipv4_hdr, 0);
@@ -666,7 +669,9 @@  __rte_ipv6_udptcp_cksum_mbuf(const struct rte_mbuf *m,
 	if (l4_off > m->pkt_len)
 		return 0;
 
-	if (rte_raw_cksum_mbuf(m, l4_off, m->pkt_len - l4_off, &raw_cksum))
+	uint16_t len = rte_be_to_cpu_16(ipv6_hdr->payload_len);
+
+	if (rte_raw_cksum_mbuf(m, l4_off, len, &raw_cksum))
 		return 0;
 
 	cksum = raw_cksum + rte_ipv6_phdr_cksum(ipv6_hdr, 0);