Wang Zhan wrote:
> gso_features_check() compares the frame length against
> netif_get_gso_max_size(), which picks the IPv4 or the IPv6 limit from
> skb->protocol. A tag which is already inside the frame replaces that field
> with the VLAN ethertype, as skb_vlan_push() does, and an IPv6 packet is
> then measured against the IPv4 limit and segmented although the device
> could send it as one TSO frame.
>
> Let the limit lookup take the protocol as an argument, and pass the L3
> protocol, so where the tag sits does not decide which limit applies. The
> helper cannot look behind the tag itself: it lives in netdevice.h, which
> cannot include if_vlan.h because that header includes netdevice.h.
>
> Fixes: e609c959a9396 ("net: Fix gso_features_check to check for both
> dev->gso_{ipv4_,}max_size")
> Assisted-by: LLM
> Signed-off-by: Wang Zhan <[email protected]>
>
> ---
> v3:
> - new patch: the L3 protocol fix split out of the resegmentation patch
> v2: https://lore.kernel.org/[email protected]/
> v1: https://lore.kernel.org/[email protected]/
> ---
> include/linux/netdevice.h | 4 ++--
> net/core/dev.c | 3 ++-
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index d037faff7c44b..1c28861fcbe2c 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -5562,10 +5562,10 @@ netif_get_gro_max_size(const struct net_device *dev,
> const struct sk_buff *skb)
> }
>
> static inline unsigned int
> -netif_get_gso_max_size(const struct net_device *dev, const struct sk_buff
> *skb)
> +netif_get_gso_max_size(const struct net_device *dev, __be16 protocol)
> {
> /* pairs with WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
> - return skb->protocol == htons(ETH_P_IPV6) ?
> + return protocol == htons(ETH_P_IPV6) ?
> READ_ONCE(dev->gso_max_size) :
> READ_ONCE(dev->gso_ipv4_max_size);
> }
> diff --git a/net/core/dev.c b/net/core/dev.c
> index f660fccfc0dbc..ffa9b0c27788c 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3843,7 +3843,8 @@ 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 >= netif_get_gso_max_size(dev, skb)))
> + if (unlikely(skb->len >=
> + netif_get_gso_max_size(dev, vlan_get_protocol(skb))))
If netif_get_gso_max_size needs to inspect the result from
vlan_get_protocol, call it inside that function directly? More robust
and a one line change.
> return features & ~NETIF_F_GSO_MASK;
>
> if (!skb_shinfo(skb)->gso_type) {
> --
> 2.47.3
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev