summaryrefslogtreecommitdiffstats
path: root/net/bridge/br_stp.c
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2021-03-23 00:51:42 +0100
committerDavid S. Miller <davem@davemloft.net>2021-03-23 22:49:05 +0100
commitc0e715bbd50e57319f76d0b757dc282893f2d476 (patch)
treed6b9da556666db7f8fa9cef38ecc42dca88dea42 /net/bridge/br_stp.c
parentnet: lapb: Make "lapb_t1timer_running" able to detect an already running timer (diff)
downloadlinux-c0e715bbd50e57319f76d0b757dc282893f2d476.tar.xz
linux-c0e715bbd50e57319f76d0b757dc282893f2d476.zip
net: bridge: add helper for retrieving the current bridge port STP state
It may happen that we have the following topology with DSA or any other switchdev driver with LAG offload: ip link add br0 type bridge stp_state 1 ip link add bond0 type bond ip link set bond0 master br0 ip link set swp0 master bond0 ip link set swp1 master bond0 STP decides that it should put bond0 into the BLOCKING state, and that's that. The ports that are actively listening for the switchdev port attributes emitted for the bond0 bridge port (because they are offloading it) and have the honor of seeing that switchdev port attribute can react to it, so we can program swp0 and swp1 into the BLOCKING state. But if then we do: ip link set swp2 master bond0 then as far as the bridge is concerned, nothing has changed: it still has one bridge port. But this new bridge port will not see any STP state change notification and will remain FORWARDING, which is how the standalone code leaves it in. We need a function in the bridge driver which retrieves the current STP state, such that drivers can synchronize to it when they may have missed switchdev events. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com> Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_stp.c')
-rw-r--r--net/bridge/br_stp.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 21c6781906aa..86b5e05d3f21 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -64,6 +64,20 @@ void br_set_state(struct net_bridge_port *p, unsigned int state)
}
}
+u8 br_port_get_stp_state(const struct net_device *dev)
+{
+ struct net_bridge_port *p;
+
+ ASSERT_RTNL();
+
+ p = br_port_get_rtnl(dev);
+ if (!p)
+ return BR_STATE_DISABLED;
+
+ return p->state;
+}
+EXPORT_SYMBOL_GPL(br_port_get_stp_state);
+
/* called under bridge lock */
struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no)
{