Skip to content

Commit 06fdc45

Browse files
Jianbo Liukuba-moo
authored andcommitted
net/mlx5e: Prevent entering switchdev mode with inconsistent netns
When a PF enters switchdev mode, its netdevice becomes the uplink representor but remains in its current network namespace. All other representors (VFs, SFs) are created in the netns of the devlink instance. If the PF's netns has been moved and differs from the devlink's netns, enabling switchdev mode would create a state where the OVS control plane (ovs-vsctl) cannot manage the switch because the PF uplink representor and the other representors are split across different namespaces. To prevent this inconsistent configuration, block the request to enter switchdev mode if the PF netdevice's netns does not match the netns of its devlink instance. As part of this change, the PF's netns is first marked as immutable. This prevents race conditions where the netns could be changed after the check is performed but before the mode transition is complete, and it aligns the PF's behavior with that of the final uplink representor. Signed-off-by: Jianbo Liu <jianbol@nvidia.com> Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/1759094723-843774-3-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 906154c commit 06fdc45

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,6 +3774,29 @@ void mlx5_eswitch_unblock_mode(struct mlx5_core_dev *dev)
37743774
up_write(&esw->mode_lock);
37753775
}
37763776

3777+
/* Returns false only when uplink netdev exists and its netns is different from
3778+
* devlink's netns. True for all others so entering switchdev mode is allowed.
3779+
*/
3780+
static bool mlx5_devlink_netdev_netns_immutable_set(struct devlink *devlink,
3781+
bool immutable)
3782+
{
3783+
struct mlx5_core_dev *mdev = devlink_priv(devlink);
3784+
struct net_device *netdev;
3785+
bool ret;
3786+
3787+
netdev = mlx5_uplink_netdev_get(mdev);
3788+
if (!netdev)
3789+
return true;
3790+
3791+
rtnl_lock();
3792+
netdev->netns_immutable = immutable;
3793+
ret = net_eq(dev_net(netdev), devlink_net(devlink));
3794+
rtnl_unlock();
3795+
3796+
mlx5_uplink_netdev_put(mdev, netdev);
3797+
return ret;
3798+
}
3799+
37773800
int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
37783801
struct netlink_ext_ack *extack)
37793802
{
@@ -3816,6 +3839,14 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
38163839
esw->eswitch_operation_in_progress = true;
38173840
up_write(&esw->mode_lock);
38183841

3842+
if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV &&
3843+
!mlx5_devlink_netdev_netns_immutable_set(devlink, true)) {
3844+
NL_SET_ERR_MSG_MOD(extack,
3845+
"Can't change E-Switch mode to switchdev when netdev net namespace has diverged from the devlink's.");
3846+
err = -EINVAL;
3847+
goto skip;
3848+
}
3849+
38193850
if (mode == DEVLINK_ESWITCH_MODE_LEGACY)
38203851
esw->dev->priv.flags |= MLX5_PRIV_FLAGS_SWITCH_LEGACY;
38213852
mlx5_eswitch_disable_locked(esw);
@@ -3834,6 +3865,8 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
38343865
}
38353866

38363867
skip:
3868+
if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV && err)
3869+
mlx5_devlink_netdev_netns_immutable_set(devlink, false);
38373870
down_write(&esw->mode_lock);
38383871
esw->eswitch_operation_in_progress = false;
38393872
unlock:

0 commit comments

Comments
 (0)