Skip to content

Commit

Permalink
net: dsa: sja1105: ignore the FDB entry for unknown multicast when ad…
Browse files Browse the repository at this point in the history
…ding a new address

[ Upstream commit 728db84 ]

Currently, when sja1105pqrs_fdb_add() is called for a host-joined IPv6
MDB entry such as 33:33:00:00:00:6a, the search for that address will
return the FDB entry for SJA1105_UNKNOWN_MULTICAST, which has a
destination MAC of 01:00:00:00:00:00 and a mask of 01:00:00:00:00:00.
It returns that entry because, well, it matches, in the sense that
unknown multicast is supposed by design to match it...

But the issue is that we then proceed to overwrite this entry with the
one for our precise host-joined multicast address, and the unknown
multicast entry is no longer there - unknown multicast is now flooded to
the same group of ports as broadcast, which does not look up the FDB.

To solve this problem, we should ignore searches that return the unknown
multicast address as the match, and treat them as "no match" which will
result in the entry being installed to hardware.

For this to work properly, we need to put the result of the FDB search
in a temporary variable in order to avoid overwriting the l2_lookup
entry we want to program. The l2_lookup entry returned by the search
might not have the same set of DESTPORTS and not even the same MACADDR
as the entry we're trying to add.

Fixes: 4d94235 ("net: dsa: sja1105: offload bridge port flags to device")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
vladimiroltean authored and gregkh committed Aug 12, 2021
1 parent f072c44 commit 8a9e4d4
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions drivers/net/dsa/sja1105/sja1105_main.c
Expand Up @@ -1446,14 +1446,19 @@ int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port,
}
l2_lookup.destports = BIT(port);

tmp = l2_lookup;

rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP,
SJA1105_SEARCH, &l2_lookup);
if (rc == 0) {
SJA1105_SEARCH, &tmp);
if (rc == 0 && tmp.index != SJA1105_MAX_L2_LOOKUP_COUNT - 1) {
/* Found a static entry and this port is already in the entry's
* port mask => job done
*/
if ((l2_lookup.destports & BIT(port)) && l2_lookup.lockeds)
if ((tmp.destports & BIT(port)) && tmp.lockeds)
return 0;

l2_lookup = tmp;

/* l2_lookup.index is populated by the switch in case it
* found something.
*/
Expand Down

0 comments on commit 8a9e4d4

Please sign in to comment.