Skip to content

Commit 602b74e

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum_switchdev: Do not leak RIFs when removing bridge
When a bridge device is removed, the VLANs are flushed from each configured port. This causes the ports to decrement the reference count on the associated FIDs (filtering identifier). If the reference count of a FID is 1 and it has a RIF (router interface), then this RIF is destroyed. However, if no port is member in the VLAN for which a RIF exists, then the RIF will continue to exist after the removal of the bridge. To reproduce: # ip link add name br0 type bridge vlan_filtering 1 # ip link set dev swp1 master br0 # ip link add link br0 name br0.10 type vlan id 10 # ip address add 192.0.2.0/24 dev br0.10 # ip link del dev br0 The RIF associated with br0.10 continues to exist. Fix this by iterating over all the bridge device uppers when it is destroyed and take care of destroying their RIFs. Fixes: 99f44bb ("mlxsw: spectrum: Enable L3 interfaces on top of bridge devices") Signed-off-by: Ido Schimmel <idosch@mellanox.com> Reviewed-by: Petr Machata <petrm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ae92378 commit 602b74e

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
414414
void
415415
mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
416416
void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif);
417+
void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
418+
struct net_device *dev);
417419

418420
/* spectrum_kvdl.c */
419421
enum mlxsw_sp_kvdl_entry_type {

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6234,6 +6234,17 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
62346234
mlxsw_sp_vr_put(mlxsw_sp, vr);
62356235
}
62366236

6237+
void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
6238+
struct net_device *dev)
6239+
{
6240+
struct mlxsw_sp_rif *rif;
6241+
6242+
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
6243+
if (!rif)
6244+
return;
6245+
mlxsw_sp_rif_destroy(rif);
6246+
}
6247+
62376248
static void
62386249
mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params,
62396250
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,24 @@ bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
127127
return !!mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
128128
}
129129

130+
static int mlxsw_sp_bridge_device_upper_rif_destroy(struct net_device *dev,
131+
void *data)
132+
{
133+
struct mlxsw_sp *mlxsw_sp = data;
134+
135+
mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
136+
return 0;
137+
}
138+
139+
static void mlxsw_sp_bridge_device_rifs_destroy(struct mlxsw_sp *mlxsw_sp,
140+
struct net_device *dev)
141+
{
142+
mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
143+
netdev_walk_all_upper_dev_rcu(dev,
144+
mlxsw_sp_bridge_device_upper_rif_destroy,
145+
mlxsw_sp);
146+
}
147+
130148
static struct mlxsw_sp_bridge_device *
131149
mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
132150
struct net_device *br_dev)
@@ -165,6 +183,8 @@ static void
165183
mlxsw_sp_bridge_device_destroy(struct mlxsw_sp_bridge *bridge,
166184
struct mlxsw_sp_bridge_device *bridge_device)
167185
{
186+
mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp,
187+
bridge_device->dev);
168188
list_del(&bridge_device->list);
169189
if (bridge_device->vlan_enabled)
170190
bridge->vlan_enabled_exists = false;

0 commit comments

Comments
 (0)