aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c6
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--net/core/dev.c3
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,
3866bool netdev_has_upper_dev_all_rcu(struct net_device *dev, 3866bool netdev_has_upper_dev_all_rcu(struct net_device *dev,
3867 struct net_device *upper_dev); 3867 struct net_device *upper_dev);
3868 3868
3869bool netdev_has_any_upper_dev(struct net_device *dev);
3870
3869void *netdev_lower_get_next_private(struct net_device *dev, 3871void *netdev_lower_get_next_private(struct net_device *dev,
3870 struct list_head **iter); 3872 struct list_head **iter);
3871void *netdev_lower_get_next_private_rcu(struct net_device *dev, 3873void *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 */
5671static bool netdev_has_any_upper_dev(struct net_device *dev) 5671bool 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}
5677EXPORT_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