OSDN Git Service

net: dsa: fix bridge_num not getting cleared after ports leaving the bridge
authorVladimir Oltean <vladimir.oltean@nxp.com>
Thu, 7 Oct 2021 16:47:08 +0000 (19:47 +0300)
committerJakub Kicinski <kuba@kernel.org>
Fri, 8 Oct 2021 22:47:45 +0000 (15:47 -0700)
commit1bec0f05062cf21e78093b1c4a2ae744e2873b8a
tree421e565aa34fce7b05e425b44bac72069e858710
parent1b1499a817c90fd1ce9453a2c98d2a01cca0e775
net: dsa: fix bridge_num not getting cleared after ports leaving the bridge

The dp->bridge_num is zero-based, with -1 being the encoding for an
invalid value. But dsa_bridge_num_put used to check for an invalid value
by comparing bridge_num with 0, which is of course incorrect.

The result is that the bridge_num will never get cleared by
dsa_bridge_num_put, and further port joins to other bridges will get a
bridge_num larger than the previous one, and once all the available
bridges with TX forwarding offload supported by the hardware get
exhausted, the TX forwarding offload feature is simply disabled.

In the case of sja1105, 7 iterations of the loop below are enough to
exhaust the TX forwarding offload bits, and further bridge joins operate
without that feature.

ip link add br0 type bridge vlan_filtering 1

while :; do
        ip link set sw0p2 master br0 && sleep 1
        ip link set sw0p2 nomaster && sleep 1
done

This issue is enough of an indication that having the dp->bridge_num
invalid encoding be a negative number is prone to bugs, so this will be
changed to a one-based value, with the dp->bridge_num of zero being the
indication of no bridge. However, that is material for net-next.

Fixes: f5e165e72b29 ("net: dsa: track unique bridge numbers across all DSA switch trees")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/dsa/dsa2.c