aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2019-02-20 17:35:38 -0500
committerDavid S. Miller <davem@davemloft.net>2019-02-22 14:53:32 -0500
commitcc1d5bda17c8eb4cd195f05a5558ed63df057fce (patch)
tree78a7fe8dfe224a9ac807b0593cd436900034b0df /net/dsa
parent6d20faecc5949a305946559a38c89578e7d68264 (diff)
net: dsa: Deny enslaving VLAN devices into VLAN aware bridge
VLAN devices on top of a DSA network device which is already part of a bridge and with said bridge being VLAN aware should not be allowed to be enslaved into that bridge. For one, this duplicates functionality offered by the VLAN aware bridge which supports tagged and untagged VLAN frames processing and it would make things needlessly complex to e.g.: propagate FDB/MDB accordingly. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/slave.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index a78b2bba0332..f7f5d126a704 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1408,16 +1408,49 @@ static int dsa_slave_changeupper(struct net_device *dev,
1408 return err; 1408 return err;
1409} 1409}
1410 1410
1411static int dsa_slave_upper_vlan_check(struct net_device *dev,
1412 struct netdev_notifier_changeupper_info *
1413 info)
1414{
1415 struct netlink_ext_ack *ext_ack;
1416 struct net_device *slave;
1417 struct dsa_port *dp;
1418
1419 ext_ack = netdev_notifier_info_to_extack(&info->info);
1420
1421 if (!is_vlan_dev(dev))
1422 return NOTIFY_DONE;
1423
1424 slave = vlan_dev_real_dev(dev);
1425 if (!dsa_slave_dev_check(slave))
1426 return NOTIFY_DONE;
1427
1428 dp = dsa_slave_to_port(slave);
1429 if (!dp->bridge_dev)
1430 return NOTIFY_DONE;
1431
1432 /* Deny enslaving a VLAN device into a VLAN-aware bridge */
1433 if (br_vlan_enabled(dp->bridge_dev) &&
1434 netif_is_bridge_master(info->upper_dev) && info->linking) {
1435 NL_SET_ERR_MSG_MOD(ext_ack,
1436 "Cannot enslave VLAN device into VLAN aware bridge");
1437 return notifier_from_errno(-EINVAL);
1438 }
1439
1440 return NOTIFY_DONE;
1441}
1442
1411static int dsa_slave_netdevice_event(struct notifier_block *nb, 1443static int dsa_slave_netdevice_event(struct notifier_block *nb,
1412 unsigned long event, void *ptr) 1444 unsigned long event, void *ptr)
1413{ 1445{
1414 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1446 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1415 1447
1416 if (!dsa_slave_dev_check(dev)) 1448 if (event == NETDEV_CHANGEUPPER) {
1417 return NOTIFY_DONE; 1449 if (!dsa_slave_dev_check(dev))
1450 return dsa_slave_upper_vlan_check(dev, ptr);
1418 1451
1419 if (event == NETDEV_CHANGEUPPER)
1420 return dsa_slave_changeupper(dev, ptr); 1452 return dsa_slave_changeupper(dev, ptr);
1453 }
1421 1454
1422 return NOTIFY_DONE; 1455 return NOTIFY_DONE;
1423} 1456}