[v2] app/test-pmd: fix tcp/udp cksum with padding data
Checks
Commit Message
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. Testpmd does not trim these IP packets to the true
length of the frame, so errors will occur when calculating TCP
or UDP checksum.
This commit fixes this issue by triming IP packets to the true
length of the frame in testpmd.
Fixes: 03d17e4d0179 ("app/testpmd: do not change IP addrs in checksum engine")
Cc: stable@dpdk.org
Signed-off-by: Kaiwen Deng <kaiwenx.deng@intel.com>
---
app/test-pmd/csumonly.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
Comments
On 12/7/2023 8:53 AM, Kaiwen Deng wrote:
> 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. Testpmd does not trim these IP packets to the true
> length of the frame, so errors will occur when calculating TCP
> or UDP checksum.
>
> This commit fixes this issue by triming IP packets to the true
> length of the frame in testpmd.
>
> Fixes: 03d17e4d0179 ("app/testpmd: do not change IP addrs in checksum engine")
> Cc: stable@dpdk.org
>
> Signed-off-by: Kaiwen Deng <kaiwenx.deng@intel.com>
>
I think decision was to fix 'rte_ipv4_udptcp_cksum_mbuf()' &
'rte_ipv6_udptcp_cksum_mbuf()'.
@@ -860,12 +860,14 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
uint16_t nb_rx;
uint16_t nb_prep;
uint16_t i;
+ uint16_t pad_len;
uint64_t rx_ol_flags, tx_ol_flags;
uint64_t tx_offloads;
uint32_t rx_bad_ip_csum;
uint32_t rx_bad_l4_csum;
uint32_t rx_bad_outer_l4_csum;
uint32_t rx_bad_outer_ip_csum;
+ uint32_t l3_off;
struct testpmd_offload_info info;
/* receive a burst of packet */
@@ -987,6 +989,36 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
l3_hdr = (char *)l3_hdr + info.outer_l3_len + info.l2_len;
}
+ if (info.is_tunnel) {
+ l3_off = info.outer_l2_len +
+ info.outer_l3_len +
+ info.l2_len;
+ } else {
+ l3_off = info.l2_len;
+ }
+ switch (info.ethertype) {
+ case _htons(RTE_ETHER_TYPE_IPV4):
+ pad_len = rte_pktmbuf_data_len(m) -
+ (l3_off +
+ rte_be_to_cpu_16(
+ ((struct rte_ipv4_hdr *)l3_hdr)->total_length));
+ break;
+ case _htons(RTE_ETHER_TYPE_IPV6):
+ pad_len = rte_pktmbuf_data_len(m) -
+ (l3_off + info.l3_len +
+ rte_be_to_cpu_16(
+ ((struct rte_ipv6_hdr *)l3_hdr)->payload_len));
+ break;
+ default:
+ pad_len = 0;
+ break;
+ }
+
+ if (pad_len) {
+ rte_pktmbuf_data_len(m) = rte_pktmbuf_data_len(m) - pad_len;
+ rte_pktmbuf_pkt_len(m) = rte_pktmbuf_data_len(m);
+ }
+
/* step 2: depending on user command line configuration,
* recompute checksum either in software or flag the
* mbuf to offload the calculation to the NIC. If TSO