Skip to content

Commit b3529af

Browse files
idoschdavem330
authored andcommitted
spectrum: Reference count VLAN entries
One of the basic construct in the device is a port-VLAN pair, which can be bound to a FID or a RIF in order to direct packets to the bridge or the router, respectively. Since not all the netdevs are configured with a VLAN (e.g., sw1p1 vs. sw1p1.10), VID 1 is used to represent these and thus this VID can be used by both upper devices of mlxsw ports and by the driver itself. However, this VID is not reference counted and therefore might be freed prematurely, which can result in various WARNINGs. For example: $ ip link add name br0 type bridge vlan_filtering 1 $ teamd -t team0 -d -c '{"runner": {"name": "lacp"}}' $ ip link set dev team0 master br0 $ ip link set dev enp1s0np1 master team0 $ ip address add 192.0.2.1/24 dev enp1s0np1 The enslavement to team0 will fail because team0 already has an upper and thus vlan_vids_del_by_dev() will be executed as part of team's error path which will delete VID 1 from enp1s0np1 (added by br0 as PVID). The WARNING will be generated when the driver will realize it can't find VID 1 on the port and bind it to a RIF. Fix this by adding a reference count to the VLAN entries on the port, in a similar fashion to the reference counting used by the corresponding 'vlan_vid_info' structure in the 8021q driver. Fixes: c57529e ("mlxsw: spectrum: Replace vPorts with Port-VLAN") Reported-by: Tal Bar <talb@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Tested-by: Tal Bar <talb@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 9d45deb commit b3529af

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,7 @@ mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
14591459
}
14601460

14611461
mlxsw_sp_port_vlan->mlxsw_sp_port = mlxsw_sp_port;
1462+
mlxsw_sp_port_vlan->ref_count = 1;
14621463
mlxsw_sp_port_vlan->vid = vid;
14631464
list_add(&mlxsw_sp_port_vlan->list, &mlxsw_sp_port->vlans_list);
14641465

@@ -1486,8 +1487,10 @@ mlxsw_sp_port_vlan_get(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
14861487
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
14871488

14881489
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1489-
if (mlxsw_sp_port_vlan)
1490+
if (mlxsw_sp_port_vlan) {
1491+
mlxsw_sp_port_vlan->ref_count++;
14901492
return mlxsw_sp_port_vlan;
1493+
}
14911494

14921495
return mlxsw_sp_port_vlan_create(mlxsw_sp_port, vid);
14931496
}
@@ -1496,6 +1499,9 @@ void mlxsw_sp_port_vlan_put(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
14961499
{
14971500
struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
14981501

1502+
if (--mlxsw_sp_port_vlan->ref_count != 0)
1503+
return;
1504+
14991505
if (mlxsw_sp_port_vlan->bridge_port)
15001506
mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
15011507
else if (fid)

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ struct mlxsw_sp_port_vlan {
211211
struct list_head list;
212212
struct mlxsw_sp_port *mlxsw_sp_port;
213213
struct mlxsw_sp_fid *fid;
214+
unsigned int ref_count;
214215
u16 vid;
215216
struct mlxsw_sp_bridge_port *bridge_port;
216217
struct list_head bridge_vlan_node;

0 commit comments

Comments
 (0)