From d34d2baa9173f6e0c0f22d005d18e83d1cb54d8d Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 30 May 2019 00:42:30 +0300 Subject: net: dsa: tag_8021q: Change order of rx_vid setup The 802.1Q tagging performs an unbalanced setup in terms of RX VIDs on the CPU port. For the ingress path of a 802.1Q switch to work, the RX VID of a port needs to be seen as tagged egress on the CPU port. While configuring the other front-panel ports to be part of this VID, for bridge scenarios, the untagged flag is applied even on the CPU port in dsa_switch_vlan_add. This happens because DSA applies the same flags on the CPU port as on the (bridge-controlled) slave ports, and the effect in this case is that the CPU port tagged settings get deleted. Instead of fixing DSA by introducing a way to control VLAN flags on the CPU port (and hence stop inheriting from the slave ports) - a hard, perhaps intractable problem - avoid this situation by moving the setup part of the RX VID on the CPU port after all the other front-panel ports have been added to the VID. Fixes: f9bbe4477c30 ("net: dsa: Optional VLAN-based port separation for switches without tagging") Signed-off-by: Ioana Ciornei Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/tag_8021q.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c index 8ae48c7e1e76..4adec6bbfe59 100644 --- a/net/dsa/tag_8021q.c +++ b/net/dsa/tag_8021q.c @@ -128,10 +128,7 @@ int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int port, bool enabled) u16 flags; if (i == upstream) - /* CPU port needs to see this port's RX VID - * as tagged egress. - */ - flags = 0; + continue; else if (i == port) /* The RX VID is pvid on this port */ flags = BRIDGE_VLAN_INFO_UNTAGGED | @@ -150,6 +147,20 @@ int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int port, bool enabled) return err; } } + + /* CPU port needs to see this port's RX VID + * as tagged egress. + */ + if (enabled) + err = dsa_port_vid_add(upstream_dp, rx_vid, 0); + else + err = dsa_port_vid_del(upstream_dp, rx_vid); + if (err) { + dev_err(ds->dev, "Failed to apply RX VID %d to port %d: %d\n", + rx_vid, port, err); + return err; + } + /* Finally apply the TX VID on this port and on the CPU port */ if (enabled) err = dsa_port_vid_add(dp, tx_vid, BRIDGE_VLAN_INFO_UNTAGGED); -- cgit v1.2.3