Commit e609c959 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Paolo Abeni

net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size

Commit 24ab059d ("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: 24ab059d ("net: check dev->gso_max_size in gso_features_check()")
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20240923212242.15669-2-daniel@iogearbox.netSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent e8d4d34d
...@@ -5038,6 +5038,15 @@ netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb) ...@@ -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); 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) static inline bool netif_is_macsec(const struct net_device *dev)
{ {
return dev->priv_flags & IFF_MACSEC; return dev->priv_flags & IFF_MACSEC;
......
...@@ -3512,7 +3512,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb, ...@@ -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)) if (gso_segs > READ_ONCE(dev->gso_max_segs))
return features & ~NETIF_F_GSO_MASK; 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; return features & ~NETIF_F_GSO_MASK;
if (!skb_shinfo(skb)->gso_type) { if (!skb_shinfo(skb)->gso_type) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment