| From dc7f820a49b671493cb743d81d995ccd5eecf2f8 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 21 Jan 2026 17:11:27 +0100 |
| Subject: net: introduce mangleid_features |
| |
| From: Paolo Abeni <pabeni@redhat.com> |
| |
| [ Upstream commit 31c5a71d982b57df75858974634c2f0a338f2fc6 ] |
| |
| Some/most devices implementing gso_partial need to disable the GSO partial |
| features when the IP ID can't be mangled; to that extend each of them |
| implements something alike the following[1]: |
| |
| if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID)) |
| features &= ~NETIF_F_TSO; |
| |
| in the ndo_features_check() op, which leads to a bit of duplicate code. |
| |
| Later patch in the series will implement GSO partial support for virtual |
| devices, and the current status quo will require more duplicate code and |
| a new indirect call in the TX path for them. |
| |
| Introduce the mangleid_features mask, allowing the core to disable NIC |
| features based on/requiring MANGLEID, without any further intervention |
| from the driver. |
| |
| The same functionality could be alternatively implemented adding a single |
| boolean flag to the struct net_device, but would require an additional |
| checks in ndo_features_check(). |
| |
| Also note that [1] is incorrect if the NIC additionally implements |
| NETIF_F_GSO_UDP_L4, mangleid_features transparently handle even such a |
| case. |
| |
| Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
| Reviewed-by: Eric Dumazet <edumazet@google.com> |
| Link: https://patch.msgid.link/5a7cdaeea40b0a29b88e525b6c942d73ed3b8ce7.1769011015.git.pabeni@redhat.com |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Stable-dep-of: ddc748a391dd ("net: use skb_header_pointer() for TCPv4 GSO frag_off check") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/netdevice.h | 3 +++ |
| net/core/dev.c | 5 ++++- |
| 2 files changed, 7 insertions(+), 1 deletion(-) |
| |
| diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h |
| index 1216f050f0699..846afec74703b 100644 |
| --- a/include/linux/netdevice.h |
| +++ b/include/linux/netdevice.h |
| @@ -1833,6 +1833,8 @@ enum netdev_reg_state { |
| * |
| * @mpls_features: Mask of features inheritable by MPLS |
| * @gso_partial_features: value(s) from NETIF_F_GSO\* |
| + * @mangleid_features: Mask of features requiring MANGLEID, will be |
| + * disabled together with the latter. |
| * |
| * @ifindex: interface index |
| * @group: The group the device belongs to |
| @@ -2222,6 +2224,7 @@ struct net_device { |
| netdev_features_t vlan_features; |
| netdev_features_t hw_enc_features; |
| netdev_features_t mpls_features; |
| + netdev_features_t mangleid_features; |
| |
| unsigned int min_mtu; |
| unsigned int max_mtu; |
| diff --git a/net/core/dev.c b/net/core/dev.c |
| index b5f0d5c4d5412..8439bac371b7d 100644 |
| --- a/net/core/dev.c |
| +++ b/net/core/dev.c |
| @@ -3819,7 +3819,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb, |
| inner_ip_hdr(skb) : ip_hdr(skb); |
| |
| if (!(iph->frag_off & htons(IP_DF))) |
| - features &= ~NETIF_F_TSO_MANGLEID; |
| + features &= ~dev->mangleid_features; |
| } |
| |
| /* NETIF_F_IPV6_CSUM does not support IPv6 extension headers, |
| @@ -11411,6 +11411,9 @@ int register_netdevice(struct net_device *dev) |
| if (dev->hw_enc_features & NETIF_F_TSO) |
| dev->hw_enc_features |= NETIF_F_TSO_MANGLEID; |
| |
| + /* TSO_MANGLEID belongs in mangleid_features by definition */ |
| + dev->mangleid_features |= NETIF_F_TSO_MANGLEID; |
| + |
| /* Make NETIF_F_HIGHDMA inheritable to VLAN devices. |
| */ |
| dev->vlan_features |= NETIF_F_HIGHDMA; |
| -- |
| 2.53.0 |
| |