mirror of https://gitee.com/openkylin/linux.git
net: dsa: fix unintended change of bridge interface STP state
When a DSA port is added to a bridge and brought up, the resulting STP state programmed into the hardware depends on the order that these operations are performed. However, the Linux bridge code believes that the port is in disabled mode. If the DSA port is first added to a bridge and then brought up, it will be in blocking mode. If it is brought up and then added to the bridge, it will be in disabled mode. This difference is caused by DSA always setting the STP mode in dsa_port_enable() whether or not this port is part of a bridge. Since bridge always sets the STP state when the port is added, brought up or taken down, it is unnecessary for us to manipulate the STP state. Apparently, this code was copied from Rocker, and the very next day a similar fix for Rocker was merged but was not propagated to DSA. Seee47172ab7e
("rocker: put port in FORWADING state after leaving bridge") Fixes:b73adef677
("net: dsa: integrate with SWITCHDEV for HW bridging") Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
40e196a906
commit
9c2054a5cf
|
@ -69,7 +69,6 @@ static void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
|
|||
|
||||
int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy)
|
||||
{
|
||||
u8 stp_state = dp->bridge_dev ? BR_STATE_BLOCKING : BR_STATE_FORWARDING;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
int port = dp->index;
|
||||
int err;
|
||||
|
@ -80,7 +79,8 @@ int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy)
|
|||
return err;
|
||||
}
|
||||
|
||||
dsa_port_set_state_now(dp, stp_state);
|
||||
if (!dp->bridge_dev)
|
||||
dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -90,7 +90,8 @@ void dsa_port_disable(struct dsa_port *dp, struct phy_device *phy)
|
|||
struct dsa_switch *ds = dp->ds;
|
||||
int port = dp->index;
|
||||
|
||||
dsa_port_set_state_now(dp, BR_STATE_DISABLED);
|
||||
if (!dp->bridge_dev)
|
||||
dsa_port_set_state_now(dp, BR_STATE_DISABLED);
|
||||
|
||||
if (ds->ops->port_disable)
|
||||
ds->ops->port_disable(ds, port, phy);
|
||||
|
|
Loading…
Reference in New Issue