From: Xin Xie <xiexinet@gmail.com>
To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch,
shuah@kernel.org, kees@kernel.org, petr.wozniak@gmail.com,
qingfang.deng@linux.dev, fmaurer@redhat.com,
luka.gejak@linux.dev, bigeasy@linutronix.de,
xiaoliang.yang_1@nxp.com, skhawaja@google.com,
liuhangbin@gmail.com, stable@vger.kernel.org,
sdf.kernel@gmail.com, xiexinet@gmail.com
Subject: [PATCH net v7 1/4] net: hsr: keep GRO disabled on HSR/PRP ports
Date: Fri, 9 Oct 2026 22:13:21 +0200 [thread overview]
Message-ID: <20261009201324.17-2-xiexinet@gmail.com> (raw)
In-Reply-To: <20261009201324.17-1-xiexinet@gmail.com>
HSR/PRP add tags and sequence numbers per wire frame. GRO can merge
plain interlink traffic before those fields are added, and userspace
can re-enable GRO after the port is attached.
Mark slave A/B and interlink devices with a kernel role bit. Filter
software GRO and configurable GRO_HW requests before ndo_fix_features()
without changing wanted_features. Filtering before the driver keeps
feature dependencies intact; fixed-on or driver-required GRO_HW is
left enabled.
Apply the policy before registering the RX handler and reject attach
if software GRO remains enabled. On failure or detach, unlink the
upper before clearing the role and recomputing features, restoring
the user's last request.
GSO skbs may still arrive. A later patch segments valid GSO before
HSR/PRP processing.
Fixes: 5055cccfc2d1 ("net: hsr: Provide RedBox support (HSR-SAN)")
Signed-off-by: Xin Xie <xiexinet@gmail.com>
---
.../networking/net_cachelines/net_device.rst | 1 +
include/linux/netdevice.h | 6 +++
net/core/dev.c | 10 ++++
net/hsr/hsr_slave.c | 47 +++++++++++++++++++
4 files changed, 64 insertions(+)
diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index 512f6d6fa3d8..114a29b2ff4c 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -168,6 +168,7 @@ unsigned_long:1 see_all_hwtstamp_requests
unsigned_long:1 change_proto_down
unsigned_long:1 netns_immutable
unsigned_long:1 fcoe_mtu
+unsigned_long:1 hsr_port
struct list_head net_notifier_list
struct macsec_ops* macsec_ops
struct udp_tunnel_nic_info* udp_tunnel_nic_info
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3cff2174dc03..0a917906fe2a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2102,6 +2102,7 @@ enum netdev_reg_state {
* @change_proto_down: device supports setting carrier via IFLA_PROTO_DOWN
* @netns_immutable: interface can't change network namespaces
* @fcoe_mtu: device supports maximum FCoE MTU, 2158 bytes
+ * @hsr_port: direct HSR/PRP member (slave A/B or interlink)
*
* @net_notifier_list: List of per-net netdev notifier block
* that follow this device when it is moved
@@ -2522,6 +2523,11 @@ struct net_device {
unsigned long change_proto_down:1;
unsigned long netns_immutable:1;
unsigned long fcoe_mtu:1;
+ /* Direct HSR/PRP member: slave A/B or interlink.
+ * Software GRO is filtered off while set. Kernel role
+ * state only; no user ABI or offload capability.
+ */
+ unsigned long hsr_port:1;
struct list_head net_notifier_list;
diff --git a/net/core/dev.c b/net/core/dev.c
index 18dc88990510..0c53b59af439 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -11111,6 +11111,16 @@ int __netdev_update_features(struct net_device *dev)
features = netdev_get_wanted_features(dev);
+ /* A direct HSR/PRP port needs per-frame metadata: filter
+ * software GRO and configurable GRO_HW requests before the
+ * driver fix runs, keeping the existing driver and core
+ * feature coupling.
+ */
+ if (dev->hsr_port) {
+ features &= ~NETIF_F_GRO;
+ features &= ~(dev->hw_features & NETIF_F_GRO_HW);
+ }
+
if (dev->netdev_ops->ndo_fix_features)
features = dev->netdev_ops->ndo_fix_features(dev, features);
diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
index a546f70f9cc8..1afcacac6b3c 100644
--- a/net/hsr/hsr_slave.c
+++ b/net/hsr/hsr_slave.c
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/if_vlan.h>
+#include <net/netdev_lock.h>
#include "hsr_main.h"
#include "hsr_device.h"
#include "hsr_forward.h"
@@ -137,6 +138,33 @@ static int hsr_check_dev_ok(struct net_device *dev,
return 0;
}
+/* Member role and feature policy.
+ * Setting the role makes __netdev_update_features() filter GRO
+ * and GRO_HW for this device. Only the role and feature update
+ * run under the device ops lock; unlink, promiscuous updates and
+ * the master recompute stay outside.
+ */
+static void hsr_portdev_role_set(struct net_device *dev)
+{
+ netdev_lock_ops(dev);
+ dev->hsr_port = true;
+ netdev_change_features(dev);
+ netdev_unlock_ops(dev);
+}
+
+static void hsr_portdev_role_clear(struct net_device *dev)
+{
+ netdev_lock_ops(dev);
+ dev->hsr_port = false;
+ /* Restore from the current wanted state only on a still-
+ * registered device; a netns move stays registered and must
+ * restore, a dying device just drops the role.
+ */
+ if (dev->reg_state == NETREG_REGISTERED)
+ netdev_change_features(dev);
+ netdev_unlock_ops(dev);
+}
+
/* Setup device to be added to the HSR bridge. */
static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
struct hsr_port *port,
@@ -169,6 +197,19 @@ static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
if (res)
goto fail_upper_dev_link;
+ /* Enable the member role and recompute before the RX handler
+ * is published: software GRO must be off before frames can
+ * arrive. A still-active software GRO rejects the port, a
+ * remaining GRO_HW alone does not.
+ */
+ hsr_portdev_role_set(dev);
+ if (dev->features & NETIF_F_GRO) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "software GRO still on after feature update, cannot join");
+ res = -EBUSY;
+ goto fail_role_policy;
+ }
+
res = netdev_rx_handler_register(dev, hsr_handle_frame, port);
if (res)
goto fail_rx_handler;
@@ -177,7 +218,12 @@ static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
return 0;
fail_rx_handler:
+fail_role_policy:
+ /* Rollback order: unlink the upper, clear the role and
+ * recompute, then undo this setup's promiscuous increment.
+ */
netdev_upper_dev_unlink(dev, hsr_dev);
+ hsr_portdev_role_clear(dev);
fail_upper_dev_link:
if (!port->hsr->fwd_offloaded || port->type == HSR_PT_INTERLINK)
dev_set_promiscuity(dev, -1);
@@ -248,6 +294,7 @@ void hsr_del_port(struct hsr_port *port)
if (port->type == HSR_PT_SLAVE_A || port->type == HSR_PT_SLAVE_B)
vlan_vids_del_by_dev(port->dev, master->dev);
netdev_upper_dev_unlink(port->dev, master->dev);
+ hsr_portdev_role_clear(port->dev);
if (hsr->prot_version == PRP_V1 &&
port->type == HSR_PT_SLAVE_B) {
eth_hw_addr_set(port->dev, port->original_macaddress);
--
2.43.0
next prev parent reply other threads:[~2026-10-09 20:13 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 20:13 [PATCH net v7 0/4] net: hsr: fix super-packet forwarding and ordering Xin Xie
2026-10-09 20:13 ` Xin Xie [this message]
2026-10-09 20:13 ` [PATCH net v7 2/4] net: hsr: preserve submission order without a forwarding lock Xin Xie
2026-10-09 20:13 ` [PATCH net v7 3/4] net: hsr: segment GSO before per-frame forwarding Xin Xie
2026-10-09 20:13 ` [PATCH net v7 4/4] selftests: net: hsr: verify GRO policy and ordered forwarding Xin Xie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261009201324.17-2-xiexinet@gmail.com \
--to=xiexinet@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=bigeasy@linutronix.de \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fmaurer@redhat.com \
--cc=horms@kernel.org \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=liuhangbin@gmail.com \
--cc=luka.gejak@linux.dev \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=petr.wozniak@gmail.com \
--cc=qingfang.deng@linux.dev \
--cc=sdf.kernel@gmail.com \
--cc=shuah@kernel.org \
--cc=skhawaja@google.com \
--cc=stable@vger.kernel.org \
--cc=xiaoliang.yang_1@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®