linux/net/bridge
Vladimir Oltean cbb56b03ec net: bridge: do not replay fdb entries pointing towards the bridge twice
This simple script:

ip link add br0 type bridge
ip link set swp2 master br0
ip link set br0 address 00:01:02:03:04:05
ip link del br0

produces this result on a DSA switch:

[  421.306399] br0: port 1(swp2) entered blocking state
[  421.311445] br0: port 1(swp2) entered disabled state
[  421.472553] device swp2 entered promiscuous mode
[  421.488986] device swp2 left promiscuous mode
[  421.493508] br0: port 1(swp2) entered disabled state
[  421.886107] sja1105 spi0.1: port 1 failed to delete 00:01:02:03:04:05 vid 1 from fdb: -ENOENT
[  421.894374] sja1105 spi0.1: port 1 failed to delete 00:01:02:03:04:05 vid 0 from fdb: -ENOENT
[  421.943982] br0: port 1(swp2) entered blocking state
[  421.949030] br0: port 1(swp2) entered disabled state
[  422.112504] device swp2 entered promiscuous mode

A very simplified view of what happens is:

(1) the bridge port is created, and the bridge device inherits its MAC
    address

(2) when joining, the bridge port (DSA) requests a replay of the
    addition of all FDB entries towards this bridge port and towards the
    bridge device itself. In fact, DSA calls br_fdb_replay() twice:

	br_fdb_replay(br, brport_dev);
	br_fdb_replay(br, br);

    DSA uses reference counting for the FDB entries. So the MAC address
    of the bridge is simply kept with refcount 2. When the bridge port
    leaves under normal circumstances, everything cancels out since the
    replay of the FDB entry deletion is also done twice per VLAN.

(3) when the bridge MAC address changes, switchdev is notified of the
    deletion of the old address and of the insertion of the new one.
    But the old address does not really go away, since it had refcount
    2, and the new address is added "only" with refcount 1.

(4) when the bridge port leaves now, it will replay a deletion of the
    FDB entries pointing towards the bridge twice. Then DSA will
    complain that it can't delete something that no longer exists.

It is clear that the problem is that the FDB entries towards the bridge
are replayed too many times, so let's fix that problem.

Fixes: 63c51453c8 ("net: dsa: replay the local bridge FDB entries pointing to the bridge dev too")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://lore.kernel.org/r/20210719093916.4099032-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2021-07-20 13:08:45 +02:00
..
netfilter netfilter: allow to turn off xtables compat layer 2021-04-26 18:16:56 +02:00
Kconfig
Makefile
br.c
br_arp_nd_proxy.c
br_cfm.c bridge: cfm: remove redundant return 2021-06-22 10:35:15 -07:00
br_cfm_netlink.c
br_device.c
br_fdb.c net: bridge: do not replay fdb entries pointing towards the bridge twice 2021-07-20 13:08:45 +02:00
br_forward.c net: bridge: mcast: add wrappers for router node retrieval 2021-05-13 14:04:31 -07:00
br_if.c net: bridge: sync fdb to new unicast-filtering ports 2021-07-02 13:34:07 -07:00
br_input.c net: bridge: mcast: prepare is-router function for mcast router split 2021-05-13 14:04:31 -07:00
br_ioctl.c
br_mdb.c net: bridge: allow the switchdev replay functions to be called for deletion 2021-06-28 14:09:03 -07:00
br_mrp.c net: bridge: mrp: Update the Test frames for MRA 2021-06-28 15:46:10 -07:00
br_mrp_netlink.c
br_mrp_switchdev.c
br_multicast.c net: bridge: multicast: fix MRD advertisement router port marking race 2021-07-11 12:11:06 -07:00
br_multicast_eht.c
br_netfilter_hooks.c
br_netfilter_ipv6.c
br_netlink.c net: bridge: remove redundant assignment 2021-05-25 15:20:27 -07:00
br_netlink_tunnel.c
br_nf_core.c
br_private.h net: bridge: switchdev: send FDB notifications for host addresses 2021-06-29 10:46:23 -07:00
br_private_cfm.h
br_private_mcast_eht.h
br_private_mrp.h net: bridge: mrp: Update the Test frames for MRA 2021-06-28 15:46:10 -07:00
br_private_stp.h
br_private_tunnel.h
br_stp.c net: bridge: constify variables in the replay helpers 2021-06-28 14:09:03 -07:00
br_stp_bpdu.c
br_stp_if.c
br_stp_timer.c
br_switchdev.c net: bridge: switchdev: send FDB notifications for host addresses 2021-06-29 10:46:23 -07:00
br_sysfs_br.c net: bridge: propagate error code and extack from br_mc_disabled_update 2021-04-14 14:32:05 -07:00
br_sysfs_if.c
br_vlan.c net: bridge: allow the switchdev replay functions to be called for deletion 2021-06-28 14:09:03 -07:00
br_vlan_options.c
br_vlan_tunnel.c net: bridge: fix vlan tunnel dst refcnt when egressing 2021-06-10 14:06:43 -07:00