Merge branch 'net-mlx5-bridge-fix-remaining-switchdev-ownership-gaps-on-merged-eswitch'

Bernardo Soares says:

====================
net/mlx5: Bridge, fix remaining switchdev ownership gaps on merged eswitch
====================

Link: https://patch.msgid.link/20260918095931.29792-1-bsoares.it@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-09-22 18:09:23 -07:00
commit 1c34493df9
3 changed files with 49 additions and 13 deletions

View File

@ -85,9 +85,16 @@ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct m
struct net_device *lower_dev;
struct list_head *iter;
if (netif_is_lag_master(dev) || mlx5e_eswitch_rep(dev))
return mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, esw, vport_num,
esw_owner_vhca_id);
if (netif_is_lag_master(dev) || mlx5e_eswitch_rep(dev)) {
struct net_device *rep;
rep = mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, esw, vport_num,
esw_owner_vhca_id);
if (rep && !mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id,
esw->br_offloads))
return NULL;
return rep;
}
netdev_for_each_lower_dev(dev, lower_dev, iter) {
struct net_device *rep;
@ -104,6 +111,28 @@ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct m
return NULL;
}
static bool mlx5_esw_bridge_rep_port_lookup(struct net_device *dev,
struct mlx5_esw_bridge_offloads *br_offloads,
u16 *vport_num, u16 *esw_owner_vhca_id)
{
if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, vport_num,
esw_owner_vhca_id))
return false;
return mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id, br_offloads);
}
static bool mlx5_esw_bridge_lower_rep_port_lookup(struct net_device *dev,
struct mlx5_esw_bridge_offloads *br_offloads,
u16 *vport_num, u16 *esw_owner_vhca_id)
{
if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, vport_num,
esw_owner_vhca_id))
return false;
return mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id, br_offloads);
}
static bool mlx5_esw_bridge_is_local(struct net_device *dev, struct net_device *rep,
struct mlx5_eswitch *esw)
{
@ -218,8 +247,7 @@ mlx5_esw_bridge_port_obj_add(struct net_device *dev,
u16 vport_num, esw_owner_vhca_id;
int err;
if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
&esw_owner_vhca_id))
if (!mlx5_esw_bridge_rep_port_lookup(dev, br_offloads, &vport_num, &esw_owner_vhca_id))
return 0;
port_obj_info->handled = true;
@ -251,8 +279,7 @@ mlx5_esw_bridge_port_obj_del(struct net_device *dev,
const struct switchdev_obj_port_mdb *mdb;
u16 vport_num, esw_owner_vhca_id;
if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
&esw_owner_vhca_id))
if (!mlx5_esw_bridge_rep_port_lookup(dev, br_offloads, &vport_num, &esw_owner_vhca_id))
return 0;
port_obj_info->handled = true;
@ -283,8 +310,8 @@ mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
u16 vport_num, esw_owner_vhca_id;
int err = 0;
if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
&esw_owner_vhca_id))
if (!mlx5_esw_bridge_lower_rep_port_lookup(dev, br_offloads, &vport_num,
&esw_owner_vhca_id))
return 0;
port_attr_info->handled = true;

View File

@ -1649,10 +1649,8 @@ int mlx5_esw_bridge_vport_unlink(struct net_device *br_netdev, u16 vport_num,
int err;
port = mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads);
if (!port) {
NL_SET_ERR_MSG_MOD(extack, "Port is not attached to any bridge");
return -EINVAL;
}
if (!port)
return 0;
if (port->bridge->ifindex != br_netdev->ifindex) {
NL_SET_ERR_MSG_MOD(extack, "Port is attached to another bridge");
return -EINVAL;
@ -1682,10 +1680,19 @@ int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_nu
struct mlx5_esw_bridge_offloads *br_offloads,
struct netlink_ext_ack *extack)
{
if (!MLX5_CAP_ESW(br_offloads->esw->dev, merged_eswitch))
return 0;
return mlx5_esw_bridge_vport_unlink(br_netdev, vport_num, esw_owner_vhca_id, br_offloads,
extack);
}
bool mlx5_esw_bridge_port_exists(u16 vport_num, u16 esw_owner_vhca_id,
struct mlx5_esw_bridge_offloads *br_offloads)
{
return mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads);
}
int mlx5_esw_bridge_port_vlan_add(u16 vport_num, u16 esw_owner_vhca_id, u16 vid, u16 flags,
struct mlx5_esw_bridge_offloads *br_offloads,
struct netlink_ext_ack *extack)

View File

@ -80,6 +80,8 @@ int mlx5_esw_bridge_vlan_proto_set(u16 vport_num, u16 esw_owner_vhca_id, u16 pro
struct mlx5_esw_bridge_offloads *br_offloads);
int mlx5_esw_bridge_mcast_set(u16 vport_num, u16 esw_owner_vhca_id, bool enable,
struct mlx5_esw_bridge_offloads *br_offloads);
bool mlx5_esw_bridge_port_exists(u16 vport_num, u16 esw_owner_vhca_id,
struct mlx5_esw_bridge_offloads *br_offloads);
int mlx5_esw_bridge_port_vlan_add(u16 vport_num, u16 esw_owner_vhca_id, u16 vid, u16 flags,
struct mlx5_esw_bridge_offloads *br_offloads,
struct netlink_ext_ack *extack);