Re: [PATCH net-next 1/9] net: tso: add tso_features_check()

Eric Dumazet
2026-04-03T06:41:48Z

On Thu, Apr 2, 2026 at 9:32 PM Eric Dumazet <edumazet@google.com> wrote:
>
> net/core/tso.c users expecting headers size is smaller
> than TSO_HEADER_SIZE must fallback to GSO when headers
> are too big.
>
> Provide tso_features_check() for drivers .ndo_features_check().
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> include/net/tso.h | 11 +++++++++++
> net/core/tso.c | 12 ++++++++++++
> 2 files changed, 23 insertions(+)
>
> diff --git a/include/net/tso.h b/include/net/tso.h
> index e7e157ae0526c8d655aca67a8a49191ec870746b..9be7cb6553975a2a82e0987214fee6883bf74404 100644
> --- a/include/net/tso.h
> +++ b/include/net/tso.h
> @@ -28,4 +28,15 @@ void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
> void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size);
> int tso_start(struct sk_buff *skb, struct tso_t *tso);
>
> +static inline int tso_compute_hdr_len(const struct sk_buff *skb)
> +{
> + int tlen = skb_is_gso_tcp(skb) ? tcp_hdrlen(skb) : sizeof(struct udphdr);
> + int hdr_len = skb_transport_offset(skb) + tlen;
> +
> + return hdr_len;
> +}
> +
> +netdev_features_t tso_features_check(struct sk_buff *skb,
> + struct net_device *dev,
> + netdev_features_t features);
> #endif /* _TSO_H */
> diff --git a/net/core/tso.c b/net/core/tso.c
> index 6df997b9076e9842f3de7bb3e34599d8ff4e4fd4..81e2cc66d0dd29eeb647232e04032b1412382a6f 100644
> --- a/net/core/tso.c
> +++ b/net/core/tso.c
> @@ -87,3 +87,15 @@ int tso_start(struct sk_buff *skb, struct tso_t *tso)
> return hdr_len;
> }
> EXPORT_SYMBOL(tso_start);
> +
> +netdev_features_t tso_features_check(struct sk_buff *skb,
> + struct net_device *dev,
> + netdev_features_t features)
> +{
> + if (skb_is_gso(skb)) {
> + if (tso_compute_hdr_len(skb) > TSO_HEADER_SIZE)
> + features &= ~NETIF_F_GSO_MASK;
> + }
> + return features;

I forgot that netif_skb_features() uses:

if (dev->netdev_ops->ndo_features_check)
features &= dev->netdev_ops->ndo_features_check(skb, dev,
features);
else
features &= dflt_features_check(skb, dev, features);

So I need to call vlan_features_check() from tso_features_check()

pw-bot: cr