From: netdev-bot+sashiko@kernel.org
To: daniel.zahka@gmail.com
Cc: alexanderduyck@fb.com, kuba@kernel.org, kernel-team@meta.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@kernel.org,
pabeni@redhat.com, dimitri.daskalakis1@gmail.com,
mohsin.bashr@gmail.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v2 3/6] eth: mpnic: TCP segmentation offload
Date: Thu, 12 Nov 2026 10:08:55 +0000 [thread overview]
Message-ID: <179447813579.2199510.17629296645152623901@kernel.org> (raw)
In-Reply-To: <20261110-mpnic-lso-v2-3-ccd37b051d08@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 2 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] At this commit, mpnic_xmit_frame_ring()
(drivers/net/ethernet/meta/mpnic/mpnic_txrx.c:306) calls…
- [Medium] eth: mpnic: GSO validation bypass in mpnic_features_check()
--
eth: mpnic: TCP segmentation offload
This adds hardware segmentation for non-encapsulated TCPv4/TCPv6 packets
to the mpnic driver. It also programs the TOF mode and TCP flag clear
registers, and reports hw_gso_wire_packets through the netdev qstats API.
> diff --git a/drivers/net/ethernet/meta/mpnic/mpnic_txrx.c b/drivers/net/ethernet/meta/mpnic/mpnic_txrx.c
> index a35ce8998409d..b78f8599bbe8f 100644
> --- a/drivers/net/ethernet/meta/mpnic/mpnic_txrx.c
> +++ b/drivers/net/ethernet/meta/mpnic/mpnic_txrx.c
[ ... ]
> @@ -312,6 +368,10 @@ netdev_features_t mpnic_features_check(struct sk_buff *skb,
> l2len + i3len + sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE > 256)
> return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
>
> + if (skb_is_gso(skb) &&
> + !FIELD_FIT(MPNIC_TWD_MSS, skb_shinfo(skb)->gso_size))
> + return features & ~NETIF_F_GSO_MASK;
> +
> return features;
> }
[Severity: Medium]
Does this MSS check cover every GSO skb that reaches mpnic_tx_lso()?
Earlier in mpnic_features_check() there is an early return when
skb->ip_summed != CHECKSUM_PARTIAL. For those skbs, neither the header
geometry checks above nor the new gso_size check run, and NETIF_F_TSO
and NETIF_F_TSO6 stay set.
Those skbs can still end up offloaded. __virtio_net_hdr_to_skb()
accepts VIRTIO_NET_HDR_GSO_TCPV4/TCPV6 without
VIRTIO_NET_HDR_F_NEEDS_CSUM. So a tap or virtio guest, or a
PACKET_VNET_HDR sender, can hand us a GSO skb with CHECKSUM_NONE and
SKB_GSO_DODGY.
The path from there looks like this:
- validate_xmit_skb() sees netif_needs_gso() and calls
skb_gso_segment().
- tcp4_gso_segment() or tcp6_gso_segment() seeds the pseudo-header
checksum and switches ip_summed to CHECKSUM_PARTIAL.
- tcp_gso_segment() then returns NULL, because skb_gso_ok() is still
true for the advertised features.
The original skb then goes to mpnic_xmit_frame() unsegmented, having
skipped every check in this function.
In mpnic_tx_lso(), shinfo->gso_size then goes into the 14-bit
MPNIC_TWD_MSS field unchecked. gso_features_check() only bounds
gso_segs and skb->len. A gso_size of 16384 with a total length under
64K therefore gets through, and FIELD_PREP() truncates it to an MSS
of 0.
The header lengths that mpnic_tx_offloads() writes into
MPNIC_TWD_L2_HLEN and MPNIC_TWD_L3_IHLEN are also unvalidated for
these skbs. The same goes for the even-length and 256 byte header
limits. Here the transport header was set by the flow dissector, not
by a trusted stack.
What does the hardware do with an MSS of 0, or with truncated header
lengths? At best it seems to put malformed segments on the wire.
I see two possible fixes, and I'm not sure which you'd prefer:
- Clear NETIF_F_GSO_MASK for GSO skbs that are not CHECKSUM_PARTIAL
yet.
- Move the gso_size check above the early return, and validate the
headers from skb_transport_header() in that case.
Either way, this patch is the one that turns TSO on, so the fix
probably belongs here.
[Severity: Medium]
Can a TCP GSO skb shorter than MPNIC_MIN_FRAME_LEN get to hardware LSO
here? The only GSO fallback in this check is for a gso_size that doesn't
fit MPNIC_TWD_MSS. Eth + IPv4 + TCP headers add up to 54 bytes, so a TCPv4
GSO skb can be 56 bytes long with gso_size 1 and gso_segs 2.
mpnic_xmit_frame_ring() pads every skb before the offloads are set up:
if (skb_put_padto(skb, MPNIC_MIN_FRAME_LEN))
goto err_drop;
That puts the zero pad inside the buffer lengths that mpnic_tx_map()
programs. Will the LSO engine then segment the pad as TCP payload? That
would produce more wire segments than shinfo->gso_segs, carrying zero
bytes at sequence numbers past the real data.
The checksum seed also looks wrong for these skbs. mpnic_tx_lso() takes
the length out of the pseudo-header using the padded skb->len:
payload_len = cpu_to_be16(skb->len - skb_checksum_start_offset(skb));
csum_replace_by_diff(&tcph->check, (__force __wsum)payload_len);
The sender, or tcp4_gro_complete(), seeded tcph->check with the unpadded
L4 length. So the seed ends up off by the pad size. Won't every segment
the hardware generates then carry a bad TCP checksum?
One way to reach this is a remote peer sending back-to-back non-PSH
1-byte segments. A forwarding host GRO-merges them and sends them out an
mpnic port. tun/tap/virtio and PACKET_VNET_HDR sources can also build
such skbs.
Now that NETIF_F_TSO is advertised, these skbs reach the driver
unsegmented. Before this patch GSO was never offloaded, so the padding
did no harm.
The next patch in the series, "eth: mpnic: UDP segmentation offload",
adds skb->len < MPNIC_MIN_FRAME_LEN to this condition. Could that check
move into this patch, so this commit doesn't send bad segments on its own?
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261110-mpnic-lso-v2-0-ccd37b051d08%40gmail.com
next prev parent reply other threads:[~2026-11-12 10:08 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 22:06 [PATCH net-next v2 0/6] eth: mpnic: checksum and segmentation offloads Daniel Zahka
2026-11-10 22:06 ` [PATCH net-next v2 1/6] eth: mpnic: Tx checksum offload Daniel Zahka
2026-11-12 10:08 ` netdev-bot+sashiko
2026-11-10 22:06 ` [PATCH net-next v2 2/6] eth: mpnic: Rx " Daniel Zahka
2026-11-10 22:06 ` [PATCH net-next v2 3/6] eth: mpnic: TCP segmentation offload Daniel Zahka
2026-11-12 10:08 ` netdev-bot+sashiko [this message]
2026-11-10 22:06 ` [PATCH net-next v2 4/6] eth: mpnic: UDP " Daniel Zahka
2026-11-12 10:08 ` netdev-bot+sashiko
2026-11-10 22:06 ` [PATCH net-next v2 5/6] eth: mpnic: IPv4 and IPv6 in IPv6 tunnel segmentation Daniel Zahka
2026-11-12 10:08 ` netdev-bot+sashiko
2026-11-10 22:06 ` [PATCH net-next v2 6/6] eth: mpnic: add GSO_PARTIAL for other tunnels Daniel Zahka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=179447813579.2199510.17629296645152623901@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=alexanderduyck@fb.com \
--cc=andrew+netdev@lunn.ch \
--cc=daniel.zahka@gmail.com \
--cc=davem@davemloft.net \
--cc=dimitri.daskalakis1@gmail.com \
--cc=edumazet@kernel.org \
--cc=kernel-team@meta.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mohsin.bashr@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox