mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 14:37:57 +00:00
ee6ba216d8
Fix FDB learning bugs when VLAN filtering is enabled. Signed-off-by: DENG Qingfang <dqfext@gmail.com> Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com> Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
103 lines
3.4 KiB
Diff
103 lines
3.4 KiB
Diff
From 59c8adbc8e2c7f6b46385f36962eadaad3ea2daa Mon Sep 17 00:00:00 2001
|
|
From: DENG Qingfang <dqfext@gmail.com>
|
|
Date: Wed, 4 Aug 2021 00:04:01 +0800
|
|
Subject: [PATCH] net: dsa: mt7530: enable assisted learning on CPU port
|
|
|
|
Consider the following bridge configuration, where bond0 is not
|
|
offloaded:
|
|
|
|
+-- br0 --+
|
|
/ / | \
|
|
/ / | \
|
|
/ | | bond0
|
|
/ | | / \
|
|
swp0 swp1 swp2 swp3 swp4
|
|
. . .
|
|
. . .
|
|
A B C
|
|
|
|
Address learning is enabled on offloaded ports (swp0~2) and the CPU
|
|
port, so when client A sends a packet to C, the following will happen:
|
|
|
|
1. The switch learns that client A can be reached at swp0.
|
|
2. The switch probably already knows that client C can be reached at the
|
|
CPU port, so it forwards the packet to the CPU.
|
|
3. The bridge core knows client C can be reached at bond0, so it
|
|
forwards the packet back to the switch.
|
|
4. The switch learns that client A can be reached at the CPU port.
|
|
5. The switch forwards the packet to either swp3 or swp4, according to
|
|
the packet's tag.
|
|
|
|
That makes client A's MAC address flap between swp0 and the CPU port. If
|
|
client B sends a packet to A, it is possible that the packet is
|
|
forwarded to the CPU. With offload_fwd_mark = 1, the bridge core won't
|
|
forward it back to the switch, resulting in packet loss.
|
|
|
|
As we have the assisted_learning_on_cpu_port in DSA core now, enable
|
|
that and disable hardware learning on the CPU port.
|
|
|
|
Signed-off-by: DENG Qingfang <dqfext@gmail.com>
|
|
Reviewed-by: Vladimir Oltean <oltean@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/dsa/mt7530.c | 14 ++++++++------
|
|
1 file changed, 8 insertions(+), 6 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/mt7530.c
|
|
+++ b/drivers/net/dsa/mt7530.c
|
|
@@ -1747,6 +1747,7 @@ mt7530_setup(struct dsa_switch *ds)
|
|
*/
|
|
dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
|
|
ds->configure_vlan_while_not_filtering = true;
|
|
+ ds->assisted_learning_on_cpu_port = true;
|
|
ds->mtu_enforcement_ingress = true;
|
|
|
|
if (priv->id == ID_MT7530) {
|
|
@@ -1817,15 +1818,15 @@ mt7530_setup(struct dsa_switch *ds)
|
|
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
|
PCR_MATRIX_CLR);
|
|
|
|
+ /* Disable learning by default on all ports */
|
|
+ mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
|
+
|
|
if (dsa_is_cpu_port(ds, i)) {
|
|
ret = mt753x_cpu_port_enable(ds, i);
|
|
if (ret)
|
|
return ret;
|
|
} else {
|
|
mt7530_port_disable(ds, i);
|
|
-
|
|
- /* Disable learning by default on all user ports */
|
|
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
|
}
|
|
|
|
/* Enable consistent egress tag */
|
|
@@ -1981,6 +1982,9 @@ mt7531_setup(struct dsa_switch *ds)
|
|
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
|
PCR_MATRIX_CLR);
|
|
|
|
+ /* Disable learning by default on all ports */
|
|
+ mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
|
+
|
|
mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
|
|
|
|
if (dsa_is_cpu_port(ds, i)) {
|
|
@@ -1989,9 +1993,6 @@ mt7531_setup(struct dsa_switch *ds)
|
|
return ret;
|
|
} else {
|
|
mt7530_port_disable(ds, i);
|
|
-
|
|
- /* Disable learning by default on all user ports */
|
|
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
|
}
|
|
|
|
/* Enable consistent egress tag */
|
|
@@ -2000,6 +2001,7 @@ mt7531_setup(struct dsa_switch *ds)
|
|
}
|
|
|
|
ds->configure_vlan_while_not_filtering = true;
|
|
+ ds->assisted_learning_on_cpu_port = true;
|
|
ds->mtu_enforcement_ingress = true;
|
|
|
|
/* Flush the FDB table */
|