netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] bnx2x: fix header length calculation for encapsulated TSO
@ 2026-10-09 17:30 George Melikov via B4 Relay
  2026-10-15 11:22 ` Simon Horman
  0 siblings, 1 reply; 2+ messages in thread
From: George Melikov via B4 Relay @ 2026-10-09 17:30 UTC (permalink / raw)
  To: Sudarsana Kalluru, Manish Chopra, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Edward Cree
  Cc: netdev, linux-kernel, George Melikov

From: George Melikov <mail@gmelikov.ru>

Commit 80bfab79b835 ("net: adopt skb_network_offset() and similar helpers")
replaced the difference between the inner transport header and the outer
network header with skb_inner_transport_offset().
The helper is relative to skb->data, so the new calculation incorrectly
includes the outer Ethernet header in fw_ip_hdr_to_payload_w.

On a BCM57810 transmitting TCP over VXLAN with an outer MTU of 1500,
hardware segmentation emits packets declaring an outer IPv4 total length
of 1514 while the actual IP packet is only 1500 bytes long. The receiver
drops these malformed packets, severely degrading TCP connectivity.

Subtract skb_network_offset() to restore the original calculation of the
length from the outer network header to the inner TCP payload.

Reproduced with plain kernel VXLAN and one TCP flow on kernel
7.0.0-31-generic: 50 of 200 captured packets had an invalid outer IP length
with the original driver, versus none with this fix. Disabling TSO/GSO on
the test VXLAN device also eliminated the error with the original driver.

Fixes: 80bfab79b835 ("net: adopt skb_network_offset() and similar helpers")
Signed-off-by: George Melikov <mail@gmelikov.ru>
Assisted-by: LLM
---
Minimal reproducer: two physical Linux hosts and plain kernel VXLAN.
Sender: BCM57810, affected bnx2x, TCP and UDP tunnel segmentation enabled.
Receiver need not use bnx2x. Underlay MTU 1500, VXLAN MTU 1450.
Run commands in a root Bash shell.

On A:

    LOCAL=192.168.1.185 REMOTE=192.168.1.102 DEV=eno1 TEST=198.18.77.1

On B (underlay IP on br0, physical NIC eno1):

    LOCAL=192.168.1.102 REMOTE=192.168.1.185 DEV=br0 TEST=198.18.77.2

On both:

    ip netns add bnx-repro
    ip link add bnxvx type vxlan id 160009 local "$LOCAL" remote "$REMOTE" dev "$DEV" dstport 4790 nolearning
    ip link set bnxvx netns bnx-repro
    ip -n bnx-repro addr add "${TEST}/30" dev bnxvx
    ip -n bnx-repro link set lo up
    ip -n bnx-repro link set bnxvx mtu 1450 up

On A, verify TSO/GSO and TX checksumming are on for eno1 and bnxvx,
and tx-udp_tnl-segmentation is on for eno1:

    ethtool -k eno1
    ip netns exec bnx-repro ethtool -k bnxvx

On B, first terminal:

    ip netns exec bnx-repro iperf3 -s -B 198.18.77.2 -p 35219

On B, second terminal: verify rx-gro-hw and LRO are off. These commands
assume software GRO was initially on; restore it after capture, including
if interrupted. If initially off, leave it off.

    ethtool -k eno1
    ethtool -K eno1 gro off
    timeout --signal=INT 30 tcpdump -U -ni eno1 -s 0 -c 200 \
        -w /tmp/bnx2x-repro.pcap \
        'ip and udp dst port 4790 and src host 192.168.1.185'
    ethtool -K eno1 gro on

Once tcpdump reports "listening on eno1", run on A:

    timeout 12 ip netns exec bnx-repro iperf3 -c 198.18.77.2 -p 35219 -t 3 -P 1 -J

Read the capture on B:

    tcpdump -T vxlan -nn -vv -r /tmp/bnx2x-repro.pcap

Malformed outer IP length, depending on tcpdump version:

    4.99.4: IP truncated-ip - 14 bytes missing! (... length 1514)
    4.99.6: IP [total length 1514 > length 1500] (invalid)

The complete frame contains only 1500 IP bytes; the header declares 1514.

Control: on A, disable TSO/GSO on the test device; repeat capture with a
new filename and rerun the client. Restore both flags afterwards:

    ip netns exec bnx-repro ethtool -K bnxvx tso off gso off
    # Repeat capture and client, then:
    ip netns exec bnx-repro ethtool -K bnxvx tso on gso on

Observed on 7.0.0-31-generic/BCM57810: original hardware TSO 50/200 bad
packets, software segmentation 0/200, fixed hardware TSO 0/200.
Counts may vary. These short runs are functional checks, not benchmarks.

Cleanup: stop iperf3, then on both hosts:

ip netns del bnx-repro
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 5a9742fd3..6fb061973 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3666,7 +3666,8 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
 	u8 outerip_off, outerip_len = 0;
 
 	/* from outer IP to transport */
-	hlen_w = skb_inner_transport_offset(skb) >> 1;
+	hlen_w = (skb_inner_transport_offset(skb) -
+		  skb_network_offset(skb)) >> 1;
 
 	/* transport len */
 	hlen_w += inner_tcp_hdrlen(skb) >> 1;

---
base-commit: af32da41b0327b9c6a37856ba82b6760d6c8d10e
change-id: 20261009-bnx2x-tso-fix-71248eedded4

Best regards,
--  
George Melikov <mail@gmelikov.ru>



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net] bnx2x: fix header length calculation for encapsulated TSO
  2026-10-09 17:30 [PATCH net] bnx2x: fix header length calculation for encapsulated TSO George Melikov via B4 Relay
@ 2026-10-15 11:22 ` Simon Horman
  0 siblings, 0 replies; 2+ messages in thread
From: Simon Horman @ 2026-10-15 11:22 UTC (permalink / raw)
  To: mail
  Cc: Sudarsana Kalluru, Manish Chopra, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Edward Cree, netdev,
	linux-kernel

On Fri, Oct 09, 2026 at 08:30:18PM +0300, George Melikov via B4 Relay wrote:
> From: George Melikov <mail@gmelikov.ru>
> 
> Commit 80bfab79b835 ("net: adopt skb_network_offset() and similar helpers")
> replaced the difference between the inner transport header and the outer
> network header with skb_inner_transport_offset().
> The helper is relative to skb->data, so the new calculation incorrectly
> includes the outer Ethernet header in fw_ip_hdr_to_payload_w.
> 
> On a BCM57810 transmitting TCP over VXLAN with an outer MTU of 1500,
> hardware segmentation emits packets declaring an outer IPv4 total length
> of 1514 while the actual IP packet is only 1500 bytes long. The receiver
> drops these malformed packets, severely degrading TCP connectivity.
> 
> Subtract skb_network_offset() to restore the original calculation of the
> length from the outer network header to the inner TCP payload.
> 
> Reproduced with plain kernel VXLAN and one TCP flow on kernel
> 7.0.0-31-generic: 50 of 200 captured packets had an invalid outer IP length
> with the original driver, versus none with this fix. Disabling TSO/GSO on
> the test VXLAN device also eliminated the error with the original driver.
> 
> Fixes: 80bfab79b835 ("net: adopt skb_network_offset() and similar helpers")
> Signed-off-by: George Melikov <mail@gmelikov.ru>
> Assisted-by: LLM

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-15 11:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09 17:30 [PATCH net] bnx2x: fix header length calculation for encapsulated TSO George Melikov via B4 Relay
2026-10-15 11:22 ` Simon Horman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).