diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/dsa/slave.c | 39 |
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 | ||
| 1411 | static 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 | |||
| 1411 | static int dsa_slave_netdevice_event(struct notifier_block *nb, | 1443 | static 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 | } |
