Skip to content

Commit 3167378

Browse files
IoanaCiorneigregkh
authored andcommitted
staging: dpaa2-switch: prevent joining a bridge while VLAN uppers are present
Each time a switch port joins a bridge, it will start to use a FDB table common with all the other switch ports that are under the same bridge. This means that any VLAN added prior to a bridge join, will retain its previous FDB table destination. With this patch, I choose to restrict when a switch port can change it's upper device (either join or leave) so that the driver does not have to delete all the previously installed VLANs from the previous FDB and add them into the new one. Thus, in the PRECHANGEUPPER notification we check if there are any VLAN type upper devices and if that's true, deny the CHANGEUPPER. This way, the user is not restricted in the topology but rather in the order in which the setup is done: it must first create the bridging domain layout and after that add the necessary VLAN devices if necessary. The teardown is similar, the VLAN devices will need to be destroyed prior to a change in the bridging layout. Signed-off-by: Ioana Ciornei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 53011af commit 3167378

File tree

1 file changed

+29
-1
lines changed
  • drivers/staging/fsl-dpaa2/ethsw

1 file changed

+29
-1
lines changed

drivers/staging/fsl-dpaa2/ethsw/ethsw.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,21 @@ static int dpaa2_switch_port_bridge_leave(struct net_device *netdev)
15901590
BRIDGE_VLAN_INFO_UNTAGGED | BRIDGE_VLAN_INFO_PVID);
15911591
}
15921592

1593+
static int dpaa2_switch_prevent_bridging_with_8021q_upper(struct net_device *netdev)
1594+
{
1595+
struct net_device *upper_dev;
1596+
struct list_head *iter;
1597+
1598+
/* RCU read lock not necessary because we have write-side protection
1599+
* (rtnl_mutex), however a non-rcu iterator does not exist.
1600+
*/
1601+
netdev_for_each_upper_dev_rcu(netdev, upper_dev, iter)
1602+
if (is_vlan_dev(upper_dev))
1603+
return -EOPNOTSUPP;
1604+
1605+
return 0;
1606+
}
1607+
15931608
static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb,
15941609
unsigned long event, void *ptr)
15951610
{
@@ -1607,10 +1622,22 @@ static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb,
16071622
switch (event) {
16081623
case NETDEV_PRECHANGEUPPER:
16091624
upper_dev = info->upper_dev;
1610-
if (netif_is_bridge_master(upper_dev) && !br_vlan_enabled(upper_dev)) {
1625+
if (!netif_is_bridge_master(upper_dev))
1626+
break;
1627+
1628+
if (!br_vlan_enabled(upper_dev)) {
16111629
NL_SET_ERR_MSG_MOD(extack, "Cannot join a VLAN-unaware bridge");
16121630
err = -EOPNOTSUPP;
1631+
goto out;
1632+
}
1633+
1634+
err = dpaa2_switch_prevent_bridging_with_8021q_upper(netdev);
1635+
if (err) {
1636+
NL_SET_ERR_MSG_MOD(extack,
1637+
"Cannot join a bridge while VLAN uppers are present");
1638+
goto out;
16131639
}
1640+
16141641
break;
16151642
case NETDEV_CHANGEUPPER:
16161643
upper_dev = info->upper_dev;
@@ -1623,6 +1650,7 @@ static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb,
16231650
break;
16241651
}
16251652

1653+
out:
16261654
return notifier_from_errno(err);
16271655
}
16281656

0 commit comments

Comments
 (0)