net: bridge: Add checks for enabling the STP.

It is not possible to have the MRP and STP running at the same time on the
bridge, therefore add check when enabling the STP to check if MRP is already
enabled. In that case return error.

Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Horatiu Vultur 2020-04-26 15:22:08 +02:00 committed by David S. Miller
parent 6536993371
commit 419dba8a49
6 changed files with 23 additions and 8 deletions

View File

@ -242,8 +242,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
return -EPERM; return -EPERM;
br_stp_set_enabled(br, args[1]); ret = br_stp_set_enabled(br, args[1], NULL);
ret = 0;
break; break;
case BRCTL_SET_BRIDGE_PRIORITY: case BRCTL_SET_BRIDGE_PRIORITY:

View File

@ -1109,7 +1109,9 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
if (data[IFLA_BR_STP_STATE]) { if (data[IFLA_BR_STP_STATE]) {
u32 stp_enabled = nla_get_u32(data[IFLA_BR_STP_STATE]); u32 stp_enabled = nla_get_u32(data[IFLA_BR_STP_STATE]);
br_stp_set_enabled(br, stp_enabled); err = br_stp_set_enabled(br, stp_enabled, extack);
if (err)
return err;
} }
if (data[IFLA_BR_PRIORITY]) { if (data[IFLA_BR_PRIORITY]) {

View File

@ -1283,7 +1283,8 @@ int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time);
/* br_stp_if.c */ /* br_stp_if.c */
void br_stp_enable_bridge(struct net_bridge *br); void br_stp_enable_bridge(struct net_bridge *br);
void br_stp_disable_bridge(struct net_bridge *br); void br_stp_disable_bridge(struct net_bridge *br);
void br_stp_set_enabled(struct net_bridge *br, unsigned long val); int br_stp_set_enabled(struct net_bridge *br, unsigned long val,
struct netlink_ext_ack *extack);
void br_stp_enable_port(struct net_bridge_port *p); void br_stp_enable_port(struct net_bridge_port *p);
void br_stp_disable_port(struct net_bridge_port *p); void br_stp_disable_port(struct net_bridge_port *p);
bool br_stp_recalculate_bridge_id(struct net_bridge *br); bool br_stp_recalculate_bridge_id(struct net_bridge *br);

View File

@ -36,6 +36,12 @@ void br_set_state(struct net_bridge_port *p, unsigned int state)
}; };
int err; int err;
/* Don't change the state of the ports if they are driven by a different
* protocol.
*/
if (p->flags & BR_MRP_AWARE)
return;
p->state = state; p->state = state;
err = switchdev_port_attr_set(p->dev, &attr); err = switchdev_port_attr_set(p->dev, &attr);
if (err && err != -EOPNOTSUPP) if (err && err != -EOPNOTSUPP)

View File

@ -196,10 +196,17 @@ static void br_stp_stop(struct net_bridge *br)
br->stp_enabled = BR_NO_STP; br->stp_enabled = BR_NO_STP;
} }
void br_stp_set_enabled(struct net_bridge *br, unsigned long val) int br_stp_set_enabled(struct net_bridge *br, unsigned long val,
struct netlink_ext_ack *extack)
{ {
ASSERT_RTNL(); ASSERT_RTNL();
if (br_mrp_enabled(br)) {
NL_SET_ERR_MSG_MOD(extack,
"STP can't be enabled if MRP is already enabled\n");
return -EINVAL;
}
if (val) { if (val) {
if (br->stp_enabled == BR_NO_STP) if (br->stp_enabled == BR_NO_STP)
br_stp_start(br); br_stp_start(br);
@ -207,6 +214,8 @@ void br_stp_set_enabled(struct net_bridge *br, unsigned long val)
if (br->stp_enabled != BR_NO_STP) if (br->stp_enabled != BR_NO_STP)
br_stp_stop(br); br_stp_stop(br);
} }
return 0;
} }
/* called under bridge lock */ /* called under bridge lock */

View File

@ -126,9 +126,7 @@ static ssize_t stp_state_show(struct device *d,
static int set_stp_state(struct net_bridge *br, unsigned long val) static int set_stp_state(struct net_bridge *br, unsigned long val)
{ {
br_stp_set_enabled(br, val); return br_stp_set_enabled(br, val, NULL);
return 0;
} }
static ssize_t stp_state_store(struct device *d, static ssize_t stp_state_store(struct device *d,