netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA
@ 2020-09-26 19:32 Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 01/15] net: mscc: ocelot: move NPI port configuration to DSA Vladimir Oltean
                   ` (15 more replies)
  0 siblings, 16 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

This is the v2 of a series initially submitted in May:
https://www.spinics.net/lists/netdev/msg651866.html

The end goal is to get rid of the unintuitive code for the flow
dissector that currently exists in the taggers. It can all be replaced
by a single, common function.

Some background work needs to be done for that. Especially the ocelot
driver poses some problems, since it has a different tag length between
RX and TX, and I didn't want to make DSA aware of that, since I could
instead make the tag lengths equal.

Changes in v3:
- Added an optimization (08/15) that makes the generic case not need to
  call the .flow_dissect function pointer. Basically .flow_dissect now
  currently only exists for sja1105.
- Moved the .promisc_on_master property to the tagger structure.
- Added the .tail_tag property to the tagger structure.
- Disabled "suppresscc = all" from my .gitconfig.

Vladimir Oltean (15):
  net: mscc: ocelot: move NPI port configuration to DSA
  net: dsa: allow drivers to request promiscuous mode on master
  net: dsa: tag_sja1105: request promiscuous mode for master
  net: dsa: tag_ocelot: use a short prefix on both ingress and egress
  net: dsa: make the .flow_dissect tagger callback return void
  net: dsa: add a generic procedure for the flow dissector
  net: dsa: point out the tail taggers
  net: flow_dissector: avoid indirect call to DSA .flow_dissect for
    generic case
  net: dsa: tag_brcm: use generic flow dissector procedure
  net: dsa: tag_dsa: use the generic flow dissector procedure
  net: dsa: tag_edsa: use the generic flow dissector procedure
  net: dsa: tag_mtk: use the generic flow dissector procedure
  net: dsa: tag_qca: use the generic flow dissector procedure
  net: dsa: tag_sja1105: use a custom flow dissector procedure
  net: dsa: tag_rtl4_a: use the generic flow dissector procedure

 drivers/net/dsa/ocelot/felix.c             | 31 ++++++++++++++---
 drivers/net/dsa/ocelot/felix_vsc9959.c     | 13 +++++--
 drivers/net/dsa/ocelot/seville_vsc9953.c   | 13 +++++--
 drivers/net/ethernet/mscc/ocelot.c         | 40 ++++------------------
 drivers/net/ethernet/mscc/ocelot_vsc7514.c |  7 ++--
 include/net/dsa.h                          | 37 ++++++++++++++++++--
 include/soc/mscc/ocelot.h                  |  4 +--
 net/core/flow_dissector.c                  | 10 ++++--
 net/dsa/master.c                           | 20 ++++++++++-
 net/dsa/tag_brcm.c                         | 35 +++++++------------
 net/dsa/tag_dsa.c                          |  9 -----
 net/dsa/tag_edsa.c                         |  9 -----
 net/dsa/tag_ksz.c                          |  1 +
 net/dsa/tag_mtk.c                          | 10 ------
 net/dsa/tag_ocelot.c                       | 20 +++++++----
 net/dsa/tag_qca.c                          | 10 ------
 net/dsa/tag_rtl4_a.c                       | 11 ------
 net/dsa/tag_sja1105.c                      | 12 +++++++
 net/dsa/tag_trailer.c                      |  1 +
 19 files changed, 158 insertions(+), 135 deletions(-)

-- 
2.25.1


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

* [PATCH v3 net-next 01/15] net: mscc: ocelot: move NPI port configuration to DSA
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 02/15] net: dsa: allow drivers to request promiscuous mode on master Vladimir Oltean
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem
  Cc: andrew, f.fainelli, vivien.didelot, kuba, Horatiu Vultur,
	Alexandre Belloni, UNGLinuxDriver

Remove the ocelot_configure_cpu() function, which was in fact bringing
up 2 ports: the CPU port module, which both switchdev and DSA have, and
the NPI port, which only DSA has.

The (non-Ethernet) CPU port module is at a fixed index in the analyzer,
whereas the NPI port is selected through the "ethernet" property in the
device tree.

Therefore, the function to set up an NPI port is DSA-specific, so we
move it there, simplifying the ocelot switch library a little bit.

Cc: Horatiu Vultur <horatiu.vultur@microchip.com>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: UNGLinuxDriver <UNGLinuxDriver@microchip.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Actually copied the people from cc to the patch.

 drivers/net/dsa/ocelot/felix.c             | 29 +++++++++++++---
 drivers/net/ethernet/mscc/ocelot.c         | 40 ++++------------------
 drivers/net/ethernet/mscc/ocelot_vsc7514.c |  7 ++--
 include/soc/mscc/ocelot.h                  |  3 --
 4 files changed, 35 insertions(+), 44 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index a56fc50f5be4..b8e192374a32 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -439,6 +439,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 	ocelot->vcap_is2_actions= felix->info->vcap_is2_actions;
 	ocelot->vcap		= felix->info->vcap;
 	ocelot->ops		= felix->info->ops;
+	ocelot->inj_prefix	= OCELOT_TAG_PREFIX_NONE;
+	ocelot->xtr_prefix	= OCELOT_TAG_PREFIX_LONG;
 
 	port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t),
 				 GFP_KERNEL);
@@ -538,6 +540,28 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 	return 0;
 }
 
+/* The CPU port module is connected to the Node Processor Interface (NPI). This
+ * is the mode through which frames can be injected from and extracted to an
+ * external CPU, over Ethernet.
+ */
+static void felix_npi_port_init(struct ocelot *ocelot, int port)
+{
+	ocelot->npi = port;
+
+	ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
+		     QSYS_EXT_CPU_CFG_EXT_CPU_PORT(port),
+		     QSYS_EXT_CPU_CFG);
+
+	/* NPI port Injection/Extraction configuration */
+	ocelot_fields_write(ocelot, port, SYS_PORT_MODE_INCL_XTR_HDR,
+			    ocelot->xtr_prefix);
+	ocelot_fields_write(ocelot, port, SYS_PORT_MODE_INCL_INJ_HDR,
+			    ocelot->inj_prefix);
+
+	/* Disable transmission of pause frames */
+	ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, 0);
+}
+
 /* Hardware initialization done here so that we can allocate structures with
  * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing
  * us to allocate structures twice (leak memory) and map PCI memory twice
@@ -570,11 +594,8 @@ static int felix_setup(struct dsa_switch *ds)
 	for (port = 0; port < ds->num_ports; port++) {
 		ocelot_init_port(ocelot, port);
 
-		/* Bring up the CPU port module and configure the NPI port */
 		if (dsa_is_cpu_port(ds, port))
-			ocelot_configure_cpu(ocelot, port,
-					     OCELOT_TAG_PREFIX_NONE,
-					     OCELOT_TAG_PREFIX_LONG);
+			felix_npi_port_init(ocelot, port);
 
 		/* Set the default QoS Classification based on PCP and DEI
 		 * bits of vlan tag.
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 0445c5ee5551..b9375d96cdbc 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1346,22 +1346,14 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
 }
 EXPORT_SYMBOL(ocelot_init_port);
 
-/* Configure and enable the CPU port module, which is a set of queues.
- * If @npi contains a valid port index, the CPU port module is connected
- * to the Node Processor Interface (NPI). This is the mode through which
- * frames can be injected from and extracted to an external CPU,
- * over Ethernet.
+/* Configure and enable the CPU port module, which is a set of queues
+ * accessible through register MMIO, frame DMA or Ethernet (in case
+ * NPI mode is used).
  */
-void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
-			  enum ocelot_tag_prefix injection,
-			  enum ocelot_tag_prefix extraction)
+static void ocelot_cpu_port_init(struct ocelot *ocelot)
 {
 	int cpu = ocelot->num_phys_ports;
 
-	ocelot->npi = npi;
-	ocelot->inj_prefix = injection;
-	ocelot->xtr_prefix = extraction;
-
 	/* The unicast destination PGID for the CPU port module is unused */
 	ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
 	/* Instead set up a multicast destination PGID for traffic copied to
@@ -1373,31 +1365,13 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
 			 ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
 			 ANA_PORT_PORT_CFG, cpu);
 
-	if (npi >= 0 && npi < ocelot->num_phys_ports) {
-		ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
-			     QSYS_EXT_CPU_CFG_EXT_CPU_PORT(npi),
-			     QSYS_EXT_CPU_CFG);
-
-		/* Enable NPI port */
-		ocelot_fields_write(ocelot, npi,
-				    QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
-		/* NPI port Injection/Extraction configuration */
-		ocelot_fields_write(ocelot, npi, SYS_PORT_MODE_INCL_XTR_HDR,
-				    extraction);
-		ocelot_fields_write(ocelot, npi, SYS_PORT_MODE_INCL_INJ_HDR,
-				    injection);
-
-		/* Disable transmission of pause frames */
-		ocelot_fields_write(ocelot, npi, SYS_PAUSE_CFG_PAUSE_ENA, 0);
-	}
-
 	/* Enable CPU port module */
 	ocelot_fields_write(ocelot, cpu, QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
 	/* CPU port Injection/Extraction configuration */
 	ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_XTR_HDR,
-			    extraction);
+			    ocelot->xtr_prefix);
 	ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_INJ_HDR,
-			    injection);
+			    ocelot->inj_prefix);
 
 	/* Configure the CPU port to be VLAN aware */
 	ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
@@ -1405,7 +1379,6 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
 				 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
 			 ANA_PORT_VLAN_CFG, cpu);
 }
-EXPORT_SYMBOL(ocelot_configure_cpu);
 
 int ocelot_init(struct ocelot *ocelot)
 {
@@ -1445,6 +1418,7 @@ int ocelot_init(struct ocelot *ocelot)
 	ocelot_mact_init(ocelot);
 	ocelot_vlan_init(ocelot);
 	ocelot_vcap_init(ocelot);
+	ocelot_cpu_port_init(ocelot);
 
 	for (port = 0; port < ocelot->num_phys_ports; port++) {
 		/* Clear all counters (5 groups) */
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
index dfb1535f26f2..d7aef2fb9848 100644
--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -930,10 +930,6 @@ static int mscc_ocelot_init_ports(struct platform_device *pdev,
 	if (!ocelot->ports)
 		return -ENOMEM;
 
-	/* No NPI port */
-	ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
-			     OCELOT_TAG_PREFIX_NONE);
-
 	for_each_available_child_of_node(ports, portnp) {
 		struct ocelot_port_private *priv;
 		struct ocelot_port *ocelot_port;
@@ -1120,6 +1116,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
 	ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
 	ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
 	ocelot->vcap = vsc7514_vcap_props;
+	ocelot->inj_prefix = OCELOT_TAG_PREFIX_NONE;
+	ocelot->xtr_prefix = OCELOT_TAG_PREFIX_NONE;
+	ocelot->npi = -1;
 
 	err = ocelot_init(ocelot);
 	if (err)
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 3105bbb6cdcf..349e839c4c18 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -672,9 +672,6 @@ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
 int ocelot_regfields_init(struct ocelot *ocelot,
 			  const struct reg_field *const regfields);
 struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res);
-void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
-			  enum ocelot_tag_prefix injection,
-			  enum ocelot_tag_prefix extraction);
 int ocelot_init(struct ocelot *ocelot);
 void ocelot_deinit(struct ocelot *ocelot);
 void ocelot_init_port(struct ocelot *ocelot, int port);
-- 
2.25.1


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

* [PATCH v3 net-next 02/15] net: dsa: allow drivers to request promiscuous mode on master
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 01/15] net: mscc: ocelot: move NPI port configuration to DSA Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 20:22   ` Andrew Lunn
  2020-09-26 19:32 ` [PATCH v3 net-next 03/15] net: dsa: tag_sja1105: request promiscuous mode for master Vladimir Oltean
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

Currently DSA assumes that taggers don't mess with the destination MAC
address of the frames on RX. That is not always the case. Some DSA
headers are placed before the Ethernet header (ocelot), and others
simply mangle random bytes from the destination MAC address (sja1105
with its incl_srcpt option).

Currently the DSA master goes to promiscuous mode automatically when the
slave devices go too (such as when enslaved to a bridge), but in
standalone mode this is a problem that needs to be dealt with.

So give drivers the possibility to signal that their tagging protocol
will get randomly dropped otherwise, and let DSA deal with fixing that.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Make "promisc_on_master" a tagger property.

 include/net/dsa.h |  6 ++++++
 net/dsa/master.c  | 20 +++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index d16057c5987a..46019edc32cb 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -84,6 +84,12 @@ struct dsa_device_ops {
 	unsigned int overhead;
 	const char *name;
 	enum dsa_tag_protocol proto;
+	/* Some tagging protocols either mangle or shift the destination MAC
+	 * address, in which case the DSA master would drop packets on ingress
+	 * if what it understands out of the destination MAC address is not in
+	 * its RX filter.
+	 */
+	bool promisc_on_master;
 };
 
 /* This structure defines the control interfaces that are overlayed by the
diff --git a/net/dsa/master.c b/net/dsa/master.c
index 61615ebc70e9..c91de041a91d 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -259,6 +259,18 @@ static void dsa_netdev_ops_set(struct net_device *dev,
 	dev->dsa_ptr->netdev_ops = ops;
 }
 
+static void dsa_master_set_promiscuity(struct net_device *dev, int inc)
+{
+	const struct dsa_device_ops *ops = dev->dsa_ptr->tag_ops;
+
+	if (!ops->promisc_on_master)
+		return;
+
+	rtnl_lock();
+	dev_set_promiscuity(dev, inc);
+	rtnl_unlock();
+}
+
 static ssize_t tagging_show(struct device *d, struct device_attribute *attr,
 			    char *buf)
 {
@@ -314,9 +326,12 @@ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
 	dev->dsa_ptr = cpu_dp;
 	lockdep_set_class(&dev->addr_list_lock,
 			  &dsa_master_addr_list_lock_key);
+
+	dsa_master_set_promiscuity(dev, 1);
+
 	ret = dsa_master_ethtool_setup(dev);
 	if (ret)
-		return ret;
+		goto out_err_reset_promisc;
 
 	dsa_netdev_ops_set(dev, &dsa_netdev_ops);
 
@@ -329,6 +344,8 @@ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
 out_err_ndo_teardown:
 	dsa_netdev_ops_set(dev, NULL);
 	dsa_master_ethtool_teardown(dev);
+out_err_reset_promisc:
+	dsa_master_set_promiscuity(dev, -1);
 	return ret;
 }
 
@@ -338,6 +355,7 @@ void dsa_master_teardown(struct net_device *dev)
 	dsa_netdev_ops_set(dev, NULL);
 	dsa_master_ethtool_teardown(dev);
 	dsa_master_reset_mtu(dev);
+	dsa_master_set_promiscuity(dev, -1);
 
 	dev->dsa_ptr = NULL;
 
-- 
2.25.1


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

* [PATCH v3 net-next 03/15] net: dsa: tag_sja1105: request promiscuous mode for master
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 01/15] net: mscc: ocelot: move NPI port configuration to DSA Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 02/15] net: dsa: allow drivers to request promiscuous mode on master Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 20:22   ` Andrew Lunn
  2020-09-26 19:32 ` [PATCH v3 net-next 04/15] net: dsa: tag_ocelot: use a short prefix on both ingress and egress Vladimir Oltean
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

Currently PTP is broken when ports are in standalone mode (the tagger
keeps printing this message):

sja1105 spi0.1: Expected meta frame, is 01-80-c2-00-00-0e in the DSA master multicast filter?

Sure, one might say "simply add 01-80-c2-00-00-0e to the master's RX
filter" but things become more complicated because:

- Actually all frames in the 01-80-c2-xx-xx-xx and 01-1b-19-xx-xx-xx
  range are trapped to the CPU automatically
- The switch mangles bytes 3 and 4 of the MAC address via the incl_srcpt
  ("include source port [in the DMAC]") option, which is how source port
  and switch id identification is done for link-local traffic on RX. But
  this means that an address installed to the RX filter would, at the
  end of the day, not correspond to the final address seen by the DSA
  master.

Assume RX filtering lists on DSA masters are typically too small to
include all necessary addresses for PTP to work properly on sja1105, and
just request promiscuous mode unconditionally.

Just an example:
Assuming the following addresses are trapped to the CPU:
01-80-c2-00-00-00 to 01-80-c2-00-00-ff
01-1b-19-00-00-00 to 01-1b-19-00-00-ff

These are 512 addresses.
Now let's say this is a board with 3 switches, and 4 ports per switch.
The 512 addresses become 6144 addresses that must be managed by the DSA
master's RX filtering lists.

This may be refined in the future, but for now, it is simply not worth
it to add the additional addresses to the master's RX filter, so simply
request it to become promiscuous as soon as the driver probes.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Move this setting from the driver code to the tagger code.

 net/dsa/tag_sja1105.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 3710f9daa46d..36ebd5878061 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -353,6 +353,7 @@ static const struct dsa_device_ops sja1105_netdev_ops = {
 	.rcv = sja1105_rcv,
 	.filter = sja1105_filter,
 	.overhead = VLAN_HLEN,
+	.promisc_on_master = true,
 };
 
 MODULE_LICENSE("GPL v2");
-- 
2.25.1


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

* [PATCH v3 net-next 04/15] net: dsa: tag_ocelot: use a short prefix on both ingress and egress
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (2 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 03/15] net: dsa: tag_sja1105: request promiscuous mode for master Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 05/15] net: dsa: make the .flow_dissect tagger callback return void Vladimir Oltean
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

There are 2 goals that we follow:

- Reduce the header size
- Make the header size equal between RX and TX

The issue that required long prefix on RX was the fact that the ocelot
DSA tag, being put before Ethernet as it is, would overlap with the area
that a DSA master uses for RX filtering (destination MAC address
mainly).

Now that we can ask DSA to put the master in promiscuous mode, in theory
we could remove the prefix altogether and call it a day, but it looks
like we can't. Using no prefix on ingress, some packets (such as ICMP)
would be received, while others (such as PTP) would not be received.
This is because the DSA master we use (enetc) triggers parse errors
("MAC rx frame errors") presumably because it sees Ethernet frames with
a bad length. And indeed, when using no prefix, the EtherType (bytes
12-13 of the frame, bits 96-111) falls over the REW_VAL field from the
extraction header, aka the PTP timestamp.

When turning the short (32-bit) prefix on, the EtherType overlaps with
bits 64-79 of the extraction header, which are a reserved area
transmitted as zero by the switch. The packets are not dropped by the
DSA master with a short prefix. Actually, the frames look like this in
tcpdump (below is a PTP frame, with an extra dsa_8021q tag - dadb 0482 -
added by a downstream sja1105).

89:0c:a9:f2:01:00 > 88:80:00:0a:00:1d, 802.3, length 0: LLC, \
	dsap Unknown (0x10) Individual, ssap ProWay NM (0x0e) Response, \
	ctrl 0x0004: Information, send seq 2, rcv seq 0, \
	Flags [Response], length 78

0x0000:  8880 000a 001d 890c a9f2 0100 0000 100f  ................
0x0010:  0400 0000 0180 c200 000e 001f 7b63 0248  ............{c.H
0x0020:  dadb 0482 88f7 1202 0036 0000 0000 0000  .........6......
0x0030:  0000 0000 0000 0000 0000 001f 7bff fe63  ............{..c
0x0040:  0248 0001 1f81 0500 0000 0000 0000 0000  .H..............
0x0050:  0000 0000 0000 0000 0000 0000            ............

So the short prefix is our new default: we've shortened our RX frames by
12 octets, increased TX by 4, and headers are now equal between RX and
TX. Note that we still need promiscuous mode for the DSA master to not
drop it.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
None.

 drivers/net/dsa/ocelot/felix.c           |  6 +++---
 drivers/net/dsa/ocelot/felix_vsc9959.c   | 13 ++++++++++---
 drivers/net/dsa/ocelot/seville_vsc9953.c | 13 ++++++++++---
 include/soc/mscc/ocelot.h                |  1 +
 net/dsa/tag_ocelot.c                     | 20 +++++++++++++-------
 5 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index b8e192374a32..ab3ee5c3fd02 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -439,8 +439,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 	ocelot->vcap_is2_actions= felix->info->vcap_is2_actions;
 	ocelot->vcap		= felix->info->vcap;
 	ocelot->ops		= felix->info->ops;
-	ocelot->inj_prefix	= OCELOT_TAG_PREFIX_NONE;
-	ocelot->xtr_prefix	= OCELOT_TAG_PREFIX_LONG;
+	ocelot->inj_prefix	= OCELOT_TAG_PREFIX_SHORT;
+	ocelot->xtr_prefix	= OCELOT_TAG_PREFIX_SHORT;
 
 	port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t),
 				 GFP_KERNEL);
@@ -511,7 +511,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 			return PTR_ERR(target);
 		}
 
-		template = devm_kzalloc(ocelot->dev, OCELOT_TAG_LEN,
+		template = devm_kzalloc(ocelot->dev, OCELOT_TOTAL_TAG_LEN,
 					GFP_KERNEL);
 		if (!template) {
 			dev_err(ocelot->dev,
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 3ab6d6847c5b..2e9270c00096 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -1155,6 +1155,8 @@ static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port)
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
 	u8 *template = ocelot_port->xmit_template;
 	u64 bypass, dest, src;
+	__be32 *prefix;
+	u8 *injection;
 
 	/* Set the source port as the CPU port module and not the
 	 * NPI port
@@ -1163,9 +1165,14 @@ static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port)
 	dest = BIT(port);
 	bypass = true;
 
-	packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
-	packing(template, &dest,    68,  56, OCELOT_TAG_LEN, PACK, 0);
-	packing(template, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);
+	injection = template + OCELOT_SHORT_PREFIX_LEN;
+	prefix = (__be32 *)template;
+
+	packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
+	packing(injection, &dest,    68,  56, OCELOT_TAG_LEN, PACK, 0);
+	packing(injection, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);
+
+	*prefix = cpu_to_be32(0x8880000a);
 }
 
 static const struct felix_info felix_info_vsc9959 = {
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index b0ff90c0ae16..e28dd600f464 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -1003,6 +1003,8 @@ static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port)
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
 	u8 *template = ocelot_port->xmit_template;
 	u64 bypass, dest, src;
+	__be32 *prefix;
+	u8 *injection;
 
 	/* Set the source port as the CPU port module and not the
 	 * NPI port
@@ -1011,9 +1013,14 @@ static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port)
 	dest = BIT(port);
 	bypass = true;
 
-	packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
-	packing(template, &dest,    67,  57, OCELOT_TAG_LEN, PACK, 0);
-	packing(template, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);
+	injection = template + OCELOT_SHORT_PREFIX_LEN;
+	prefix = (__be32 *)template;
+
+	packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
+	packing(injection, &dest,    67,  57, OCELOT_TAG_LEN, PACK, 0);
+	packing(injection, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);
+
+	*prefix = cpu_to_be32(0x88800005);
 }
 
 static const struct felix_info seville_info_vsc9953 = {
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 349e839c4c18..3093385f6147 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -101,6 +101,7 @@
 #define OCELOT_TAG_LEN			16
 #define OCELOT_SHORT_PREFIX_LEN		4
 #define OCELOT_LONG_PREFIX_LEN		16
+#define OCELOT_TOTAL_TAG_LEN	(OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN)
 
 #define OCELOT_SPEED_2500		0
 #define OCELOT_SPEED_1000		1
diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c
index d1a7e224adff..ec16badb7812 100644
--- a/net/dsa/tag_ocelot.c
+++ b/net/dsa/tag_ocelot.c
@@ -141,10 +141,12 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
 	struct dsa_switch *ds = dp->ds;
 	struct ocelot *ocelot = ds->priv;
 	struct ocelot_port *ocelot_port;
+	u8 *prefix, *injection;
 	u64 qos_class, rew_op;
-	u8 *injection;
+	int err;
 
-	if (unlikely(skb_cow_head(skb, OCELOT_TAG_LEN) < 0)) {
+	err = skb_cow_head(skb, OCELOT_TOTAL_TAG_LEN);
+	if (unlikely(err < 0)) {
 		netdev_err(netdev, "Cannot make room for tag.\n");
 		return NULL;
 	}
@@ -153,7 +155,10 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
 
 	injection = skb_push(skb, OCELOT_TAG_LEN);
 
-	memcpy(injection, ocelot_port->xmit_template, OCELOT_TAG_LEN);
+	prefix = skb_push(skb, OCELOT_SHORT_PREFIX_LEN);
+
+	memcpy(prefix, ocelot_port->xmit_template, OCELOT_TOTAL_TAG_LEN);
+
 	/* Fix up the fields which are not statically determined
 	 * in the template
 	 */
@@ -187,11 +192,11 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
 	 * so it points to the beginning of the frame.
 	 */
 	skb_push(skb, ETH_HLEN);
-	/* We don't care about the long prefix, it is just for easy entrance
+	/* We don't care about the short prefix, it is just for easy entrance
 	 * into the DSA master's RX filter. Discard it now by moving it into
 	 * the headroom.
 	 */
-	skb_pull(skb, OCELOT_LONG_PREFIX_LEN);
+	skb_pull(skb, OCELOT_SHORT_PREFIX_LEN);
 	/* And skb->data now points to the extraction frame header.
 	 * Keep a pointer to it.
 	 */
@@ -205,7 +210,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
 	skb_pull(skb, ETH_HLEN);
 
 	/* Remove from inet csum the extraction header */
-	skb_postpull_rcsum(skb, start, OCELOT_LONG_PREFIX_LEN + OCELOT_TAG_LEN);
+	skb_postpull_rcsum(skb, start, OCELOT_TOTAL_TAG_LEN);
 
 	packing(extraction, &src_port,  46, 43, OCELOT_TAG_LEN, UNPACK, 0);
 	packing(extraction, &qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0);
@@ -231,7 +236,8 @@ static const struct dsa_device_ops ocelot_netdev_ops = {
 	.proto			= DSA_TAG_PROTO_OCELOT,
 	.xmit			= ocelot_xmit,
 	.rcv			= ocelot_rcv,
-	.overhead		= OCELOT_TAG_LEN + OCELOT_LONG_PREFIX_LEN,
+	.overhead		= OCELOT_TOTAL_TAG_LEN,
+	.promisc_on_master	= true,
 };
 
 MODULE_LICENSE("GPL v2");
-- 
2.25.1


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

* [PATCH v3 net-next 05/15] net: dsa: make the .flow_dissect tagger callback return void
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (3 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 04/15] net: dsa: tag_ocelot: use a short prefix on both ingress and egress Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector Vladimir Oltean
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

There is no tagger that returns anything other than zero, so just change
the return type appropriately.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
Changes in v3:
None.

 include/net/dsa.h         | 4 ++--
 net/core/flow_dissector.c | 4 ++--
 net/dsa/tag_brcm.c        | 5 ++---
 net/dsa/tag_dsa.c         | 5 ++---
 net/dsa/tag_edsa.c        | 5 ++---
 net/dsa/tag_mtk.c         | 6 ++----
 net/dsa/tag_qca.c         | 6 ++----
 net/dsa/tag_rtl4_a.c      | 6 ++----
 8 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 46019edc32cb..98d339311898 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -74,8 +74,8 @@ struct dsa_device_ops {
 	struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
 	struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
 			       struct packet_type *pt);
-	int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
-			    int *offset);
+	void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
+			     int *offset);
 	/* Used to determine which traffic should match the DSA filter in
 	 * eth_type_trans, and which, if any, should bypass it and be processed
 	 * as regular on the master net device.
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 29806eb765cf..13cc4c0a8863 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -932,8 +932,8 @@ bool __skb_flow_dissect(const struct net *net,
 			int offset = 0;
 
 			ops = skb->dev->dsa_ptr->tag_ops;
-			if (ops->flow_dissect &&
-			    !ops->flow_dissect(skb, &proto, &offset)) {
+			if (ops->flow_dissect) {
+				ops->flow_dissect(skb, &proto, &offset);
 				hlen -= offset;
 				nhoff += offset;
 			}
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index 1dab212a294f..610bc7469667 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -150,8 +150,8 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
 	return skb;
 }
 
-static int brcm_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				 int *offset)
+static void brcm_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				  int *offset)
 {
 	/* We have been called on the DSA master network device after
 	 * eth_type_trans() which pulled the Ethernet header already.
@@ -168,7 +168,6 @@ static int brcm_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
 	 */
 	*offset = BRCM_TAG_LEN;
 	*proto = ((__be16 *)skb->data)[1];
-	return 0;
 }
 #endif
 
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index 7ddec9794477..ef15aee58dfc 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -142,12 +142,11 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static int dsa_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				int *offset)
+static void dsa_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				 int *offset)
 {
 	*offset = 4;
 	*proto = ((__be16 *)skb->data)[1];
-	return 0;
 }
 
 static const struct dsa_device_ops dsa_netdev_ops = {
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index d6200ff98200..275e7d931b1a 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -192,12 +192,11 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static int edsa_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				 int *offset)
+static void edsa_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				  int *offset)
 {
 	*offset = 8;
 	*proto = ((__be16 *)skb->data)[3];
-	return 0;
 }
 
 static const struct dsa_device_ops edsa_netdev_ops = {
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index f602fc758d68..2aba17b43e69 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -105,13 +105,11 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static int mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				int *offset)
+static void mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				 int *offset)
 {
 	*offset = 4;
 	*proto = ((__be16 *)skb->data)[1];
-
-	return 0;
 }
 
 static const struct dsa_device_ops mtk_netdev_ops = {
diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
index 7066f5e697d7..a75c6b20c215 100644
--- a/net/dsa/tag_qca.c
+++ b/net/dsa/tag_qca.c
@@ -89,13 +89,11 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static int qca_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-                                int *offset)
+static void qca_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				 int *offset)
 {
 	*offset = QCA_HDR_LEN;
 	*proto = ((__be16 *)skb->data)[0];
-
-	return 0;
 }
 
 static const struct dsa_device_ops qca_netdev_ops = {
diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c
index 7b63010fa87b..868980ba1fcd 100644
--- a/net/dsa/tag_rtl4_a.c
+++ b/net/dsa/tag_rtl4_a.c
@@ -106,14 +106,12 @@ static struct sk_buff *rtl4a_tag_rcv(struct sk_buff *skb,
 	return skb;
 }
 
-static int rtl4a_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				  int *offset)
+static void rtl4a_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				   int *offset)
 {
 	*offset = RTL4_A_HDR_LEN;
 	/* Skip past the tag and fetch the encapsulated Ethertype */
 	*proto = ((__be16 *)skb->data)[1];
-
-	return 0;
 }
 
 static const struct dsa_device_ops rtl4a_netdev_ops = {
-- 
2.25.1


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

* [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (4 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 05/15] net: dsa: make the .flow_dissect tagger callback return void Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 20:25   ` Andrew Lunn
  2020-09-26 20:33   ` Andrew Lunn
  2020-09-26 19:32 ` [PATCH v3 net-next 07/15] net: dsa: point out the tail taggers Vladimir Oltean
                   ` (9 subsequent siblings)
  15 siblings, 2 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

For all DSA formats that don't use tail tags, it looks like behind the
obscure number crunching they're all doing the same thing: locating the
real EtherType behind the DSA tag. Nonetheless, this is not immediately
obvious, so create a generic helper for those DSA taggers that put the
header before the EtherType.

Another assumption for the generic function is that the DSA tags are of
equal length on RX and on TX. Prior to the previous patch, this was not
true for ocelot and for gswip. The problem was resolved for ocelot, but
for gswip it still remains, so that can't use this helper yet.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Made this a static inline function callable from the outside world.

 include/net/dsa.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 98d339311898..817fab5e2c21 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -711,6 +711,32 @@ static inline bool dsa_can_decode(const struct sk_buff *skb,
 	return false;
 }
 
+/* All DSA tags that push the EtherType to the right (basically all except tail
+ * tags, which don't break dissection) can be treated the same from the
+ * perspective of the flow dissector.
+ *
+ * We need to return:
+ *  - offset: the (B - A) difference between:
+ *    A. the position of the real EtherType and
+ *    B. the current skb->data (aka ETH_HLEN bytes into the frame, aka 2 bytes
+ *       after the normal EtherType was supposed to be)
+ *    The offset in bytes is exactly equal to the tagger overhead (and half of
+ *    that, in __be16 shorts).
+ *
+ *  - proto: the value of the real EtherType.
+ */
+static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
+						__be16 *proto, int *offset)
+{
+#if IS_ENABLED(CONFIG_NET_DSA)
+	const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops;
+	int tag_len = ops->overhead;
+
+	*offset = tag_len;
+	*proto = ((__be16 *)skb->data)[(tag_len / 2) - 1];
+#endif
+}
+
 #if IS_ENABLED(CONFIG_NET_DSA)
 static inline int __dsa_netdevice_ops_check(struct net_device *dev)
 {
-- 
2.25.1


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

* [PATCH v3 net-next 07/15] net: dsa: point out the tail taggers
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (5 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 20:27   ` Andrew Lunn
  2020-09-26 19:32 ` [PATCH v3 net-next 08/15] net: flow_dissector: avoid indirect call to DSA .flow_dissect for generic case Vladimir Oltean
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

The Marvell 88E6060 uses tag_trailer.c and the KSZ8795, KSZ9477 and
KSZ9893 switches also use tail tags.

Tell that to the DSA core, since this makes a difference for the flow
dissector. Most switches break the parsing of frame headers, but these
ones don't, so no flow dissector adjustment needs to be done for them.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Patch is new.

 include/net/dsa.h     | 1 +
 net/dsa/tag_ksz.c     | 1 +
 net/dsa/tag_trailer.c | 1 +
 3 files changed, 3 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 817fab5e2c21..b502a63d196e 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -90,6 +90,7 @@ struct dsa_device_ops {
 	 * its RX filter.
 	 */
 	bool promisc_on_master;
+	bool tail_tag;
 };
 
 /* This structure defines the control interfaces that are overlayed by the
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index bd1a3158d79a..945a9bd5ba35 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -237,6 +237,7 @@ static const struct dsa_device_ops ksz9893_netdev_ops = {
 	.xmit	= ksz9893_xmit,
 	.rcv	= ksz9477_rcv,
 	.overhead = KSZ_INGRESS_TAG_LEN,
+	.tail_tag = true,
 };
 
 DSA_TAG_DRIVER(ksz9893_netdev_ops);
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index 4f8ab62f0208..3a1cc24a4f0a 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -83,6 +83,7 @@ static const struct dsa_device_ops trailer_netdev_ops = {
 	.xmit	= trailer_xmit,
 	.rcv	= trailer_rcv,
 	.overhead = 4,
+	.tail_tag = true,
 };
 
 MODULE_LICENSE("GPL");
-- 
2.25.1


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

* [PATCH v3 net-next 08/15] net: flow_dissector: avoid indirect call to DSA .flow_dissect for generic case
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (6 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 07/15] net: dsa: point out the tail taggers Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 09/15] net: dsa: tag_brcm: use generic flow dissector procedure Vladimir Oltean
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

With the recent mitigations against speculative execution exploits,
indirect function calls are more expensive and it would be good to avoid
them where possible.

In the case of DSA, most switch taggers will shift the EtherType and
next headers by a fixed amount equal to that tag's length in bytes.
So we can use a generic procedure to determine that, without calling
into custom tagger code. However we still leave the flow_dissect method
inside struct dsa_device_ops as an override for the generic function.

Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Patch is new.

 net/core/flow_dissector.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 13cc4c0a8863..e21950a2c897 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -932,8 +932,14 @@ bool __skb_flow_dissect(const struct net *net,
 			int offset = 0;
 
 			ops = skb->dev->dsa_ptr->tag_ops;
-			if (ops->flow_dissect) {
-				ops->flow_dissect(skb, &proto, &offset);
+			/* Tail taggers don't break flow dissection */
+			if (!ops->tail_tag) {
+				if (ops->flow_dissect)
+					ops->flow_dissect(skb, &proto, &offset);
+				else
+					dsa_tag_generic_flow_dissect(skb,
+								     &proto,
+								     &offset);
 				hlen -= offset;
 				nhoff += offset;
 			}
-- 
2.25.1


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

* [PATCH v3 net-next 09/15] net: dsa: tag_brcm: use generic flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (7 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 08/15] net: flow_dissector: avoid indirect call to DSA .flow_dissect for generic case Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 10/15] net: dsa: tag_dsa: use the " Vladimir Oltean
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

There are 2 Broadcom tags in use, one places the DSA tag before the
Ethernet destination MAC address, and the other before the EtherType.
Nonetheless, both displace the rest of the headers, so this tagger can
use the generic flow dissector procedure which accounts for that.

The ASCII art drawing is a good reference though, so keep it but move it
somewhere else.

Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Remove the .flow_dissect callback altogether.
Actually copy the people from cc to the patch.

 net/dsa/tag_brcm.c | 34 ++++++++++++----------------------
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index 610bc7469667..69d6b8c597a9 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -107,6 +107,18 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
 	return skb;
 }
 
+/* Frames with this tag have one of these two layouts:
+ * -----------------------------------
+ * | MAC DA | MAC SA | 4b tag | Type | DSA_TAG_PROTO_BRCM
+ * -----------------------------------
+ * -----------------------------------
+ * | 4b tag | MAC DA | MAC SA | Type | DSA_TAG_PROTO_BRCM_PREPEND
+ * -----------------------------------
+ * In both cases, at receive time, skb->data points 2 bytes before the actual
+ * Ethernet type field and we have an offset of 4bytes between where skb->data
+ * and where the payload starts. So the same low-level receive function can be
+ * used.
+ */
 static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
 				       struct net_device *dev,
 				       struct packet_type *pt,
@@ -149,26 +161,6 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
 
 	return skb;
 }
-
-static void brcm_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				  int *offset)
-{
-	/* We have been called on the DSA master network device after
-	 * eth_type_trans() which pulled the Ethernet header already.
-	 * Frames have one of these two layouts:
-	 * -----------------------------------
-	 * | MAC DA | MAC SA | 4b tag | Type | DSA_TAG_PROTO_BRCM
-	 * -----------------------------------
-	 * -----------------------------------
-	 * | 4b tag | MAC DA | MAC SA | Type | DSA_TAG_PROTO_BRCM_PREPEND
-	 * -----------------------------------
-	 * skb->data points 2 bytes before the actual Ethernet type field and
-	 * we have an offset of 4bytes between where skb->data and where the
-	 * payload starts.
-	 */
-	*offset = BRCM_TAG_LEN;
-	*proto = ((__be16 *)skb->data)[1];
-}
 #endif
 
 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
@@ -204,7 +196,6 @@ static const struct dsa_device_ops brcm_netdev_ops = {
 	.xmit	= brcm_tag_xmit,
 	.rcv	= brcm_tag_rcv,
 	.overhead = BRCM_TAG_LEN,
-	.flow_dissect = brcm_tag_flow_dissect,
 };
 
 DSA_TAG_DRIVER(brcm_netdev_ops);
@@ -239,7 +230,6 @@ static const struct dsa_device_ops brcm_prepend_netdev_ops = {
 	.xmit	= brcm_tag_xmit_prepend,
 	.rcv	= brcm_tag_rcv_prepend,
 	.overhead = BRCM_TAG_LEN,
-	.flow_dissect = brcm_tag_flow_dissect,
 };
 
 DSA_TAG_DRIVER(brcm_prepend_netdev_ops);
-- 
2.25.1


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

* [PATCH v3 net-next 10/15] net: dsa: tag_dsa: use the generic flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (8 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 09/15] net: dsa: tag_brcm: use generic flow dissector procedure Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 21:08   ` Andrew Lunn
  2020-09-26 19:32 ` [PATCH v3 net-next 11/15] net: dsa: tag_edsa: " Vladimir Oltean
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

Remove the .flow_dissect procedure, so the flow dissector will call the
generic variant which works for this tagging protocol.

Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Remove the .flow_dissect callback altogether.
Actually copy the people from cc to the patch.

 net/dsa/tag_dsa.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index ef15aee58dfc..0b756fae68a5 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -142,19 +142,11 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static void dsa_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				 int *offset)
-{
-	*offset = 4;
-	*proto = ((__be16 *)skb->data)[1];
-}
-
 static const struct dsa_device_ops dsa_netdev_ops = {
 	.name	= "dsa",
 	.proto	= DSA_TAG_PROTO_DSA,
 	.xmit	= dsa_xmit,
 	.rcv	= dsa_rcv,
-	.flow_dissect   = dsa_tag_flow_dissect,
 	.overhead = DSA_HLEN,
 };
 
-- 
2.25.1


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

* [PATCH v3 net-next 11/15] net: dsa: tag_edsa: use the generic flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (9 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 10/15] net: dsa: tag_dsa: use the " Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 21:08   ` Andrew Lunn
  2020-09-26 19:32 ` [PATCH v3 net-next 12/15] net: dsa: tag_mtk: " Vladimir Oltean
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

Remove the .flow_dissect procedure, so the flow dissector will call the
generic variant which works for this tagging protocol.

Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Remove the .flow_dissect callback altogether.
Actually copy the people from cc to the patch.

 net/dsa/tag_edsa.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 275e7d931b1a..120614240319 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -192,19 +192,11 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static void edsa_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				  int *offset)
-{
-	*offset = 8;
-	*proto = ((__be16 *)skb->data)[3];
-}
-
 static const struct dsa_device_ops edsa_netdev_ops = {
 	.name	= "edsa",
 	.proto	= DSA_TAG_PROTO_EDSA,
 	.xmit	= edsa_xmit,
 	.rcv	= edsa_rcv,
-	.flow_dissect   = edsa_tag_flow_dissect,
 	.overhead = EDSA_HLEN,
 };
 
-- 
2.25.1


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

* [PATCH v3 net-next 12/15] net: dsa: tag_mtk: use the generic flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (10 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 11/15] net: dsa: tag_edsa: " Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 13/15] net: dsa: tag_qca: " Vladimir Oltean
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem
  Cc: andrew, f.fainelli, vivien.didelot, kuba, DENG Qingfang,
	Sean Wang, John Crispin

Remove the .flow_dissect procedure, so the flow dissector will call the
generic variant which works for this tagging protocol.

Cc: DENG Qingfang <dqfext@gmail.com>
Cc: Sean Wang <sean.wang@mediatek.com>
Cc: John Crispin <john@phrozen.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Remove the .flow_dissect callback altogether.
Actually copy the people from cc to the patch.

 net/dsa/tag_mtk.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index 2aba17b43e69..4cdd9cf428fb 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -105,19 +105,11 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static void mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				 int *offset)
-{
-	*offset = 4;
-	*proto = ((__be16 *)skb->data)[1];
-}
-
 static const struct dsa_device_ops mtk_netdev_ops = {
 	.name		= "mtk",
 	.proto		= DSA_TAG_PROTO_MTK,
 	.xmit		= mtk_tag_xmit,
 	.rcv		= mtk_tag_rcv,
-	.flow_dissect	= mtk_tag_flow_dissect,
 	.overhead	= MTK_HDR_LEN,
 };
 
-- 
2.25.1


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

* [PATCH v3 net-next 13/15] net: dsa: tag_qca: use the generic flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (11 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 12/15] net: dsa: tag_mtk: " Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 14/15] net: dsa: tag_sja1105: use a custom " Vladimir Oltean
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem
  Cc: andrew, f.fainelli, vivien.didelot, kuba, John Crispin,
	Alexander Lobakin

Remove the .flow_dissect procedure, so the flow dissector will call the
generic variant which works for this tagging protocol.

Cc: John Crispin <john@phrozen.org>
Cc: Alexander Lobakin <alobakin@pm.me>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Remove the .flow_dissect callback altogether.
Actually copy the people from cc to the patch.

 net/dsa/tag_qca.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
index a75c6b20c215..1b9e8507112b 100644
--- a/net/dsa/tag_qca.c
+++ b/net/dsa/tag_qca.c
@@ -89,19 +89,11 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 }
 
-static void qca_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				 int *offset)
-{
-	*offset = QCA_HDR_LEN;
-	*proto = ((__be16 *)skb->data)[0];
-}
-
 static const struct dsa_device_ops qca_netdev_ops = {
 	.name	= "qca",
 	.proto	= DSA_TAG_PROTO_QCA,
 	.xmit	= qca_tag_xmit,
 	.rcv	= qca_tag_rcv,
-	.flow_dissect = qca_tag_flow_dissect,
 	.overhead = QCA_HDR_LEN,
 };
 
-- 
2.25.1


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

* [PATCH v3 net-next 14/15] net: dsa: tag_sja1105: use a custom flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (12 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 13/15] net: dsa: tag_qca: " Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-26 19:32 ` [PATCH v3 net-next 15/15] net: dsa: tag_rtl4_a: use the generic " Vladimir Oltean
  2020-09-26 21:18 ` [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA David Miller
  15 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, f.fainelli, vivien.didelot, kuba

The sja1105 is a bit of a special snowflake, in that not all frames are
transmitted/received in the same way. L2 link-local frames are received
with the source port/switch ID information put in the destination MAC
address. For the rest, a tag_8021q header is used. So only the latter
frames displace the rest of the headers and need to use the generic flow
dissector procedure.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
None.

 net/dsa/tag_sja1105.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 36ebd5878061..50496013cdb7 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -346,6 +346,16 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 					      is_meta);
 }
 
+static void sja1105_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+				 int *offset)
+{
+	/* No tag added for management frames, all ok */
+	if (unlikely(sja1105_is_link_local(skb)))
+		return;
+
+	dsa_tag_generic_flow_dissect(skb, proto, offset);
+}
+
 static const struct dsa_device_ops sja1105_netdev_ops = {
 	.name = "sja1105",
 	.proto = DSA_TAG_PROTO_SJA1105,
@@ -353,6 +363,7 @@ static const struct dsa_device_ops sja1105_netdev_ops = {
 	.rcv = sja1105_rcv,
 	.filter = sja1105_filter,
 	.overhead = VLAN_HLEN,
+	.flow_dissect = sja1105_flow_dissect,
 	.promisc_on_master = true,
 };
 
-- 
2.25.1


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

* [PATCH v3 net-next 15/15] net: dsa: tag_rtl4_a: use the generic flow dissector procedure
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (13 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 14/15] net: dsa: tag_sja1105: use a custom " Vladimir Oltean
@ 2020-09-26 19:32 ` Vladimir Oltean
  2020-09-30  8:36   ` Linus Walleij
  2020-09-26 21:18 ` [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA David Miller
  15 siblings, 1 reply; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 19:32 UTC (permalink / raw)
  To: netdev, davem
  Cc: andrew, f.fainelli, vivien.didelot, kuba, Linus Walleij,
	DENG Qingfang, Mauri Sandberg

Remove the .flow_dissect procedure, so the flow dissector will call the
generic variant which works for this tagging protocol.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: DENG Qingfang <dqfext@gmail.com>
Cc: Mauri Sandberg <sandberg@mailfence.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v3:
Remove the .flow_dissect callback altogether.
Actually copy the people from cc to the patch.

 net/dsa/tag_rtl4_a.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c
index 868980ba1fcd..2646abe5a69e 100644
--- a/net/dsa/tag_rtl4_a.c
+++ b/net/dsa/tag_rtl4_a.c
@@ -106,20 +106,11 @@ static struct sk_buff *rtl4a_tag_rcv(struct sk_buff *skb,
 	return skb;
 }
 
-static void rtl4a_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-				   int *offset)
-{
-	*offset = RTL4_A_HDR_LEN;
-	/* Skip past the tag and fetch the encapsulated Ethertype */
-	*proto = ((__be16 *)skb->data)[1];
-}
-
 static const struct dsa_device_ops rtl4a_netdev_ops = {
 	.name	= "rtl4a",
 	.proto	= DSA_TAG_PROTO_RTL4_A,
 	.xmit	= rtl4a_tag_xmit,
 	.rcv	= rtl4a_tag_rcv,
-	.flow_dissect = rtl4a_tag_flow_dissect,
 	.overhead = RTL4_A_HDR_LEN,
 };
 module_dsa_tag_driver(rtl4a_netdev_ops);
-- 
2.25.1


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

* Re: [PATCH v3 net-next 02/15] net: dsa: allow drivers to request promiscuous mode on master
  2020-09-26 19:32 ` [PATCH v3 net-next 02/15] net: dsa: allow drivers to request promiscuous mode on master Vladimir Oltean
@ 2020-09-26 20:22   ` Andrew Lunn
  0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 20:22 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:32:02PM +0300, Vladimir Oltean wrote:
> Currently DSA assumes that taggers don't mess with the destination MAC
> address of the frames on RX. That is not always the case. Some DSA
> headers are placed before the Ethernet header (ocelot), and others
> simply mangle random bytes from the destination MAC address (sja1105
> with its incl_srcpt option).
> 
> Currently the DSA master goes to promiscuous mode automatically when the
> slave devices go too (such as when enslaved to a bridge), but in
> standalone mode this is a problem that needs to be dealt with.
> 
> So give drivers the possibility to signal that their tagging protocol
> will get randomly dropped otherwise, and let DSA deal with fixing that.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

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

* Re: [PATCH v3 net-next 03/15] net: dsa: tag_sja1105: request promiscuous mode for master
  2020-09-26 19:32 ` [PATCH v3 net-next 03/15] net: dsa: tag_sja1105: request promiscuous mode for master Vladimir Oltean
@ 2020-09-26 20:22   ` Andrew Lunn
  0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 20:22 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:32:03PM +0300, Vladimir Oltean wrote:
> Currently PTP is broken when ports are in standalone mode (the tagger
> keeps printing this message):
> 
> sja1105 spi0.1: Expected meta frame, is 01-80-c2-00-00-0e in the DSA master multicast filter?
> 
> Sure, one might say "simply add 01-80-c2-00-00-0e to the master's RX
> filter" but things become more complicated because:
> 
> - Actually all frames in the 01-80-c2-xx-xx-xx and 01-1b-19-xx-xx-xx
>   range are trapped to the CPU automatically
> - The switch mangles bytes 3 and 4 of the MAC address via the incl_srcpt
>   ("include source port [in the DMAC]") option, which is how source port
>   and switch id identification is done for link-local traffic on RX. But
>   this means that an address installed to the RX filter would, at the
>   end of the day, not correspond to the final address seen by the DSA
>   master.
> 
> Assume RX filtering lists on DSA masters are typically too small to
> include all necessary addresses for PTP to work properly on sja1105, and
> just request promiscuous mode unconditionally.
> 
> Just an example:
> Assuming the following addresses are trapped to the CPU:
> 01-80-c2-00-00-00 to 01-80-c2-00-00-ff
> 01-1b-19-00-00-00 to 01-1b-19-00-00-ff
> 
> These are 512 addresses.
> Now let's say this is a board with 3 switches, and 4 ports per switch.
> The 512 addresses become 6144 addresses that must be managed by the DSA
> master's RX filtering lists.
> 
> This may be refined in the future, but for now, it is simply not worth
> it to add the additional addresses to the master's RX filter, so simply
> request it to become promiscuous as soon as the driver probes.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

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

* Re: [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector
  2020-09-26 19:32 ` [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector Vladimir Oltean
@ 2020-09-26 20:25   ` Andrew Lunn
  2020-09-26 20:33   ` Andrew Lunn
  1 sibling, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 20:25 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:32:06PM +0300, Vladimir Oltean wrote:
> For all DSA formats that don't use tail tags, it looks like behind the
> obscure number crunching they're all doing the same thing: locating the
> real EtherType behind the DSA tag. Nonetheless, this is not immediately
> obvious, so create a generic helper for those DSA taggers that put the
> header before the EtherType.
> 
> Another assumption for the generic function is that the DSA tags are of
> equal length on RX and on TX. Prior to the previous patch, this was not
> true for ocelot and for gswip. The problem was resolved for ocelot, but
> for gswip it still remains, so that can't use this helper yet.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

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

* Re: [PATCH v3 net-next 07/15] net: dsa: point out the tail taggers
  2020-09-26 19:32 ` [PATCH v3 net-next 07/15] net: dsa: point out the tail taggers Vladimir Oltean
@ 2020-09-26 20:27   ` Andrew Lunn
  0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 20:27 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:32:07PM +0300, Vladimir Oltean wrote:
> The Marvell 88E6060 uses tag_trailer.c and the KSZ8795, KSZ9477 and
> KSZ9893 switches also use tail tags.
> 
> Tell that to the DSA core, since this makes a difference for the flow
> dissector. Most switches break the parsing of frame headers, but these
> ones don't, so no flow dissector adjustment needs to be done for them.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

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

* Re: [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector
  2020-09-26 19:32 ` [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector Vladimir Oltean
  2020-09-26 20:25   ` Andrew Lunn
@ 2020-09-26 20:33   ` Andrew Lunn
  2020-09-26 20:49     ` Vladimir Oltean
  1 sibling, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 20:33 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

> +static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
> +						__be16 *proto, int *offset)
> +{
> +#if IS_ENABLED(CONFIG_NET_DSA)
> +	const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops;
> +	int tag_len = ops->overhead;
> +
> +	*offset = tag_len;
> +	*proto = ((__be16 *)skb->data)[(tag_len / 2) - 1];
> +#endif
> +}
> +

Do you actually need the IS_ENABLED()? There is only one caller of
this function, and it is already protected by
IS_ENABLED(CONFIG_NET_DSA). So i don't think it adds anything.

    Andrew

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

* Re: [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector
  2020-09-26 20:33   ` Andrew Lunn
@ 2020-09-26 20:49     ` Vladimir Oltean
  0 siblings, 0 replies; 26+ messages in thread
From: Vladimir Oltean @ 2020-09-26 20:49 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:33:00PM +0200, Andrew Lunn wrote:
> > +static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
> > +						__be16 *proto, int *offset)
> > +{
> > +#if IS_ENABLED(CONFIG_NET_DSA)
> > +	const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops;
> > +	int tag_len = ops->overhead;
> > +
> > +	*offset = tag_len;
> > +	*proto = ((__be16 *)skb->data)[(tag_len / 2) - 1];
> > +#endif
> > +}
> > +
>
> Do you actually need the IS_ENABLED()? There is only one caller of
> this function, and it is already protected by
> IS_ENABLED(CONFIG_NET_DSA). So i don't think it adds anything.

It doesn't matter how many callers it has, it doesn't compile when
NET_DSA=n:

./include/net/dsa.h: In function ‘dsa_tag_generic_flow_dissect’:
./include/net/dsa.h:732:47: error: ‘struct net_device’ has no member named ‘dsa_ptr’; did you mean ‘ip_ptr’?
  const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops;
                                               ^~~~~~~
                                               ip_ptr

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

* Re: [PATCH v3 net-next 10/15] net: dsa: tag_dsa: use the generic flow dissector procedure
  2020-09-26 19:32 ` [PATCH v3 net-next 10/15] net: dsa: tag_dsa: use the " Vladimir Oltean
@ 2020-09-26 21:08   ` Andrew Lunn
  0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 21:08 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:32:10PM +0300, Vladimir Oltean wrote:
> Remove the .flow_dissect procedure, so the flow dissector will call the
> generic variant which works for this tagging protocol.
> 
> Cc: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

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

* Re: [PATCH v3 net-next 11/15] net: dsa: tag_edsa: use the generic flow dissector procedure
  2020-09-26 19:32 ` [PATCH v3 net-next 11/15] net: dsa: tag_edsa: " Vladimir Oltean
@ 2020-09-26 21:08   ` Andrew Lunn
  0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2020-09-26 21:08 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, f.fainelli, vivien.didelot, kuba

On Sat, Sep 26, 2020 at 10:32:11PM +0300, Vladimir Oltean wrote:
> Remove the .flow_dissect procedure, so the flow dissector will call the
> generic variant which works for this tagging protocol.
> 
> Cc: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

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

* Re: [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA
  2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
                   ` (14 preceding siblings ...)
  2020-09-26 19:32 ` [PATCH v3 net-next 15/15] net: dsa: tag_rtl4_a: use the generic " Vladimir Oltean
@ 2020-09-26 21:18 ` David Miller
  15 siblings, 0 replies; 26+ messages in thread
From: David Miller @ 2020-09-26 21:18 UTC (permalink / raw)
  To: vladimir.oltean; +Cc: netdev, andrew, f.fainelli, vivien.didelot, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Sat, 26 Sep 2020 22:32:00 +0300

> This is the v2 of a series initially submitted in May:
> https://www.spinics.net/lists/netdev/msg651866.html
> 
> The end goal is to get rid of the unintuitive code for the flow
> dissector that currently exists in the taggers. It can all be replaced
> by a single, common function.
> 
> Some background work needs to be done for that. Especially the ocelot
> driver poses some problems, since it has a different tag length between
> RX and TX, and I didn't want to make DSA aware of that, since I could
> instead make the tag lengths equal.
> 
> Changes in v3:
> - Added an optimization (08/15) that makes the generic case not need to
>   call the .flow_dissect function pointer. Basically .flow_dissect now
>   currently only exists for sja1105.
> - Moved the .promisc_on_master property to the tagger structure.
> - Added the .tail_tag property to the tagger structure.
> - Disabled "suppresscc = all" from my .gitconfig.

Series applied, thank you.

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

* Re: [PATCH v3 net-next 15/15] net: dsa: tag_rtl4_a: use the generic flow dissector procedure
  2020-09-26 19:32 ` [PATCH v3 net-next 15/15] net: dsa: tag_rtl4_a: use the generic " Vladimir Oltean
@ 2020-09-30  8:36   ` Linus Walleij
  0 siblings, 0 replies; 26+ messages in thread
From: Linus Walleij @ 2020-09-30  8:36 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, David S. Miller, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Jakub Kicinski, DENG Qingfang, Mauri Sandberg

On Sat, Sep 26, 2020 at 9:33 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote:

> Remove the .flow_dissect procedure, so the flow dissector will call the
> generic variant which works for this tagging protocol.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: DENG Qingfang <dqfext@gmail.com>
> Cc: Mauri Sandberg <sandberg@mailfence.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Changes in v3:
> Remove the .flow_dissect callback altogether.
> Actually copy the people from cc to the patch.

That's a neat refactoring!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

end of thread, other threads:[~2020-09-30  8:36 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-26 19:32 [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 01/15] net: mscc: ocelot: move NPI port configuration to DSA Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 02/15] net: dsa: allow drivers to request promiscuous mode on master Vladimir Oltean
2020-09-26 20:22   ` Andrew Lunn
2020-09-26 19:32 ` [PATCH v3 net-next 03/15] net: dsa: tag_sja1105: request promiscuous mode for master Vladimir Oltean
2020-09-26 20:22   ` Andrew Lunn
2020-09-26 19:32 ` [PATCH v3 net-next 04/15] net: dsa: tag_ocelot: use a short prefix on both ingress and egress Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 05/15] net: dsa: make the .flow_dissect tagger callback return void Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 06/15] net: dsa: add a generic procedure for the flow dissector Vladimir Oltean
2020-09-26 20:25   ` Andrew Lunn
2020-09-26 20:33   ` Andrew Lunn
2020-09-26 20:49     ` Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 07/15] net: dsa: point out the tail taggers Vladimir Oltean
2020-09-26 20:27   ` Andrew Lunn
2020-09-26 19:32 ` [PATCH v3 net-next 08/15] net: flow_dissector: avoid indirect call to DSA .flow_dissect for generic case Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 09/15] net: dsa: tag_brcm: use generic flow dissector procedure Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 10/15] net: dsa: tag_dsa: use the " Vladimir Oltean
2020-09-26 21:08   ` Andrew Lunn
2020-09-26 19:32 ` [PATCH v3 net-next 11/15] net: dsa: tag_edsa: " Vladimir Oltean
2020-09-26 21:08   ` Andrew Lunn
2020-09-26 19:32 ` [PATCH v3 net-next 12/15] net: dsa: tag_mtk: " Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 13/15] net: dsa: tag_qca: " Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 14/15] net: dsa: tag_sja1105: use a custom " Vladimir Oltean
2020-09-26 19:32 ` [PATCH v3 net-next 15/15] net: dsa: tag_rtl4_a: use the generic " Vladimir Oltean
2020-09-30  8:36   ` Linus Walleij
2020-09-26 21:18 ` [PATCH v3 net-next 00/15] Generic adjustment for flow dissector in DSA David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).