All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Oltean <olteanv@gmail.com>
To: f.fainelli@gmail.com, vivien.didelot@gmail.com, andrew@lunn.ch,
	davem@davemloft.net
Cc: netdev@vger.kernel.org, Vladimir Oltean <olteanv@gmail.com>
Subject: [PATCH net-next 09/10] net: dsa: sja1105: Use correct dsa_8021q VIDs for FDB commands
Date: Wed, 26 Jun 2019 02:39:41 +0300	[thread overview]
Message-ID: <20190625233942.1946-10-olteanv@gmail.com> (raw)
In-Reply-To: <20190625233942.1946-1-olteanv@gmail.com>

A FDB entry means that "frames that match this VID and DMAC must be
forwarded to this port".

In the case of dsa_8021q however, the VID is not a single one (and
neither two, as my previous patch assumed). The VID can be set either by
the CPU port (1 tx_vid), or by any of the other front-panel port (n-1
rx_vid's).

Fixes: 93647594d8f5 ("net: dsa: sja1105: Hide the dsa_8021q VLANs from the bridge fdb command")
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 drivers/net/dsa/sja1105/sja1105_main.c | 82 ++++++++++++++++++--------
 1 file changed, 56 insertions(+), 26 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index ed0b721c794e..cadee7694935 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1126,44 +1126,60 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
 			   const unsigned char *addr, u16 vid)
 {
 	struct sja1105_private *priv = ds->priv;
-	int rc;
+	u16 rx_vid, tx_vid;
+	int rc, i;
+
+	if (dsa_port_is_vlan_filtering(&ds->ports[port]))
+		return priv->info->fdb_add_cmd(ds, port, addr, vid);
 
 	/* Since we make use of VLANs even when the bridge core doesn't tell us
 	 * to, translate these FDB entries into the correct dsa_8021q ones.
+	 * The basic idea (also repeats for removal below) is:
+	 * - Each of the other front-panel ports needs to be able to forward a
+	 *   pvid-tagged (aka tagged with their rx_vid) frame that matches this
+	 *   DMAC.
+	 * - The CPU port (aka the tx_vid of this port) needs to be able to
+	 *   send a frame matching this DMAC to the specified port.
+	 * For a better picture see net/dsa/tag_8021q.c.
 	 */
-	if (!dsa_port_is_vlan_filtering(&ds->ports[port])) {
-		unsigned int upstream = dsa_upstream_port(priv->ds, port);
-		u16 tx_vid = dsa_8021q_tx_vid(ds, port);
-		u16 rx_vid = dsa_8021q_rx_vid(ds, port);
+	for (i = 0; i < SJA1105_NUM_PORTS; i++) {
+		if (i == port)
+			continue;
+		if (i == dsa_upstream_port(priv->ds, port))
+			continue;
 
-		rc = priv->info->fdb_add_cmd(ds, port, addr, tx_vid);
+		rx_vid = dsa_8021q_rx_vid(ds, i);
+		rc = priv->info->fdb_add_cmd(ds, port, addr, rx_vid);
 		if (rc < 0)
 			return rc;
-		return priv->info->fdb_add_cmd(ds, upstream, addr, rx_vid);
 	}
-	return priv->info->fdb_add_cmd(ds, port, addr, vid);
+	tx_vid = dsa_8021q_tx_vid(ds, port);
+	return priv->info->fdb_add_cmd(ds, port, addr, tx_vid);
 }
 
 static int sja1105_fdb_del(struct dsa_switch *ds, int port,
 			   const unsigned char *addr, u16 vid)
 {
 	struct sja1105_private *priv = ds->priv;
-	int rc;
+	u16 rx_vid, tx_vid;
+	int rc, i;
 
-	/* Since we make use of VLANs even when the bridge core doesn't tell us
-	 * to, translate these FDB entries into the correct dsa_8021q ones.
-	 */
-	if (!dsa_port_is_vlan_filtering(&ds->ports[port])) {
-		unsigned int upstream = dsa_upstream_port(priv->ds, port);
-		u16 tx_vid = dsa_8021q_tx_vid(ds, port);
-		u16 rx_vid = dsa_8021q_rx_vid(ds, port);
+	if (dsa_port_is_vlan_filtering(&ds->ports[port]))
+		return priv->info->fdb_del_cmd(ds, port, addr, vid);
 
-		rc = priv->info->fdb_del_cmd(ds, port, addr, tx_vid);
+	for (i = 0; i < SJA1105_NUM_PORTS; i++) {
+		if (i == port)
+			continue;
+		if (i == dsa_upstream_port(priv->ds, port))
+			continue;
+
+		rx_vid = dsa_8021q_rx_vid(ds, i);
+		rc = priv->info->fdb_del_cmd(ds, port, addr, rx_vid);
 		if (rc < 0)
 			return rc;
-		return priv->info->fdb_del_cmd(ds, upstream, addr, rx_vid);
 	}
-	return priv->info->fdb_del_cmd(ds, port, addr, vid);
+	tx_vid = dsa_8021q_tx_vid(ds, port);
+	return priv->info->fdb_del_cmd(ds, port, addr, tx_vid);
 }
 
 static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
@@ -1171,8 +1187,12 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
 {
 	struct sja1105_private *priv = ds->priv;
 	struct device *dev = ds->dev;
+	u16 rx_vid, tx_vid;
 	int i;
 
+	rx_vid = dsa_8021q_rx_vid(ds, port);
+	tx_vid = dsa_8021q_tx_vid(ds, port);
+
 	for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) {
 		struct sja1105_l2_lookup_entry l2_lookup = {0};
 		u8 macaddr[ETH_ALEN];
@@ -1198,14 +1218,24 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
 			continue;
 		u64_to_ether_addr(l2_lookup.macaddr, macaddr);
 
-		/* We need to hide the dsa_8021q VLAN from the user.
-		 * Convert the TX VID into the pvid that is active in
-		 * standalone and non-vlan_filtering modes, aka 1.
-		 * The RX VID is applied on the CPU port, which is not seen by
-		 * the bridge core anyway, so there's nothing to hide.
+		/* We need to hide the dsa_8021q VLANs from the user. This
+		 * basically means hiding the duplicates and only showing
+		 * the pvid that is supposed to be active in standalone and
+		 * non-vlan_filtering modes (aka 1).
+		 * - For statically added FDB entries (bridge fdb add), we
+		 *   can convert the TX VID (coming from the CPU port) into the
+		 *   pvid and ignore the RX VIDs of the other ports.
+		 * - For dynamically learned FDB entries, a single entry with
+		 *   no duplicates is learned - that which has the real port's
+		 *   pvid, aka RX VID.
 		 */
-		if (!dsa_port_is_vlan_filtering(&ds->ports[port]))
-			l2_lookup.vlanid = 1;
+		if (!dsa_port_is_vlan_filtering(&ds->ports[port])) {
+			if (l2_lookup.vlanid == tx_vid ||
+			    l2_lookup.vlanid == rx_vid)
+				l2_lookup.vlanid = 1;
+			else
+				continue;
+		}
 		cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data);
 	}
 	return 0;
-- 
2.17.1


  parent reply	other threads:[~2019-06-25 23:40 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-25 23:39 [PATCH net-next 00/10] FDB, VLAN and PTP fixes for SJA1105 DSA Vladimir Oltean
2019-06-25 23:39 ` [PATCH net-next 01/10] net: dsa: sja1105: Build PTP support in main DSA driver Vladimir Oltean
2019-06-26  0:25   ` Willem de Bruijn
2019-06-25 23:39 ` [PATCH net-next 02/10] net: dsa: sja1105: Cancel PTP delayed work on unregister Vladimir Oltean
2019-06-26  0:11   ` Willem de Bruijn
2019-06-25 23:39 ` [PATCH net-next 03/10] net: dsa: sja1105: Make vid 1 the default pvid Vladimir Oltean
2019-06-25 23:39 ` [PATCH net-next 04/10] net: dsa: sja1105: Actually implement the P/Q/R/S FDB bits Vladimir Oltean
2019-06-25 23:39 ` [PATCH net-next 05/10] net: dsa: sja1105: Make P/Q/R/S learn MAC addresses Vladimir Oltean
2019-06-25 23:39 ` [PATCH net-next 06/10] net: dsa: sja1105: Back up static FDB entries in kernel memory Vladimir Oltean
2019-06-25 23:39 ` [PATCH net-next 07/10] net: dsa: sja1105: Add a high-level overview of the dynamic config interface Vladimir Oltean
2019-06-25 23:39 ` [PATCH net-next 08/10] net: dsa: sja1105: Populate is_static for FDB entries on P/Q/R/S Vladimir Oltean
2019-06-25 23:39 ` Vladimir Oltean [this message]
2019-06-25 23:39 ` [PATCH net-next 10/10] net: dsa: sja1105: Implement is_static for FDB entries on E/T Vladimir Oltean
2019-06-27 18:04 ` [PATCH net-next 00/10] FDB, VLAN and PTP fixes for SJA1105 DSA David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190625233942.1946-10-olteanv@gmail.com \
    --to=olteanv@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=f.fainelli@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=vivien.didelot@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.