diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 6 | ||||
-rw-r--r-- | include/linux/netdevice.h | 2 | ||||
-rw-r--r-- | net/core/dev.c | 3 |
3 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 60bf8f27cc00..c6a3e61b53bd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
@@ -4139,6 +4139,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev, | |||
4139 | return -EINVAL; | 4139 | return -EINVAL; |
4140 | if (!info->linking) | 4140 | if (!info->linking) |
4141 | break; | 4141 | break; |
4142 | if (netdev_has_any_upper_dev(upper_dev)) | ||
4143 | return -EINVAL; | ||
4142 | if (netif_is_lag_master(upper_dev) && | 4144 | if (netif_is_lag_master(upper_dev) && |
4143 | !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev, | 4145 | !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev, |
4144 | info->upper_info)) | 4146 | info->upper_info)) |
@@ -4258,6 +4260,10 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev, | |||
4258 | upper_dev = info->upper_dev; | 4260 | upper_dev = info->upper_dev; |
4259 | if (!netif_is_bridge_master(upper_dev)) | 4261 | if (!netif_is_bridge_master(upper_dev)) |
4260 | return -EINVAL; | 4262 | return -EINVAL; |
4263 | if (!info->linking) | ||
4264 | break; | ||
4265 | if (netdev_has_any_upper_dev(upper_dev)) | ||
4266 | return -EINVAL; | ||
4261 | break; | 4267 | break; |
4262 | case NETDEV_CHANGEUPPER: | 4268 | case NETDEV_CHANGEUPPER: |
4263 | upper_dev = info->upper_dev; | 4269 | upper_dev = info->upper_dev; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 779b23595596..c99ba7914c0a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -3866,6 +3866,8 @@ int netdev_walk_all_upper_dev_rcu(struct net_device *dev, | |||
3866 | bool netdev_has_upper_dev_all_rcu(struct net_device *dev, | 3866 | bool netdev_has_upper_dev_all_rcu(struct net_device *dev, |
3867 | struct net_device *upper_dev); | 3867 | struct net_device *upper_dev); |
3868 | 3868 | ||
3869 | bool netdev_has_any_upper_dev(struct net_device *dev); | ||
3870 | |||
3869 | void *netdev_lower_get_next_private(struct net_device *dev, | 3871 | void *netdev_lower_get_next_private(struct net_device *dev, |
3870 | struct list_head **iter); | 3872 | struct list_head **iter); |
3871 | void *netdev_lower_get_next_private_rcu(struct net_device *dev, | 3873 | void *netdev_lower_get_next_private_rcu(struct net_device *dev, |
diff --git a/net/core/dev.c b/net/core/dev.c index 818dfa6e7ab5..86b4b0a79e7a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5668,12 +5668,13 @@ EXPORT_SYMBOL(netdev_has_upper_dev_all_rcu); | |||
5668 | * Find out if a device is linked to an upper device and return true in case | 5668 | * Find out if a device is linked to an upper device and return true in case |
5669 | * it is. The caller must hold the RTNL lock. | 5669 | * it is. The caller must hold the RTNL lock. |
5670 | */ | 5670 | */ |
5671 | static bool netdev_has_any_upper_dev(struct net_device *dev) | 5671 | bool netdev_has_any_upper_dev(struct net_device *dev) |
5672 | { | 5672 | { |
5673 | ASSERT_RTNL(); | 5673 | ASSERT_RTNL(); |
5674 | 5674 | ||
5675 | return !list_empty(&dev->adj_list.upper); | 5675 | return !list_empty(&dev->adj_list.upper); |
5676 | } | 5676 | } |
5677 | EXPORT_SYMBOL(netdev_has_any_upper_dev); | ||
5677 | 5678 | ||
5678 | /** | 5679 | /** |
5679 | * netdev_master_upper_dev_get - Get master upper device | 5680 | * netdev_master_upper_dev_get - Get master upper device |