All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware
@ 2017-09-26 22:25 Andrew Lunn
  2017-09-26 22:25 ` [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID Andrew Lunn
                   ` (7 more replies)
  0 siblings, 8 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:25 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

This patchset makes the mv88e6xxx driver perform flooding in hardware,
rather than let the software bridge perform the flooding. This is a
prerequisite for IGMP snooping on the bridge interface.

In order to make hardware broadcasting work, a few other issues need
fixing or improving. SWITCHDEV_ATTR_ID_PORT_PARENT_ID is broken, which
is apparent when testing on the ZII devel board with multiple
switches.

Some of these patches are taken from a previous RFC patchset of IGMP
support. Hence the v2 comments...


Andrew Lunn (6):
  net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID
  net: dsa: {e}dsa: set offload_fwd_mark on received packets
  net: dsa: mv88e6xxx: Fixed port netdev check for VLANs
  net: dsa: mv88e6xxx: Print offending port when vlan check fails
  net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge()
  net: dsa: mv88e6xxx: Flood broadcast frames in hardware

 drivers/net/dsa/mv88e6xxx/chip.c | 128 ++++++++++++++++++++++++---------------
 net/dsa/slave.c                  |  11 ++--
 net/dsa/tag_dsa.c                |   1 +
 net/dsa/tag_edsa.c               |   1 +
 4 files changed, 89 insertions(+), 52 deletions(-)

-- 
2.14.1

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

* [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
@ 2017-09-26 22:25 ` Andrew Lunn
  2017-09-27 10:15   ` Sergei Shtylyov
  2017-09-27 15:31   ` Vivien Didelot
  2017-09-26 22:25 ` [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets Andrew Lunn
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:25 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

SWITCHDEV_ATTR_ID_PORT_PARENT_ID is used by the software bridge when
determining which ports to flood a packet out. If the packet
originated from a switch, it assumes the switch has already flooded
the packet out the switches ports, so the bridge should not flood the
packet itself out switch ports. Ports on the same switch are expected
to return the same parent ID when SWITCHDEV_ATTR_ID_PORT_PARENT_ID is
called.

DSA gets this wrong with clusters of switches. As far as the software
bridge is concerned, the cluster is all one switch. A packet from any
switch in the cluster can be assumed to of been flooded as needed out
all ports of the cluster, not just the switch it originated
from. Hence all ports of a cluster should return the same parent. The
old implementation did not, each switch in the cluster had its own ID.

Also wrong was that the ID was not unique if multiple DSA instances
are in operation.

Use the tree ID as the parent ID, which is the same for all switches
in a cluster and unique across switch clusters.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
v2: Swap from MAC address to dst->tree
---
 net/dsa/slave.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index bd51ef56ec5b..ee72aa164956 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -354,13 +354,16 @@ static int dsa_slave_port_attr_get(struct net_device *dev,
 				   struct switchdev_attr *attr)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct dsa_switch *ds = p->dp->ds;
 
 	switch (attr->id) {
-	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
-		attr->u.ppid.id_len = sizeof(ds->index);
-		memcpy(&attr->u.ppid.id, &ds->index, attr->u.ppid.id_len);
+	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: {
+		struct dsa_switch *ds = p->dp->ds;
+		struct dsa_switch_tree *dst = ds->dst;
+
+		attr->u.ppid.id_len = sizeof(dst->tree);
+		memcpy(&attr->u.ppid.id, &dst->tree, sizeof(dst->tree));
 		break;
+	}
 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
 		attr->u.brport_flags_support = 0;
 		break;
-- 
2.14.1

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

* [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
  2017-09-26 22:25 ` [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID Andrew Lunn
@ 2017-09-26 22:25 ` Andrew Lunn
  2017-09-27 19:46   ` Florian Fainelli
  2017-09-26 22:26 ` [PATCH net-next 3/6] net: dsa: mv88e6xxx: Fixed port netdev check for VLANs Andrew Lunn
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:25 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

The software bridge needs to know if a packet has already been bridged
by hardware offload to ports in the same hardware offload, in order
that it does not re-flood them, causing duplicates. This is
particularly true for broadcast and multicast traffic which the host
has requested.

By setting offload_fwd_mark in the skb the bridge will only flood to
ports in other offloads and other netifs. Set this flag in the DSA and
EDSA tag driver.

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

v2
--
For the moment, do this in the tag drivers, not the generic code.
Once we get more test results from other switches, maybe move it back
again.
---
 net/dsa/tag_dsa.c  | 1 +
 net/dsa/tag_edsa.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index fbf9ca954773..ea6ada9d5016 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -154,6 +154,7 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
 	}
 
 	skb->dev = ds->ports[source_port].netdev;
+	skb->offload_fwd_mark = 1;
 
 	return skb;
 }
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 76367ba1b2e2..a961b22a7018 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -173,6 +173,7 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
 	}
 
 	skb->dev = ds->ports[source_port].netdev;
+	skb->offload_fwd_mark = 1;
 
 	return skb;
 }
-- 
2.14.1

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

* [PATCH net-next 3/6] net: dsa: mv88e6xxx: Fixed port netdev check for VLANs
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
  2017-09-26 22:25 ` [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID Andrew Lunn
  2017-09-26 22:25 ` [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets Andrew Lunn
@ 2017-09-26 22:26 ` Andrew Lunn
  2017-09-26 22:26 ` [PATCH net-next 4/6] net: dsa: mv88e6xxx: Print offending port when vlan check fails Andrew Lunn
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:26 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

Having the same VLAN on multiple bridges is currently unsupported as
an offload. mv88e6xxx_port_check_hw_vlan() is used to ensure that a
VLAN is not on multiple bridges when adding a VLAN range to a port. It
loops the ports and checks to see if there are ports in a different
bridge with the same VLAN.

While walking all switch ports, the code was checking if the new port
has a netdev attached to it. If not, skip checking the port being
walked. This seems like a typ0. If the new port does not have a
netdev, how has a VLAN been added to it in the first place, requiring
this check be performed at all? More likely, we should be checking if
the port being walked has a netdev. Without it having a netdev, it
cannot have a VLAN on it, so there is no need to check further for
that particular port.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index c6678aa9b4ef..884f0507cf48 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1120,7 +1120,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
 			if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
 				continue;
 
-			if (!ds->ports[port].netdev)
+			if (!ds->ports[i].netdev)
 				continue;
 
 			if (vlan.member[i] ==
-- 
2.14.1

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

* [PATCH net-next 4/6] net: dsa: mv88e6xxx: Print offending port when vlan check fails
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
                   ` (2 preceding siblings ...)
  2017-09-26 22:26 ` [PATCH net-next 3/6] net: dsa: mv88e6xxx: Fixed port netdev check for VLANs Andrew Lunn
@ 2017-09-26 22:26 ` Andrew Lunn
  2017-09-27 15:49   ` Vivien Didelot
  2017-09-26 22:26 ` [PATCH net-next 5/6] net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge() Andrew Lunn
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:26 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

When testing if a VLAN is one more than one bridge, we print an error
message that the VLAN is already in use somewhere else. Print both the
new port which would like the VLAN, and the port which already has it,
to aid debugging.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 884f0507cf48..8a4756490a5a 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1134,8 +1134,8 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
 			if (!ds->ports[i].bridge_dev)
 				continue;
 
-			dev_err(ds->dev, "p%d: hw VLAN %d already used by %s\n",
-				port, vlan.vid,
+			dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
+				port, vlan.vid, i,
 				netdev_name(ds->ports[i].bridge_dev));
 			err = -EOPNOTSUPP;
 			goto unlock;
-- 
2.14.1

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

* [PATCH net-next 5/6] net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge()
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
                   ` (3 preceding siblings ...)
  2017-09-26 22:26 ` [PATCH net-next 4/6] net: dsa: mv88e6xxx: Print offending port when vlan check fails Andrew Lunn
@ 2017-09-26 22:26 ` Andrew Lunn
  2017-09-27 15:51   ` Vivien Didelot
  2017-09-26 22:26 ` [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware Andrew Lunn
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:26 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

This function is going to be needed by a soon to be added new
function. Move it earlier so we can avoid a forward declaration.
No code changes.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 88 ++++++++++++++++++++--------------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8a4756490a5a..9fbe1f02b9ce 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1191,6 +1191,50 @@ mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
 	return 0;
 }
 
+static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
+					const unsigned char *addr, u16 vid,
+					u8 state)
+{
+	struct mv88e6xxx_vtu_entry vlan;
+	struct mv88e6xxx_atu_entry entry;
+	int err;
+
+	/* Null VLAN ID corresponds to the port private database */
+	if (vid == 0)
+		err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid);
+	else
+		err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
+	if (err)
+		return err;
+
+	entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
+	ether_addr_copy(entry.mac, addr);
+	eth_addr_dec(entry.mac);
+
+	err = mv88e6xxx_g1_atu_getnext(chip, vlan.fid, &entry);
+	if (err)
+		return err;
+
+	/* Initialize a fresh ATU entry if it isn't found */
+	if (entry.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ||
+	    !ether_addr_equal(entry.mac, addr)) {
+		memset(&entry, 0, sizeof(entry));
+		ether_addr_copy(entry.mac, addr);
+	}
+
+	/* Purge the ATU entry only if no port is using it anymore */
+	if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED) {
+		entry.portvec &= ~BIT(port);
+		if (!entry.portvec)
+			entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
+	} else {
+		entry.portvec |= BIT(port);
+		entry.state = state;
+	}
+
+	return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
+}
+
 static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
 				    u16 vid, u8 member)
 {
@@ -1307,50 +1351,6 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
 	return err;
 }
 
-static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
-					const unsigned char *addr, u16 vid,
-					u8 state)
-{
-	struct mv88e6xxx_vtu_entry vlan;
-	struct mv88e6xxx_atu_entry entry;
-	int err;
-
-	/* Null VLAN ID corresponds to the port private database */
-	if (vid == 0)
-		err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid);
-	else
-		err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
-	if (err)
-		return err;
-
-	entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
-	ether_addr_copy(entry.mac, addr);
-	eth_addr_dec(entry.mac);
-
-	err = mv88e6xxx_g1_atu_getnext(chip, vlan.fid, &entry);
-	if (err)
-		return err;
-
-	/* Initialize a fresh ATU entry if it isn't found */
-	if (entry.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ||
-	    !ether_addr_equal(entry.mac, addr)) {
-		memset(&entry, 0, sizeof(entry));
-		ether_addr_copy(entry.mac, addr);
-	}
-
-	/* Purge the ATU entry only if no port is using it anymore */
-	if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED) {
-		entry.portvec &= ~BIT(port);
-		if (!entry.portvec)
-			entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
-	} else {
-		entry.portvec |= BIT(port);
-		entry.state = state;
-	}
-
-	return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
-}
-
 static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
 				  const unsigned char *addr, u16 vid)
 {
-- 
2.14.1

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

* [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
                   ` (4 preceding siblings ...)
  2017-09-26 22:26 ` [PATCH net-next 5/6] net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge() Andrew Lunn
@ 2017-09-26 22:26 ` Andrew Lunn
  2017-09-27 18:24   ` Vivien Didelot
  2017-09-26 22:26 ` [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports Andrew Lunn
  2017-09-27 18:28 ` [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Vivien Didelot
  7 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:26 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

By default, the switch does not flood broadcast frames. Instead the
broadcast address is unknown in the ATU, so the frame gets forwarded
out the cpu port. The software bridge then floods it back to the
individual switch ports which are members of the bridge.

Add an ATU entry in the switch so that it floods broadcast frames out
ports, rather than have the software bridge do it. Also, send a copy
out the cpu port and any dsa ports. Rely on the port vectors to
prevent broadcast frames leaking between bridges, and separated ports.

Additionally, when a VLAN is added, a new FID is allocated.  This
represents a new table of ATU entries. A broadcast entry is added to
the new FID.

With offload_fwd_mark being set, the software bridge will not flood
the frames it receives back to the switch.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 9fbe1f02b9ce..908bb867df3b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1235,6 +1235,30 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
 	return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
 }
 
+static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
+					u16 vid)
+{
+	const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	return mv88e6xxx_port_db_load_purge(
+		chip, port, broadcast, vid,
+		MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
+}
+
+static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
+{
+	int port;
+	int err;
+
+	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
+		err = mv88e6xxx_port_add_broadcast(chip, port, vid);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
 				    u16 vid, u8 member)
 {
@@ -1247,7 +1271,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
 
 	vlan.member[port] = member;
 
-	return mv88e6xxx_vtu_loadpurge(chip, &vlan);
+	err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
+	if (err)
+		return err;
+
+	return mv88e6xxx_broadcast_setup(chip, vid);
 }
 
 static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
@@ -2025,6 +2053,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	err = mv88e6xxx_broadcast_setup(chip, 0);
+	if (err)
+		goto unlock;
+
 	err = mv88e6xxx_pot_setup(chip);
 	if (err)
 		goto unlock;
-- 
2.14.1

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

* [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
                   ` (5 preceding siblings ...)
  2017-09-26 22:26 ` [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware Andrew Lunn
@ 2017-09-26 22:26 ` Andrew Lunn
  2017-09-26 22:43   ` Andrew Lunn
  2017-09-27  3:20   ` David Miller
  2017-09-27 18:28 ` [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Vivien Didelot
  7 siblings, 2 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:26 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

By default, the switch does not flood broadcast frames. Instead the
broadcast address is unknown in the ATU, so the frame gets forwarded
out the cpu port. The software bridge then floods it back to the
individual switch ports which are members of the bridge.

Add an ATU entry in the switch so that it floods broadcast frames out
ports, rather than have the software bridge do it. Also, send a copy
out the cpu port and any dsa ports. Rely on the port vectors to
prevent broadcast frames leaking between bridges, and separated ports.

Additionally, when a VLAN is added, a new FID is allocated.  This
represents a new table of ATU entries. Broadcast entry is added to the
new FID.

With offload_fwd_mark being set, the software bridge will not flood
the frames it receives back to the switch.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 9fbe1f02b9ce..908bb867df3b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1235,6 +1235,30 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
 	return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
 }
 
+static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
+					u16 vid)
+{
+	const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	return mv88e6xxx_port_db_load_purge(
+		chip, port, broadcast, vid,
+		MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
+}
+
+static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
+{
+	int port;
+	int err;
+
+	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
+		err = mv88e6xxx_port_add_broadcast(chip, port, vid);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
 				    u16 vid, u8 member)
 {
@@ -1247,7 +1271,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
 
 	vlan.member[port] = member;
 
-	return mv88e6xxx_vtu_loadpurge(chip, &vlan);
+	err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
+	if (err)
+		return err;
+
+	return mv88e6xxx_broadcast_setup(chip, vid);
 }
 
 static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
@@ -2025,6 +2053,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	err = mv88e6xxx_broadcast_setup(chip, 0);
+	if (err)
+		goto unlock;
+
 	err = mv88e6xxx_pot_setup(chip);
 	if (err)
 		goto unlock;
-- 
2.14.1

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

* Re: [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports
  2017-09-26 22:26 ` [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports Andrew Lunn
@ 2017-09-26 22:43   ` Andrew Lunn
  2017-09-27  3:20   ` David Miller
  1 sibling, 0 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-26 22:43 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev

Ah, twice patch 6. Not good.

I will wait for a few days for comments, and then repost without the
duplication.

	Andrew

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

* Re: [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports
  2017-09-26 22:26 ` [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports Andrew Lunn
  2017-09-26 22:43   ` Andrew Lunn
@ 2017-09-27  3:20   ` David Miller
  1 sibling, 0 replies; 25+ messages in thread
From: David Miller @ 2017-09-27  3:20 UTC (permalink / raw)
  To: andrew; +Cc: vivien.didelot, netdev

From: Andrew Lunn <andrew@lunn.ch>
Date: Wed, 27 Sep 2017 00:26:04 +0200

> +
> +	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {

Just a nit pick since you are going to respin this anyways:

	for (x; cond(x); x++)

seems to be the canonical way to express this in the kernel, so please
make "++port" into "port++"

Thank you.

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

* Re: [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID
  2017-09-26 22:25 ` [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID Andrew Lunn
@ 2017-09-27 10:15   ` Sergei Shtylyov
  2017-09-27 15:31   ` Vivien Didelot
  1 sibling, 0 replies; 25+ messages in thread
From: Sergei Shtylyov @ 2017-09-27 10:15 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: Vivien Didelot, netdev

Hello!

On 9/27/2017 1:25 AM, Andrew Lunn wrote:

> SWITCHDEV_ATTR_ID_PORT_PARENT_ID is used by the software bridge when
> determining which ports to flood a packet out. If the packet
> originated from a switch, it assumes the switch has already flooded
> the packet out the switches ports, so the bridge should not flood the
> packet itself out switch ports. Ports on the same switch are expected
> to return the same parent ID when SWITCHDEV_ATTR_ID_PORT_PARENT_ID is
> called.
> 
> DSA gets this wrong with clusters of switches. As far as the software
> bridge is concerned, the cluster is all one switch. A packet from any
> switch in the cluster can be assumed to of been flooded as needed out

    s/of/have/?

> all ports of the cluster, not just the switch it originated
> from. Hence all ports of a cluster should return the same parent. The
> old implementation did not, each switch in the cluster had its own ID.
> 
> Also wrong was that the ID was not unique if multiple DSA instances
> are in operation.
> 
> Use the tree ID as the parent ID, which is the same for all switches
> in a cluster and unique across switch clusters.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> v2: Swap from MAC address to dst->tree
[...]

MBR, Sergei

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

* Re: [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID
  2017-09-26 22:25 ` [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID Andrew Lunn
  2017-09-27 10:15   ` Sergei Shtylyov
@ 2017-09-27 15:31   ` Vivien Didelot
  1 sibling, 0 replies; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 15:31 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> @@ -354,13 +354,16 @@ static int dsa_slave_port_attr_get(struct net_device *dev,
>  				   struct switchdev_attr *attr)
>  {
>  	struct dsa_slave_priv *p = netdev_priv(dev);
> -	struct dsa_switch *ds = p->dp->ds;
>  
>  	switch (attr->id) {
> -	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
> -		attr->u.ppid.id_len = sizeof(ds->index);
> -		memcpy(&attr->u.ppid.id, &ds->index, attr->u.ppid.id_len);
> +	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: {
> +		struct dsa_switch *ds = p->dp->ds;
> +		struct dsa_switch_tree *dst = ds->dst;
> +
> +		attr->u.ppid.id_len = sizeof(dst->tree);
> +		memcpy(&attr->u.ppid.id, &dst->tree, sizeof(dst->tree));
>  		break;
> +	}
>  	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
>  		attr->u.brport_flags_support = 0;
>  		break;

I am pretty sure the kernel folks won't like blocks within case
statments. Simply declare dst = p->dp->ds->dst at the beginning.

Also keeping attr->u.ppid.id_len as memcpy's third argument like other
switchdev users do would be prefered.

Otherwise using the tree index is indeed the way to go:

Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>


Thanks,

        Vivien

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

* Re: [PATCH net-next 4/6] net: dsa: mv88e6xxx: Print offending port when vlan check fails
  2017-09-26 22:26 ` [PATCH net-next 4/6] net: dsa: mv88e6xxx: Print offending port when vlan check fails Andrew Lunn
@ 2017-09-27 15:49   ` Vivien Didelot
  0 siblings, 0 replies; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 15:49 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn

Andrew Lunn <andrew@lunn.ch> writes:

> When testing if a VLAN is one more than one bridge, we print an error
> message that the VLAN is already in use somewhere else. Print both the
> new port which would like the VLAN, and the port which already has it,
> to aid debugging.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>

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

* Re: [PATCH net-next 5/6] net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge()
  2017-09-26 22:26 ` [PATCH net-next 5/6] net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge() Andrew Lunn
@ 2017-09-27 15:51   ` Vivien Didelot
  0 siblings, 0 replies; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 15:51 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn

Andrew Lunn <andrew@lunn.ch> writes:

> This function is going to be needed by a soon to be added new
> function. Move it earlier so we can avoid a forward declaration.
> No code changes.

s/code/functional/

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

Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-26 22:26 ` [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware Andrew Lunn
@ 2017-09-27 18:24   ` Vivien Didelot
  2017-09-27 18:36     ` Andrew Lunn
  2017-09-27 18:37     ` Florian Fainelli
  0 siblings, 2 replies; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 18:24 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> +static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
> +					u16 vid)
> +{
> +	const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
> +
> +	return mv88e6xxx_port_db_load_purge(
> +		chip, port, broadcast, vid,
> +		MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);

Please don't do this. This is not a valid coding style and has already
shown to be a bad example for other DSA drivers copying mv88e6xxx.

Simply declare u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC above...

> +}
> +
> +static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
> +{
> +	int port;
> +	int err;
> +
> +	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
> +		err = mv88e6xxx_port_add_broadcast(chip, port, vid);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
>  static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
>  				    u16 vid, u8 member)
>  {
> @@ -1247,7 +1271,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
>  
>  	vlan.member[port] = member;
>  
> -	return mv88e6xxx_vtu_loadpurge(chip, &vlan);
> +	err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
> +	if (err)
> +		return err;
> +
> +	return mv88e6xxx_broadcast_setup(chip, vid);
>  }
>  
>  static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
> @@ -2025,6 +2053,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
>  	if (err)
>  		goto unlock;
>  
> +	err = mv88e6xxx_broadcast_setup(chip, 0);
> +	if (err)
> +		goto unlock;
> +
>  	err = mv88e6xxx_pot_setup(chip);
>  	if (err)
>  		goto unlock;


Adding the broadcast address to an Ethernet switch's FDB is pretty
generic and mv88e6xxx mustn't be the only driver doing this.

They do not have to care about the broadcast address, this is just a
standard MDB entry for them. This must be moved up to the DSA layer.

Adding the broadcast address in dsa_port_vlan_add and dsa_port_enable
like this should be enough: http://ix.io/AmS


Thanks,

        Vivien

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

* Re: [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware
  2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
                   ` (6 preceding siblings ...)
  2017-09-26 22:26 ` [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports Andrew Lunn
@ 2017-09-27 18:28 ` Vivien Didelot
  7 siblings, 0 replies; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 18:28 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> This patchset makes the mv88e6xxx driver perform flooding in hardware,
> rather than let the software bridge perform the flooding. This is a
> prerequisite for IGMP snooping on the bridge interface.
>
> In order to make hardware broadcasting work, a few other issues need
> fixing or improving. SWITCHDEV_ATTR_ID_PORT_PARENT_ID is broken, which
> is apparent when testing on the ZII devel board with multiple
> switches.
>
> Some of these patches are taken from a previous RFC patchset of IGMP
> support. Hence the v2 comments...

mlxsw and others return BR_FLOOD and BR_MCAST_FLOOD in
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT, is this something DSA needs
here?


Thanks,

        Vivien

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 18:24   ` Vivien Didelot
@ 2017-09-27 18:36     ` Andrew Lunn
  2017-09-27 18:59       ` Vivien Didelot
  2017-09-27 18:37     ` Florian Fainelli
  1 sibling, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2017-09-27 18:36 UTC (permalink / raw)
  To: Vivien Didelot; +Cc: David Miller, netdev

> Adding the broadcast address to an Ethernet switch's FDB is pretty
> generic and mv88e6xxx mustn't be the only driver doing this.

Actually, it is. All the others seem to do this in hardware without
needing an FDB. Since mv88e6xxx is the only one requiring it, it has
to be done in the mv88e6xxx driver.

   Andrew

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 18:24   ` Vivien Didelot
  2017-09-27 18:36     ` Andrew Lunn
@ 2017-09-27 18:37     ` Florian Fainelli
  2017-09-27 18:46       ` Andrew Lunn
  1 sibling, 1 reply; 25+ messages in thread
From: Florian Fainelli @ 2017-09-27 18:37 UTC (permalink / raw)
  To: Vivien Didelot, Andrew Lunn, David Miller; +Cc: netdev

On 09/27/2017 11:24 AM, Vivien Didelot wrote:
> Hi Andrew,
> 
> Andrew Lunn <andrew@lunn.ch> writes:
> 
>> +static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
>> +					u16 vid)
>> +{
>> +	const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
>> +
>> +	return mv88e6xxx_port_db_load_purge(
>> +		chip, port, broadcast, vid,
>> +		MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
> 
> Please don't do this. This is not a valid coding style and has already
> shown to be a bad example for other DSA drivers copying mv88e6xxx.
> 
> Simply declare u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC above...
> 
>> +}
>> +
>> +static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
>> +{
>> +	int port;
>> +	int err;
>> +
>> +	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
>> +		err = mv88e6xxx_port_add_broadcast(chip, port, vid);
>> +		if (err)
>> +			return err;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
>>  				    u16 vid, u8 member)
>>  {
>> @@ -1247,7 +1271,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
>>  
>>  	vlan.member[port] = member;
>>  
>> -	return mv88e6xxx_vtu_loadpurge(chip, &vlan);
>> +	err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
>> +	if (err)
>> +		return err;
>> +
>> +	return mv88e6xxx_broadcast_setup(chip, vid);
>>  }
>>  
>>  static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
>> @@ -2025,6 +2053,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
>>  	if (err)
>>  		goto unlock;
>>  
>> +	err = mv88e6xxx_broadcast_setup(chip, 0);
>> +	if (err)
>> +		goto unlock;
>> +
>>  	err = mv88e6xxx_pot_setup(chip);
>>  	if (err)
>>  		goto unlock;
> 
> 
> Adding the broadcast address to an Ethernet switch's FDB is pretty
> generic and mv88e6xxx mustn't be the only driver doing this.

I have not had time to test Andrew's IGMP patch set on bcm_sf2/b53, but
while I agree that adding a broadcast address using a FDB entry is
generic in premise, we don't know yet whether other switch drivers need
that or not, so until we do, it seems like Andrew's approach is
appropriate here by keeping this local to mv88e6xxx.

> 
> They do not have to care about the broadcast address, this is just a
> standard MDB entry for them. This must be moved up to the DSA layer.
> 
> Adding the broadcast address in dsa_port_vlan_add and dsa_port_enable
> like this should be enough: http://ix.io/AmS
> 

What if I don't have CONFIG_BRIDGE_VLAN_FILTERING enabled, what happens
in that case, would not this result in not programming the broadcast
address?
-- 
Florian

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 18:37     ` Florian Fainelli
@ 2017-09-27 18:46       ` Andrew Lunn
  2017-09-27 19:19         ` Vivien Didelot
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2017-09-27 18:46 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: Vivien Didelot, David Miller, netdev

> What if I don't have CONFIG_BRIDGE_VLAN_FILTERING enabled, what happens
> in that case, would not this result in not programming the broadcast
> address?

Hi Florian

It took me a while to make this work with CONFIG_BRIDGE_VLAN_FILTERING
enabled. Any change to enable hardware flooding needs careful testing
for lots of different configurations. This is another reason i don't
want to do it at the DSA level, until we have a good understanding
what it means in each individual driver.

     Andrew

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 18:36     ` Andrew Lunn
@ 2017-09-27 18:59       ` Vivien Didelot
  0 siblings, 0 replies; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 18:59 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: David Miller, netdev

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

>> Adding the broadcast address to an Ethernet switch's FDB is pretty
>> generic and mv88e6xxx mustn't be the only driver doing this.
>
> Actually, it is. All the others seem to do this in hardware without
> needing an FDB. Since mv88e6xxx is the only one requiring it, it has
> to be done in the mv88e6xxx driver.

Adding the broadcast address from the DSA layer wouldn't hurt and make
things pretty obvious. This would also avoid drivers to get
unnecessarily complex. A .port_vlan_add implementation must remain
simple and mustn't do more than adding a VLAN entry.

Don't forget that we want the DSA drivers to be dump and have the core
logic of Ethernet switch handling resides in DSA core itself.

If some switch chips can flood broadcast without an FDB entry, good for
them, they can skip it. We will have the same issue for special L2
Multicast destination addresses, some switches have special bits to
consider them as management, some others don't and require to load the
ATU with them.

Regarding Marvell, what value do you have for the global FloodBC bit
(Global 2, offset 0x05)?


Thanks,

        Vivien

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 18:46       ` Andrew Lunn
@ 2017-09-27 19:19         ` Vivien Didelot
  2017-09-27 19:33           ` Florian Fainelli
  0 siblings, 1 reply; 25+ messages in thread
From: Vivien Didelot @ 2017-09-27 19:19 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli; +Cc: David Miller, netdev

Hi Andrew, Florian,

Andrew Lunn <andrew@lunn.ch> writes:

> It took me a while to make this work with CONFIG_BRIDGE_VLAN_FILTERING
> enabled. Any change to enable hardware flooding needs careful testing
> for lots of different configurations. This is another reason i don't
> want to do it at the DSA level, until we have a good understanding
> what it means in each individual driver.

Then if we are worried about how broadcast flooding is handled on
different switches, we can provide a new .flood_broadcast(ds, vid)
switch operation for the drivers to implement.

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 19:19         ` Vivien Didelot
@ 2017-09-27 19:33           ` Florian Fainelli
  2017-09-27 20:18             ` Andrew Lunn
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Fainelli @ 2017-09-27 19:33 UTC (permalink / raw)
  To: Vivien Didelot, Andrew Lunn; +Cc: David Miller, netdev

On 09/27/2017 12:19 PM, Vivien Didelot wrote:
> Hi Andrew, Florian,
> 
> Andrew Lunn <andrew@lunn.ch> writes:
> 
>> It took me a while to make this work with CONFIG_BRIDGE_VLAN_FILTERING
>> enabled. Any change to enable hardware flooding needs careful testing
>> for lots of different configurations. This is another reason i don't
>> want to do it at the DSA level, until we have a good understanding
>> what it means in each individual driver.
> 
> Then if we are worried about how broadcast flooding is handled on
> different switches, we can provide a new .flood_broadcast(ds, vid)
> switch operation for the drivers to implement.

We don't really have a good visibility on the number of switches
requiring special configuration for broadcast addresses nor how this
would have to happen so it would be a tad difficult to define an
appropriate API with a single user.

In general, single user "generic" facilities tend to be biased towards
their particular problem space (c.f: devlink) so a generic interface to
call into HW specific details does not usually sell well...
-- 
Florian

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

* Re: [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets
  2017-09-26 22:25 ` [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets Andrew Lunn
@ 2017-09-27 19:46   ` Florian Fainelli
  2017-09-27 20:11     ` Andrew Lunn
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Fainelli @ 2017-09-27 19:46 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: Vivien Didelot, netdev

On 09/26/2017 03:25 PM, Andrew Lunn wrote:
> The software bridge needs to know if a packet has already been bridged
> by hardware offload to ports in the same hardware offload, in order
> that it does not re-flood them, causing duplicates. This is
> particularly true for broadcast and multicast traffic which the host
> has requested.
> 
> By setting offload_fwd_mark in the skb the bridge will only flood to
> ports in other offloads and other netifs. Set this flag in the DSA and
> EDSA tag driver.

Is not there some kind of forwarding code/reason code being provided in
the EDSA/DSA tag that tell you why this packet was sent to the CPU in
the first place?

What is the impact on non-broadcast traffic, e.g: multicast and unicast?

Nit: I don't really have a solution on how to order patches, but until
the next 4 patches get in, I suppose we temporarily have broadcast
flooding by the bridge "broken"? Ordering in the opposite way would
probably result in an equally bad situation so...

> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> 
> v2
> --
> For the moment, do this in the tag drivers, not the generic code.
> Once we get more test results from other switches, maybe move it back
> again.
> ---
>  net/dsa/tag_dsa.c  | 1 +
>  net/dsa/tag_edsa.c | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
> index fbf9ca954773..ea6ada9d5016 100644
> --- a/net/dsa/tag_dsa.c
> +++ b/net/dsa/tag_dsa.c
> @@ -154,6 +154,7 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
>  	}
>  
>  	skb->dev = ds->ports[source_port].netdev;
> +	skb->offload_fwd_mark = 1;
>  
>  	return skb;
>  }
> diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
> index 76367ba1b2e2..a961b22a7018 100644
> --- a/net/dsa/tag_edsa.c
> +++ b/net/dsa/tag_edsa.c
> @@ -173,6 +173,7 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
>  	}
>  
>  	skb->dev = ds->ports[source_port].netdev;
> +	skb->offload_fwd_mark = 1;
>  
>  	return skb;
>  }
> 


-- 
Florian

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

* Re: [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets
  2017-09-27 19:46   ` Florian Fainelli
@ 2017-09-27 20:11     ` Andrew Lunn
  0 siblings, 0 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-27 20:11 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: David Miller, Vivien Didelot, netdev

On Wed, Sep 27, 2017 at 12:46:35PM -0700, Florian Fainelli wrote:
> On 09/26/2017 03:25 PM, Andrew Lunn wrote:
> > The software bridge needs to know if a packet has already been bridged
> > by hardware offload to ports in the same hardware offload, in order
> > that it does not re-flood them, causing duplicates. This is
> > particularly true for broadcast and multicast traffic which the host
> > has requested.
> > 
> > By setting offload_fwd_mark in the skb the bridge will only flood to
> > ports in other offloads and other netifs. Set this flag in the DSA and
> > EDSA tag driver.
> 
> Is not there some kind of forwarding code/reason code being provided in
> the EDSA/DSA tag that tell you why this packet was sent to the CPU in
> the first place?

Hi Florian

There are some codes, but nothing specific to broadcast, or ATU
misses. I'm also trying to keep the code generic so it could be a
template for other drivers. Many of the tagging schemes don't provide
a reason code. So i want that any frame that comes from the switch has
no need to go back to the switch. KISS.
 
> What is the impact on non-broadcast traffic, e.g: multicast and unicast?

The bridge uses this flag when flooding. unicast traffic from the
switch should not need flooding. Either it is known in the switch and
hence won't be forwarded to the host, or it is unknown in the switch,
so it probably is on some other interface.

My testing with multicast has not shown issues. The switch pushes down
mdb entries, which causes frames to be replicated out ports. So again,
there should not be a need to pass the frame back to the switch. But
it is possible i missed a corner case or two...
 
> Nit: I don't really have a solution on how to order patches, but until
> the next 4 patches get in, I suppose we temporarily have broadcast
> flooding by the bridge "broken"? Ordering in the opposite way would
> probably result in an equally bad situation so...

Yes, it is an issue. I could put this patch last. We then get
duplication of broadcast...

Which is the lesser of two evils?

      Andrew

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

* Re: [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware
  2017-09-27 19:33           ` Florian Fainelli
@ 2017-09-27 20:18             ` Andrew Lunn
  0 siblings, 0 replies; 25+ messages in thread
From: Andrew Lunn @ 2017-09-27 20:18 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: Vivien Didelot, David Miller, netdev

On Wed, Sep 27, 2017 at 12:33:29PM -0700, Florian Fainelli wrote:
> On 09/27/2017 12:19 PM, Vivien Didelot wrote:
> > Hi Andrew, Florian,
> > 
> > Andrew Lunn <andrew@lunn.ch> writes:
> > 
> >> It took me a while to make this work with CONFIG_BRIDGE_VLAN_FILTERING
> >> enabled. Any change to enable hardware flooding needs careful testing
> >> for lots of different configurations. This is another reason i don't
> >> want to do it at the DSA level, until we have a good understanding
> >> what it means in each individual driver.
> > 
> > Then if we are worried about how broadcast flooding is handled on
> > different switches, we can provide a new .flood_broadcast(ds, vid)
> > switch operation for the drivers to implement.
> 
> We don't really have a good visibility on the number of switches
> requiring special configuration for broadcast addresses nor how this
> would have to happen so it would be a tad difficult to define an
> appropriate API with a single user.

Yes, i agree with this. We should wait before adding a generic
solution. I want to wait until a few drivers do whatever is needed for
hardware broadcast. We can then see what is common, and what is
different, find an API to suit and do some refactoring.

	   Andrew

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

end of thread, other threads:[~2017-09-27 20:18 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-26 22:25 [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Andrew Lunn
2017-09-26 22:25 ` [PATCH net-next 1/6] net: dsa: Fix SWITCHDEV_ATTR_ID_PORT_PARENT_ID Andrew Lunn
2017-09-27 10:15   ` Sergei Shtylyov
2017-09-27 15:31   ` Vivien Didelot
2017-09-26 22:25 ` [PATCH net-next 2/6] net: dsa: {e}dsa: set offload_fwd_mark on received packets Andrew Lunn
2017-09-27 19:46   ` Florian Fainelli
2017-09-27 20:11     ` Andrew Lunn
2017-09-26 22:26 ` [PATCH net-next 3/6] net: dsa: mv88e6xxx: Fixed port netdev check for VLANs Andrew Lunn
2017-09-26 22:26 ` [PATCH net-next 4/6] net: dsa: mv88e6xxx: Print offending port when vlan check fails Andrew Lunn
2017-09-27 15:49   ` Vivien Didelot
2017-09-26 22:26 ` [PATCH net-next 5/6] net: dsa: mv88e6xxx: Move mv88e6xxx_port_db_load_purge() Andrew Lunn
2017-09-27 15:51   ` Vivien Didelot
2017-09-26 22:26 ` [PATCH net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware Andrew Lunn
2017-09-27 18:24   ` Vivien Didelot
2017-09-27 18:36     ` Andrew Lunn
2017-09-27 18:59       ` Vivien Didelot
2017-09-27 18:37     ` Florian Fainelli
2017-09-27 18:46       ` Andrew Lunn
2017-09-27 19:19         ` Vivien Didelot
2017-09-27 19:33           ` Florian Fainelli
2017-09-27 20:18             ` Andrew Lunn
2017-09-26 22:26 ` [PATCH 6/6] net: dsa: mv88e6xxx: Forward broadcast frames to cpu and dsa ports Andrew Lunn
2017-09-26 22:43   ` Andrew Lunn
2017-09-27  3:20   ` David Miller
2017-09-27 18:28 ` [PATCH net-next 0/6] mv88e6xxx broadcast flooding in hardware Vivien Didelot

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.