mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
mlxsw: spectrum: Relax sanity checks during enslavement
[ Upstream commit90045fc9c7] Since commit25cc72a338("mlxsw: spectrum: Forbid linking to devices that have uppers") the driver forbids enslavement to netdevs that already have uppers of their own, as this can result in various ordering problems. This requirement proved to be too strict for some users who need to be able to enslave ports to a bridge that already has uppers. In this case, we can allow the enslavement if the bridge is already known to us, as any configuration performed on top of the bridge was already reflected to the device. Fixes:25cc72a338("mlxsw: spectrum: Forbid linking to devices that have uppers") Signed-off-by: Ido Schimmel <idosch@mellanox.com> Reported-by: Alexander Petrovskiy <alexpe@mellanox.com> Tested-by: Alexander Petrovskiy <alexpe@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0c21439334
commit
ce66902de8
@@ -4235,7 +4235,10 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
|
||||
return -EINVAL;
|
||||
if (!info->linking)
|
||||
break;
|
||||
if (netdev_has_any_upper_dev(upper_dev))
|
||||
if (netdev_has_any_upper_dev(upper_dev) &&
|
||||
(!netif_is_bridge_master(upper_dev) ||
|
||||
!mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
|
||||
upper_dev)))
|
||||
return -EINVAL;
|
||||
if (netif_is_lag_master(upper_dev) &&
|
||||
!mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
|
||||
@@ -4347,6 +4350,7 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
|
||||
u16 vid)
|
||||
{
|
||||
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
struct netdev_notifier_changeupper_info *info = ptr;
|
||||
struct net_device *upper_dev;
|
||||
int err = 0;
|
||||
@@ -4358,7 +4362,10 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
|
||||
return -EINVAL;
|
||||
if (!info->linking)
|
||||
break;
|
||||
if (netdev_has_any_upper_dev(upper_dev))
|
||||
if (netdev_has_any_upper_dev(upper_dev) &&
|
||||
(!netif_is_bridge_master(upper_dev) ||
|
||||
!mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
|
||||
upper_dev)))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NETDEV_CHANGEUPPER:
|
||||
|
||||
@@ -326,6 +326,8 @@ int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
struct net_device *brport_dev,
|
||||
struct net_device *br_dev);
|
||||
bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
|
||||
const struct net_device *br_dev);
|
||||
|
||||
/* spectrum.c */
|
||||
int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
|
||||
@@ -134,6 +134,12 @@ mlxsw_sp_bridge_device_find(const struct mlxsw_sp_bridge *bridge,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
|
||||
const struct net_device *br_dev)
|
||||
{
|
||||
return !!mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
|
||||
}
|
||||
|
||||
static struct mlxsw_sp_bridge_device *
|
||||
mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
|
||||
struct net_device *br_dev)
|
||||
|
||||
Reference in New Issue
Block a user