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

Eric Dumazet
2026-04-03T04:32:41Z

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;
+}
+EXPORT_SYMBOL(tso_features_check);
--
2.53.0.1213.gd9a14994de-goog