Re: [PATCH net v3 1/4] net/mlx5e: psp: tso: replace only the length in checksum seed
From: Daniel Zahka
Date: Tue Oct 27 2026 - 11:39:52 EST
On Fri Oct 23, 2026 at 7:46 PM EDT, Todd Freed wrote:
> for psp tcp with tso,
>
> - __tcp_transmit_skb() -> tcp_v6_send_check() or tcp_v4_send_check()
> computes the checksum seed using the addresses on the socket and the
> total length, then
>
> - mlx5e_psp_handle_tx_skb() recomputes the checksum seed using
> addresses from the packet's l3 header, and the length of one segment
>
> the length difference is expected by the device. however, the
> difference in addresses is incorrect in cases where the l3 header daddr
> is an intermediate hop (e.g. IPV6_RTHDR). this causes every segment of
> the tso packet to go out with a bad tcp checksum, in this case.
>
> the fix is to replace only the length in the seed which tcp had already
> computed. this is also what tcp_gso_segment() does.
>
> tested on connectx-7 with the rest of this series applied, with a psp
> tcp socket whose segment routing header's first hop isn't the final
> destination, and the peer checking tcp checksums in software.
>
> Fixes: e5a1861a298e ("net/mlx5e: Implement PSP Tx data path")
> Signed-off-by: Todd Freed <toddfreed@xxxxxxxx>
> ---
> .../mellanox/mlx5/core/en_accel/psp_rxtx.c | 21 ++++++++-----------
> 1 file changed, 9 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
> index 348fd7a96261..d9c2742b3c24 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
> @@ -177,18 +177,15 @@ bool mlx5e_psp_handle_tx_skb(struct net_device *netdev,
> return false;
> }
> if (skb_is_gso(skb)) {
> - int len = skb_shinfo(skb)->gso_size + inner_tcp_hdrlen(skb);
> - struct tcphdr *th = inner_tcp_hdr(skb);
> -
> - if (skb->protocol == htons(ETH_P_IP)) {
> - const struct iphdr *ip = ip_hdr(skb);
> -
> - th->check = ~tcp_v4_check(len, ip->saddr, ip->daddr, 0);
> - } else {
> - const struct ipv6hdr *ip6 = ipv6_hdr(skb);
> -
> - th->check = ~tcp_v6_check(len, &ip6->saddr, &ip6->daddr, 0);
> - }
> + u32 seg_len = skb_shinfo(skb)->gso_size + inner_tcp_hdrlen(skb);
> + u32 len = skb->len - skb_inner_transport_offset(skb);
> +
> + /* update just the length component of the checksum seed
> + * tcp computed the seed with the total length, but mlx5
> + * devices are expecting the segment length
> + */
> + inet_proto_csum_replace4(&inner_tcp_hdr(skb)->check, skb,
> + htonl(len), htonl(seg_len), true);
> }
>
> return true;
Thanks. Makes sense to me. The bot has a mega nit about the commit
message that may be worth addressing next version, but otherwise:
Acked-by: Daniel Zahka <daniel.zahka@xxxxxxxxx>