net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size
authorDaniel Borkmann <daniel@iogearbox.net>
Mon, 23 Sep 2024 21:22:42 +0000 (23:22 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 1 Oct 2024 08:48:52 +0000 (10:48 +0200)
Commit 24ab059d2ebd ("net: check dev->gso_max_size in gso_features_check()")
added a dev->gso_max_size test to gso_features_check() in order to fall
back to GSO when needed.

This was added as it was noticed that some drivers could misbehave if TSO
packets get too big. However, the check doesn't respect dev->gso_ipv4_max_size
limit. For instance, a device could be configured with BIG TCP for IPv4,
but not IPv6.

Therefore, add a netif_get_gso_max_size() equivalent to netif_get_gro_max_size()
and use the helper to respect both limits before falling back to GSO engine.

Fixes: 24ab059d2ebd ("net: check dev->gso_max_size in gso_features_check()")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20240923212242.15669-2-daniel@iogearbox.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/linux/netdevice.h
net/core/dev.c

index d571451638de45077381259783c006b572fbcec1..4d20c776a4ff3d0e881b8d9b99901edb35f66da2 100644 (file)
@@ -5038,6 +5038,15 @@ netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb)
               READ_ONCE(dev->gro_ipv4_max_size);
 }
 
+static inline unsigned int
+netif_get_gso_max_size(const struct net_device *dev, const struct sk_buff *skb)
+{
+       /* pairs with WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
+       return skb->protocol == htons(ETH_P_IPV6) ?
+              READ_ONCE(dev->gso_max_size) :
+              READ_ONCE(dev->gso_ipv4_max_size);
+}
+
 static inline bool netif_is_macsec(const struct net_device *dev)
 {
        return dev->priv_flags & IFF_MACSEC;
index cd479f5f22f61c316cb236632eea73d5924c3156..74cf78a6b512bb1ed1ce3e46a06a2f4eaa222fec 100644 (file)
@@ -3512,7 +3512,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
        if (gso_segs > READ_ONCE(dev->gso_max_segs))
                return features & ~NETIF_F_GSO_MASK;
 
-       if (unlikely(skb->len >= READ_ONCE(dev->gso_max_size)))
+       if (unlikely(skb->len >= netif_get_gso_max_size(dev, skb)))
                return features & ~NETIF_F_GSO_MASK;
 
        if (!skb_shinfo(skb)->gso_type) {