All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net 0/6] Fixes for SJA1105 DSA driver
@ 2021-05-24  9:25 Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 1/6] net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S Vladimir Oltean
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

This series contains some minor fixes in the sja1105 driver:
- improved error handling in the probe path
- rejecting an invalid phy-mode specified in the device tree
- register access fix for SJA1105P/Q/R/S for the virtual links through
  the dynamic reconfiguration interface
- handling 2 bridge VLANs where the second is supposed to overwrite the
  first
- making sure that the lack of a pvid results in the actual dropping of
  untagged traffic

Vladimir Oltean (6):
  net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S
  net: dsa: sja1105: call dsa_unregister_switch when allocating memory
    fails
  net: dsa: sja1105: add error handling in sja1105_setup()
  net: dsa: sja1105: error out on unsupported PHY mode
  net: dsa: sja1105: use 4095 as the private VLAN for untagged traffic
  net: dsa: sja1105: update existing VLANs from the bridge VLAN list

 .../net/dsa/sja1105/sja1105_dynamic_config.c  | 23 +++++-
 drivers/net/dsa/sja1105/sja1105_main.c        | 74 +++++++++++++------
 2 files changed, 70 insertions(+), 27 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net 1/6] net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
@ 2021-05-24  9:25 ` Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 2/6] net: dsa: sja1105: call dsa_unregister_switch when allocating memory fails Vladimir Oltean
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

At the beginning of the sja1105_dynamic_config.c file there is a diagram
of the dynamic config interface layout:

 packed_buf

 |
 V
 +-----------------------------------------+------------------+
 |              ENTRY BUFFER               |  COMMAND BUFFER  |
 +-----------------------------------------+------------------+

 <----------------------- packed_size ------------------------>

So in order to pack/unpack the command bits into the buffer,
sja1105_vl_lookup_cmd_packing must first advance the buffer pointer by
the length of the entry. This is similar to what the other *cmd_packing
functions do.

This bug exists because the command packing function for P/Q/R/S was
copied from the E/T generation, and on E/T, the command was actually
embedded within the entry buffer itself.

Fixes: 94f94d4acfb2 ("net: dsa: sja1105: add static tables for virtual links")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 .../net/dsa/sja1105/sja1105_dynamic_config.c  | 23 +++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index b777d3f37573..12cd04b56803 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -167,9 +167,10 @@ enum sja1105_hostcmd {
 	SJA1105_HOSTCMD_INVALIDATE = 4,
 };
 
+/* Command and entry overlap */
 static void
-sja1105_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
-			      enum packing_op op)
+sja1105et_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
+				enum packing_op op)
 {
 	const int size = SJA1105_SIZE_DYN_CMD;
 
@@ -179,6 +180,20 @@ sja1105_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
 	sja1105_packing(buf, &cmd->index,    9,  0, size, op);
 }
 
+/* Command and entry are separate */
+static void
+sja1105pqrs_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
+				  enum packing_op op)
+{
+	u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY;
+	const int size = SJA1105_SIZE_DYN_CMD;
+
+	sja1105_packing(p, &cmd->valid,   31, 31, size, op);
+	sja1105_packing(p, &cmd->errors,  30, 30, size, op);
+	sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
+	sja1105_packing(p, &cmd->index,    9,  0, size, op);
+}
+
 static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr,
 						enum packing_op op)
 {
@@ -641,7 +656,7 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,
 const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
 	[BLK_IDX_VL_LOOKUP] = {
 		.entry_packing = sja1105et_vl_lookup_entry_packing,
-		.cmd_packing = sja1105_vl_lookup_cmd_packing,
+		.cmd_packing = sja1105et_vl_lookup_cmd_packing,
 		.access = OP_WRITE,
 		.max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
 		.packed_size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD,
@@ -725,7 +740,7 @@ const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
 const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
 	[BLK_IDX_VL_LOOKUP] = {
 		.entry_packing = sja1105_vl_lookup_entry_packing,
-		.cmd_packing = sja1105_vl_lookup_cmd_packing,
+		.cmd_packing = sja1105pqrs_vl_lookup_cmd_packing,
 		.access = (OP_READ | OP_WRITE),
 		.max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
 		.packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net 2/6] net: dsa: sja1105: call dsa_unregister_switch when allocating memory fails
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 1/6] net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S Vladimir Oltean
@ 2021-05-24  9:25 ` Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 3/6] net: dsa: sja1105: add error handling in sja1105_setup() Vladimir Oltean
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

Unlike other drivers which pretty much end their .probe() execution with
dsa_register_switch(), the sja1105 does some extra stuff. When that
fails with -ENOMEM, the driver is quick to return that, forgetting to
call dsa_unregister_switch(). Not critical, but a bug nonetheless.

Fixes: 4d7525085a9b ("net: dsa: sja1105: offload the Credit-Based Shaper qdisc")
Fixes: a68578c20a96 ("net: dsa: Make deferred_xmit private to sja1105")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/sja1105/sja1105_main.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 405024b637d6..2248152b4836 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -3646,8 +3646,10 @@ static int sja1105_probe(struct spi_device *spi)
 		priv->cbs = devm_kcalloc(dev, priv->info->num_cbs_shapers,
 					 sizeof(struct sja1105_cbs_entry),
 					 GFP_KERNEL);
-		if (!priv->cbs)
-			return -ENOMEM;
+		if (!priv->cbs) {
+			rc = -ENOMEM;
+			goto out_unregister_switch;
+		}
 	}
 
 	/* Connections between dsa_port and sja1105_port */
@@ -3672,7 +3674,7 @@ static int sja1105_probe(struct spi_device *spi)
 			dev_err(ds->dev,
 				"failed to create deferred xmit thread: %d\n",
 				rc);
-			goto out;
+			goto out_destroy_workers;
 		}
 		skb_queue_head_init(&sp->xmit_queue);
 		sp->xmit_tpid = ETH_P_SJA1105;
@@ -3682,7 +3684,8 @@ static int sja1105_probe(struct spi_device *spi)
 	}
 
 	return 0;
-out:
+
+out_destroy_workers:
 	while (port-- > 0) {
 		struct sja1105_port *sp = &priv->ports[port];
 
@@ -3691,6 +3694,10 @@ static int sja1105_probe(struct spi_device *spi)
 
 		kthread_destroy_worker(sp->xmit_worker);
 	}
+
+out_unregister_switch:
+	dsa_unregister_switch(ds);
+
 	return rc;
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net 3/6] net: dsa: sja1105: add error handling in sja1105_setup()
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 1/6] net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 2/6] net: dsa: sja1105: call dsa_unregister_switch when allocating memory fails Vladimir Oltean
@ 2021-05-24  9:25 ` Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 4/6] net: dsa: sja1105: error out on unsupported PHY mode Vladimir Oltean
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

If any of sja1105_static_config_load(), sja1105_clocking_setup() or
sja1105_devlink_setup() fails, we can't just return in the middle of
sja1105_setup() or memory will leak. Add a cleanup path.

Fixes: 0a7bdbc23d8a ("net: dsa: sja1105: move devlink param code to sja1105_devlink.c")
Fixes: 8aa9ebccae87 ("net: dsa: Introduce driver for NXP SJA1105 5-port L2 switch")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/sja1105/sja1105_main.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 2248152b4836..c7a1be8bbddf 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -2976,13 +2976,13 @@ static int sja1105_setup(struct dsa_switch *ds)
 	rc = sja1105_static_config_load(priv, ports);
 	if (rc < 0) {
 		dev_err(ds->dev, "Failed to load static config: %d\n", rc);
-		return rc;
+		goto out_ptp_clock_unregister;
 	}
 	/* Configure the CGU (PHY link modes and speeds) */
 	rc = sja1105_clocking_setup(priv);
 	if (rc < 0) {
 		dev_err(ds->dev, "Failed to configure MII clocking: %d\n", rc);
-		return rc;
+		goto out_static_config_free;
 	}
 	/* On SJA1105, VLAN filtering per se is always enabled in hardware.
 	 * The only thing we can do to disable it is lie about what the 802.1Q
@@ -3003,7 +3003,7 @@ static int sja1105_setup(struct dsa_switch *ds)
 
 	rc = sja1105_devlink_setup(ds);
 	if (rc < 0)
-		return rc;
+		goto out_static_config_free;
 
 	/* The DSA/switchdev model brings up switch ports in standalone mode by
 	 * default, and that means vlan_filtering is 0 since they're not under
@@ -3012,6 +3012,17 @@ static int sja1105_setup(struct dsa_switch *ds)
 	rtnl_lock();
 	rc = sja1105_setup_8021q_tagging(ds, true);
 	rtnl_unlock();
+	if (rc)
+		goto out_devlink_teardown;
+
+	return 0;
+
+out_devlink_teardown:
+	sja1105_devlink_teardown(ds);
+out_ptp_clock_unregister:
+	sja1105_ptp_clock_unregister(ds);
+out_static_config_free:
+	sja1105_static_config_free(&priv->static_config);
 
 	return rc;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net 4/6] net: dsa: sja1105: error out on unsupported PHY mode
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
                   ` (2 preceding siblings ...)
  2021-05-24  9:25 ` [PATCH net 3/6] net: dsa: sja1105: add error handling in sja1105_setup() Vladimir Oltean
@ 2021-05-24  9:25 ` Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 5/6] net: dsa: sja1105: use 4095 as the private VLAN for untagged traffic Vladimir Oltean
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

The driver continues probing when a port is configured for an
unsupported PHY interface type, instead it should stop.

Fixes: 8aa9ebccae87 ("net: dsa: Introduce driver for NXP SJA1105 5-port L2 switch")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/sja1105/sja1105_main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index c7a1be8bbddf..7f7e0424a442 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -207,6 +207,7 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv,
 		default:
 			dev_err(dev, "Unsupported PHY mode %s!\n",
 				phy_modes(ports[i].phy_mode));
+			return -EINVAL;
 		}
 
 		/* Even though the SerDes port is able to drive SGMII autoneg
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net 5/6] net: dsa: sja1105: use 4095 as the private VLAN for untagged traffic
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
                   ` (3 preceding siblings ...)
  2021-05-24  9:25 ` [PATCH net 4/6] net: dsa: sja1105: error out on unsupported PHY mode Vladimir Oltean
@ 2021-05-24  9:25 ` Vladimir Oltean
  2021-05-24  9:25 ` [PATCH net 6/6] net: dsa: sja1105: update existing VLANs from the bridge VLAN list Vladimir Oltean
  2021-05-24 20:30 ` [PATCH net 0/6] Fixes for SJA1105 DSA driver patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

One thing became visible when writing the blamed commit, and that was
that STP and PTP frames injected by net/dsa/tag_sja1105.c using the
deferred xmit mechanism are always classified to the pvid of the CPU
port, regardless of whatever VLAN there might be in these packets.

So a decision needed to be taken regarding the mechanism through which
we should ensure that delivery of STP and PTP traffic is possible when
we are in a VLAN awareness mode that involves tag_8021q. This is because
tag_8021q is not concerned with managing the pvid of the CPU port, since
as far as tag_8021q is concerned, no traffic should be sent as untagged
from the CPU port. So we end up not actually having a pvid on the CPU
port if we only listen to tag_8021q, and unless we do something about it.

The decision taken at the time was to keep VLAN 1 in the list of
priv->dsa_8021q_vlans, and make it a pvid of the CPU port. This ensures
that STP and PTP frames can always be sent to the outside world.

However there is a problem. If we do the following while we are in
the best_effort_vlan_filtering=true mode:

ip link add br0 type bridge vlan_filtering 1
ip link set swp2 master br0
bridge vlan del dev swp2 vid 1

Then untagged and pvid-tagged frames should be dropped. But we observe
that they aren't, and this is because of the precaution we took that VID
1 is always installed on all ports.

So clearly VLAN 1 is not good for this purpose. What about VLAN 0?
Well, VLAN 0 is managed by the 8021q module, and that module wants to
ensure that 802.1p tagged frames are always received by a port, and are
always transmitted as VLAN-tagged (with VLAN ID 0). Whereas we want our
STP and PTP frames to be untagged if the stack sent them as untagged -
we don't want the driver to just decide out of the blue that it adds
VID 0 to some packets.

So what to do?

Well, there is one other VLAN that is reserved, and that is 4095:
$ ip link add link swp2 name swp2.4095 type vlan id 4095
Error: 8021q: Invalid VLAN id.
$ bridge vlan add dev swp2 vid 4095
Error: bridge: Vlan id is invalid.

After we made this change, VLAN 1 is indeed forwarded and/or dropped
according to the bridge VLAN table, there are no further alterations
done by the sja1105 driver.

Fixes: ec5ae61076d0 ("net: dsa: sja1105: save/restore VLANs using a delta commit method")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/sja1105/sja1105_main.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 7f7e0424a442..dffa7dd83877 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -26,6 +26,7 @@
 #include "sja1105_tas.h"
 
 #define SJA1105_UNKNOWN_MULTICAST	0x010000000000ull
+#define SJA1105_DEFAULT_VLAN		(VLAN_N_VID - 1)
 
 static const struct dsa_switch_ops sja1105_switch_ops;
 
@@ -322,6 +323,13 @@ static int sja1105_init_l2_lookup_params(struct sja1105_private *priv)
 	return 0;
 }
 
+/* Set up a default VLAN for untagged traffic injected from the CPU
+ * using management routes (e.g. STP, PTP) as opposed to tag_8021q.
+ * All DT-defined ports are members of this VLAN, and there are no
+ * restrictions on forwarding (since the CPU selects the destination).
+ * Frames from this VLAN will always be transmitted as untagged, and
+ * neither the bridge nor the 8021q module cannot create this VLAN ID.
+ */
 static int sja1105_init_static_vlan(struct sja1105_private *priv)
 {
 	struct sja1105_table *table;
@@ -331,17 +339,13 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv)
 		.vmemb_port = 0,
 		.vlan_bc = 0,
 		.tag_port = 0,
-		.vlanid = 1,
+		.vlanid = SJA1105_DEFAULT_VLAN,
 	};
 	struct dsa_switch *ds = priv->ds;
 	int port;
 
 	table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP];
 
-	/* The static VLAN table will only contain the initial pvid of 1.
-	 * All other VLANs are to be configured through dynamic entries,
-	 * and kept in the static configuration table as backing memory.
-	 */
 	if (table->entry_count) {
 		kfree(table->entries);
 		table->entry_count = 0;
@@ -354,9 +358,6 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv)
 
 	table->entry_count = 1;
 
-	/* VLAN 1: all DT-defined ports are members; no restrictions on
-	 * forwarding; always transmit as untagged.
-	 */
 	for (port = 0; port < ds->num_ports; port++) {
 		struct sja1105_bridge_vlan *v;
 
@@ -367,15 +368,12 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv)
 		pvid.vlan_bc |= BIT(port);
 		pvid.tag_port &= ~BIT(port);
 
-		/* Let traffic that don't need dsa_8021q (e.g. STP, PTP) be
-		 * transmitted as untagged.
-		 */
 		v = kzalloc(sizeof(*v), GFP_KERNEL);
 		if (!v)
 			return -ENOMEM;
 
 		v->port = port;
-		v->vid = 1;
+		v->vid = SJA1105_DEFAULT_VLAN;
 		v->untagged = true;
 		if (dsa_is_cpu_port(ds, port))
 			v->pvid = true;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net 6/6] net: dsa: sja1105: update existing VLANs from the bridge VLAN list
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
                   ` (4 preceding siblings ...)
  2021-05-24  9:25 ` [PATCH net 5/6] net: dsa: sja1105: use 4095 as the private VLAN for untagged traffic Vladimir Oltean
@ 2021-05-24  9:25 ` Vladimir Oltean
  2021-05-24 20:30 ` [PATCH net 0/6] Fixes for SJA1105 DSA driver patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: Vladimir Oltean @ 2021-05-24  9:25 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, Vladimir Oltean

From: Vladimir Oltean <vladimir.oltean@nxp.com>

When running this sequence of operations:

ip link add br0 type bridge vlan_filtering 1
ip link set swp4 master br0
bridge vlan add dev swp4 vid 1

We observe the traffic sent on swp4 is still untagged, even though the
bridge has overwritten the existing VLAN entry:

port    vlan ids
swp4     1 PVID

br0      1 PVID Egress Untagged

This happens because we didn't consider that the 'bridge vlan add'
command just overwrites VLANs like it's nothing. We treat the 'vid 1
pvid untagged' and the 'vid 1' as two separate VLANs, and the first
still has precedence when calling sja1105_build_vlan_table. Obviously
there is a disagreement regarding semantics, and we end up doing
something unexpected from the PoV of the bridge.

Let's actually consider an "existing VLAN" to be one which is on the
same port, and has the same VLAN ID, as one we already have, and update
it if it has different flags than we do.

The first blamed commit is the one introducing the bug, the second one
is the latest on top of which the bugfix still applies.

Fixes: ec5ae61076d0 ("net: dsa: sja1105: save/restore VLANs using a delta commit method")
Fixes: 5899ee367ab3 ("net: dsa: tag_8021q: add a context structure")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/sja1105/sja1105_main.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index dffa7dd83877..b88d9ef45a1f 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -2816,11 +2816,22 @@ static int sja1105_vlan_add_one(struct dsa_switch *ds, int port, u16 vid,
 	bool pvid = flags & BRIDGE_VLAN_INFO_PVID;
 	struct sja1105_bridge_vlan *v;
 
-	list_for_each_entry(v, vlan_list, list)
-		if (v->port == port && v->vid == vid &&
-		    v->untagged == untagged && v->pvid == pvid)
+	list_for_each_entry(v, vlan_list, list) {
+		if (v->port == port && v->vid == vid) {
 			/* Already added */
-			return 0;
+			if (v->untagged == untagged && v->pvid == pvid)
+				/* Nothing changed */
+				return 0;
+
+			/* It's the same VLAN, but some of the flags changed
+			 * and the user did not bother to delete it first.
+			 * Update it and trigger sja1105_build_vlan_table.
+			 */
+			v->untagged = untagged;
+			v->pvid = pvid;
+			return 1;
+		}
+	}
 
 	v = kzalloc(sizeof(*v), GFP_KERNEL);
 	if (!v) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net 0/6] Fixes for SJA1105 DSA driver
  2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
                   ` (5 preceding siblings ...)
  2021-05-24  9:25 ` [PATCH net 6/6] net: dsa: sja1105: update existing VLANs from the bridge VLAN list Vladimir Oltean
@ 2021-05-24 20:30 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-05-24 20:30 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: kuba, davem, netdev, f.fainelli, andrew, vivien.didelot, vladimir.oltean

Hello:

This series was applied to netdev/net.git (refs/heads/master):

On Mon, 24 May 2021 12:25:21 +0300 you wrote:
> From: Vladimir Oltean <vladimir.oltean@nxp.com>
> 
> This series contains some minor fixes in the sja1105 driver:
> - improved error handling in the probe path
> - rejecting an invalid phy-mode specified in the device tree
> - register access fix for SJA1105P/Q/R/S for the virtual links through
>   the dynamic reconfiguration interface
> - handling 2 bridge VLANs where the second is supposed to overwrite the
>   first
> - making sure that the lack of a pvid results in the actual dropping of
>   untagged traffic
> 
> [...]

Here is the summary with links:
  - [net,1/6] net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S
    https://git.kernel.org/netdev/net/c/ba61cf167cb7
  - [net,2/6] net: dsa: sja1105: call dsa_unregister_switch when allocating memory fails
    https://git.kernel.org/netdev/net/c/dc596e3fe63f
  - [net,3/6] net: dsa: sja1105: add error handling in sja1105_setup()
    https://git.kernel.org/netdev/net/c/cec279a898a3
  - [net,4/6] net: dsa: sja1105: error out on unsupported PHY mode
    https://git.kernel.org/netdev/net/c/6729188d2646
  - [net,5/6] net: dsa: sja1105: use 4095 as the private VLAN for untagged traffic
    https://git.kernel.org/netdev/net/c/ed040abca4c1
  - [net,6/6] net: dsa: sja1105: update existing VLANs from the bridge VLAN list
    https://git.kernel.org/netdev/net/c/b38e659de966

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-05-24 20:30 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-24  9:25 [PATCH net 0/6] Fixes for SJA1105 DSA driver Vladimir Oltean
2021-05-24  9:25 ` [PATCH net 1/6] net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S Vladimir Oltean
2021-05-24  9:25 ` [PATCH net 2/6] net: dsa: sja1105: call dsa_unregister_switch when allocating memory fails Vladimir Oltean
2021-05-24  9:25 ` [PATCH net 3/6] net: dsa: sja1105: add error handling in sja1105_setup() Vladimir Oltean
2021-05-24  9:25 ` [PATCH net 4/6] net: dsa: sja1105: error out on unsupported PHY mode Vladimir Oltean
2021-05-24  9:25 ` [PATCH net 5/6] net: dsa: sja1105: use 4095 as the private VLAN for untagged traffic Vladimir Oltean
2021-05-24  9:25 ` [PATCH net 6/6] net: dsa: sja1105: update existing VLANs from the bridge VLAN list Vladimir Oltean
2021-05-24 20:30 ` [PATCH net 0/6] Fixes for SJA1105 DSA driver patchwork-bot+netdevbpf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.