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

Eric Dumazet
2026-04-03T07:20:25Z

On Thu, Apr 2, 2026 at 11:41 PM Eric Dumazet <edumazet@google.com> wrote:
>
> 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()

I could be wrong though, vlan_features_check() is about skbs with
multiple vlan tags,
and net/core/tso.c should support them just fine.