Re: [PATCH net-next] net: dsa: unsync host addresses when destroying user port

From: Vladimir Oltean

Date: Thu Jul 23 2026 - 18:58:44 EST


On Wed, Jul 22, 2026 at 01:12:47AM +0100, Daniel Golle wrote:
> When a user port is destroyed while addresses are still synced to it,
> e.g. multicast addresses synced by a bridge the port is a member of,
> the host FDB/MDB entries these addresses installed on the CPU port are
> never removed: the only removal path is dsa_user_unsync_uc()/_mc() via
> ndo_set_rx_mode, and __dev_set_rx_mode() does not call the ndo on a
> device which is down. By the time the bridge unsyncs its addresses in
> del_nbp() during unregistration, the netdev has already been closed,
> so the unsync never reaches DSA and the entries linger until
> dsa_switch_release_ports() reports them:
>
> Cleaning up multicast address 33:33:00:00:00:01 vid 0 from port 9
>
> This happens on every unbind of a DSA driver supporting host address
> filtering while its ports are up.
>
> Unsync the host addresses in dsa_user_destroy() before unregistering
> the netdev, at a point where the driver can still process the
> deletion, just like dsa_user_change_conduit() already does when
> migrating host addresses to a new conduit.
>
> Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx>
> ---
> net/dsa/user.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/dsa/user.c b/net/dsa/user.c
> index 03c7af6abe18..a7dabb645036 100644
> --- a/net/dsa/user.c
> +++ b/net/dsa/user.c
> @@ -2885,6 +2885,7 @@ void dsa_user_destroy(struct net_device *user_dev)
>
> netif_carrier_off(user_dev);
> rtnl_lock();
> + dsa_user_unsync_ha(user_dev);
> netdev_upper_dev_unlink(conduit, user_dev);
> unregister_netdevice(user_dev);
> phylink_disconnect_phy(dp->pl);
> --
> 2.55.0

Sorry, I noticed this patch late. Something doesn't add up - I don't
understand what makes the unregistration path unique, since according to
all you've said, it should be enough to remove the user port from the
bridge while administratively down, and it should lead to the same
effect (no unsync event triggered). In that case, maybe the
dsa_user_unsync_ha() belongs somewhere in dsa_user_close(), near
dsa_user_host_uc_uninstall().

I will return tomorrow with more comments after I do some testing.