All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags
@ 2022-03-16 15:30 Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 1/5] switchdev: Add local_receive attribute Mattias Forsblad
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Mattias Forsblad @ 2022-03-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

Greetings,

This series implements new bridge flood flags
{flood,mcast_flood,bcast_flood}
and HW offloading for Marvell mv88e6xxx.

When using a non-VLAN filtering bridge we want to be able to limit
traffic to the CPU port to lessen the CPU load. This is specially
important when we have disabled learning on user ports.

A sample configuration could be something like this:

       br0
      /   \
   swp0   swp1

ip link add dev br0 type bridge stp_state 0 vlan_filtering 0
ip link set swp0 master br0
ip link set swp1 master br0
ip link set swp0 type bridge_slave learning off
ip link set swp1 type bridge_slave learning off
ip link set swp0 up
ip link set swp1 up
ip link set br0 type bridge flood 0 mcast_flood 0 bcast_flood 0
ip link set br0 up

To further explain the reasoning for this please refer to post by
Tobias Waldekranz:
https://lore.kernel.org/netdev/87ilsxo052.fsf@waldekranz.com/

The first part(1,2) of the series implements the flags for the SW bridge
and the second part(3) the DSA infrastructure. Part (4) implements
offloading of this flag to HW for mv88e6xxx, which uses the
port vlan table to restrict the ingress from user ports
to the CPU port when all of the flag is cleared. Part (5) adds
selftests for these flags.

v1 -> v2:
  - Split patch series in a more consistent way (Ido Shimmel)
  - Drop sysfs implementation (Ido, Nikolay Aleksandrov)
  - Change to use the boolopt API (Nikolay)
  - Drop ioctl implementation (Nikolay)
  - Split and rename local_receive to match bridge_slave
    {flood,mcast_flood,bcast_flood} (Ido)
  - Only handle the flags at apropiate places in the hot-path (Ido)
  - Add selftest (Ido)
  
Mattias Forsblad (5):
  switchdev: Add local_receive attribute
  net: bridge: Implement bridge flood flag
  dsa: Handle the flood flag in the DSA layer.
  mv88e6xxx: Offload the flood flag
  selftest: Add bridge flood flag tests

 drivers/net/dsa/mv88e6xxx/chip.c              |  45 ++++-
 include/linux/if_bridge.h                     |   6 +
 include/net/dsa.h                             |   7 +
 include/net/switchdev.h                       |   1 +
 include/uapi/linux/if_bridge.h                |   9 +-
 net/bridge/br.c                               |  46 +++++
 net/bridge/br_device.c                        |   3 +
 net/bridge/br_input.c                         |  23 ++-
 net/bridge/br_private.h                       |   4 +
 net/dsa/dsa_priv.h                            |   2 +
 net/dsa/slave.c                               |  18 ++
 .../testing/selftests/net/forwarding/Makefile |   1 +
 .../selftests/net/forwarding/bridge_flood.sh  | 169 ++++++++++++++++++
 tools/testing/selftests/net/forwarding/lib.sh |   8 +
 14 files changed, 335 insertions(+), 7 deletions(-)
 create mode 100755 tools/testing/selftests/net/forwarding/bridge_flood.sh

-- 
2.25.1


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

* [PATCH v2 net-next 1/5] switchdev: Add local_receive attribute
  2022-03-16 15:30 [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
@ 2022-03-16 15:30 ` Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag Mattias Forsblad
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Mattias Forsblad @ 2022-03-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

This commit adds the local_receive switchdev attribute in preparation
for bridge usage.

Signed-off-by: Mattias Forsblad <mattias.forsblad+netdev@gmail.com>
---
 include/net/switchdev.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 3e424d40fae3..f4c1671c2561 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -28,6 +28,7 @@ enum switchdev_attr_id {
 	SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
 	SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
 	SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
+	SWITCHDEV_ATTR_ID_BRIDGE_FLOOD,
 };
 
 struct switchdev_brport_flags {
-- 
2.25.1


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

* [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag
  2022-03-16 15:30 [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 1/5] switchdev: Add local_receive attribute Mattias Forsblad
@ 2022-03-16 15:30 ` Mattias Forsblad
  2022-03-16 20:06   ` Jakub Kicinski
  2022-03-16 20:49   ` kernel test robot
  2022-03-16 15:30 ` [PATCH v2 net-next 3/5] dsa: Handle the flood flag in the DSA layer Mattias Forsblad
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 8+ messages in thread
From: Mattias Forsblad @ 2022-03-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

This patch implements the bridge flood flags. There are three different
flags matching unicast, multicast and broadcast. When the corresponding
flag is cleared packets received on bridge ports will not be flooded
towards the bridge.
This makes is possible to only forward selected traffic between the
port members of the bridge.

Signed-off-by: Mattias Forsblad <mattias.forsblad+netdev@gmail.com>
---
 include/linux/if_bridge.h      |  6 +++++
 include/uapi/linux/if_bridge.h |  9 ++++++-
 net/bridge/br.c                | 46 ++++++++++++++++++++++++++++++++++
 net/bridge/br_device.c         |  3 +++
 net/bridge/br_input.c          | 23 ++++++++++++++---
 net/bridge/br_private.h        |  4 +++
 6 files changed, 86 insertions(+), 5 deletions(-)

diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 3aae023a9353..fa8e000a6fb9 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -157,6 +157,7 @@ static inline int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid,
 struct net_device *br_fdb_find_port(const struct net_device *br_dev,
 				    const unsigned char *addr,
 				    __u16 vid);
+bool br_flood_enabled(const struct net_device *dev);
 void br_fdb_clear_offload(const struct net_device *dev, u16 vid);
 bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag);
 u8 br_port_get_stp_state(const struct net_device *dev);
@@ -170,6 +171,11 @@ br_fdb_find_port(const struct net_device *br_dev,
 	return NULL;
 }
 
+static inline bool br_flood_enabled(const struct net_device *dev)
+{
+	return true;
+}
+
 static inline void br_fdb_clear_offload(const struct net_device *dev, u16 vid)
 {
 }
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index 2711c3522010..765ed70c9b28 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -72,6 +72,7 @@ struct __bridge_info {
 	__u32 tcn_timer_value;
 	__u32 topology_change_timer_value;
 	__u32 gc_timer_value;
+	__u8 flood;
 };
 
 struct __port_info {
@@ -752,13 +753,19 @@ struct br_mcast_stats {
 /* bridge boolean options
  * BR_BOOLOPT_NO_LL_LEARN - disable learning from link-local packets
  * BR_BOOLOPT_MCAST_VLAN_SNOOPING - control vlan multicast snooping
+ * BR_BOOLOPT_FLOOD - control bridge flood flag
+ * BR_BOOLOPT_MCAST_FLOOD - control bridge multicast flood flag
+ * BR_BOOLOPT_BCAST_FLOOD - control bridge broadcast flood flag
  *
  * IMPORTANT: if adding a new option do not forget to handle
- *            it in br_boolopt_toggle/get and bridge sysfs
+ *            it in br_boolopt_toggle/get
  */
 enum br_boolopt_id {
 	BR_BOOLOPT_NO_LL_LEARN,
 	BR_BOOLOPT_MCAST_VLAN_SNOOPING,
+	BR_BOOLOPT_FLOOD,
+	BR_BOOLOPT_MCAST_FLOOD,
+	BR_BOOLOPT_BCAST_FLOOD,
 	BR_BOOLOPT_MAX
 };
 
diff --git a/net/bridge/br.c b/net/bridge/br.c
index b1dea3febeea..52a8b4e14143 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -265,6 +265,11 @@ int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on,
 	case BR_BOOLOPT_MCAST_VLAN_SNOOPING:
 		err = br_multicast_toggle_vlan_snooping(br, on, extack);
 		break;
+	case BR_BOOLOPT_FLOOD:
+	case BR_BOOLOPT_MCAST_FLOOD:
+	case BR_BOOLOPT_BCAST_FLOOD:
+		err = br_flood_toggle(br, opt, on);
+		break;
 	default:
 		/* shouldn't be called with unsupported options */
 		WARN_ON(1);
@@ -281,6 +286,12 @@ int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt)
 		return br_opt_get(br, BROPT_NO_LL_LEARN);
 	case BR_BOOLOPT_MCAST_VLAN_SNOOPING:
 		return br_opt_get(br, BROPT_MCAST_VLAN_SNOOPING_ENABLED);
+	case BR_BOOLOPT_FLOOD:
+		return br_opt_get(br, BROPT_FLOOD);
+	case BR_BOOLOPT_MCAST_FLOOD:
+		return br_opt_get(br, BROPT_MCAST_FLOOD);
+	case BR_BOOLOPT_BCAST_FLOOD:
+		return br_opt_get(br, BROPT_BCAST_FLOOD);
 	default:
 		/* shouldn't be called with unsupported options */
 		WARN_ON(1);
@@ -325,6 +336,41 @@ void br_boolopt_multi_get(const struct net_bridge *br,
 	bm->optmask = GENMASK((BR_BOOLOPT_MAX - 1), 0);
 }
 
+int br_flood_toggle(struct net_bridge *br, enum br_boolopt_id opt,
+		    bool on)
+{
+	struct switchdev_attr attr = {
+		.orig_dev = br->dev,
+		.id = SWITCHDEV_ATTR_ID_BRIDGE_FLOOD,
+		.flags = SWITCHDEV_F_DEFER,
+	};
+	struct br_boolopt_multi bm;
+	enum net_bridge_opts bropt;
+	int ret;
+
+	switch (opt) {
+	case BR_BOOLOPT_FLOOD:
+		bropt = BROPT_FLOOD;
+		break;
+	case BR_BOOLOPT_MCAST_FLOOD:
+		bropt = BROPT_MCAST_FLOOD;
+		break;
+	case BR_BOOLOPT_BCAST_FLOOD:
+		bropt = BROPT_BCAST_FLOOD;
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+	br_opt_toggle(br, bropt, on);
+
+	attr.u.brport_flags.mask = BIT(bropt);
+	attr.u.brport_flags.val = on << bropt;
+	ret = switchdev_port_attr_set(br->dev, &attr, NULL);
+
+	return ret;
+}
+
 /* private bridge options, controlled by the kernel */
 void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on)
 {
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 8d6bab244c4a..fafaef9d4b3a 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -524,6 +524,9 @@ void br_dev_setup(struct net_device *dev)
 	br->bridge_hello_time = br->hello_time = 2 * HZ;
 	br->bridge_forward_delay = br->forward_delay = 15 * HZ;
 	br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME;
+	br_opt_toggle(br, BROPT_FLOOD, true);
+	br_opt_toggle(br, BROPT_MCAST_FLOOD, true);
+	br_opt_toggle(br, BROPT_BCAST_FLOOD, true);
 	dev->max_mtu = ETH_MAX_MTU;
 
 	br_netfilter_rtable_init(br);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index e0c13fcc50ed..fcb0757bfdcc 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -109,11 +109,12 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
 		/* by definition the broadcast is also a multicast address */
 		if (is_broadcast_ether_addr(eth_hdr(skb)->h_dest)) {
 			pkt_type = BR_PKT_BROADCAST;
-			local_rcv = true;
+			local_rcv = true && br_opt_get(br, BROPT_BCAST_FLOOD);
 		} else {
 			pkt_type = BR_PKT_MULTICAST;
-			if (br_multicast_rcv(&brmctx, &pmctx, vlan, skb, vid))
-				goto drop;
+			if (br_opt_get(br, BROPT_MCAST_FLOOD))
+				if (br_multicast_rcv(&brmctx, &pmctx, vlan, skb, vid))
+					goto drop;
 		}
 	}
 
@@ -155,9 +156,13 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
 			local_rcv = true;
 			br->dev->stats.multicast++;
 		}
+		if (!br_opt_get(br, BROPT_MCAST_FLOOD))
+			local_rcv = false;
 		break;
 	case BR_PKT_UNICAST:
 		dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid);
+		if (!br_opt_get(br, BROPT_FLOOD))
+			local_rcv = false;
 		break;
 	default:
 		break;
@@ -166,7 +171,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
 	if (dst) {
 		unsigned long now = jiffies;
 
-		if (test_bit(BR_FDB_LOCAL, &dst->flags))
+		if (test_bit(BR_FDB_LOCAL, &dst->flags) && local_rcv)
 			return br_pass_frame_up(skb);
 
 		if (now != dst->used)
@@ -190,6 +195,16 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
 }
 EXPORT_SYMBOL_GPL(br_handle_frame_finish);
 
+bool br_flood_enabled(const struct net_device *dev)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	return !!(br_opt_get(br, BROPT_FLOOD) ||
+		   br_opt_get(br, BROPT_MCAST_FLOOD) ||
+		   br_opt_get(br, BROPT_BCAST_FLOOD));
+}
+EXPORT_SYMBOL_GPL(br_flood_enabled);
+
 static void __br_handle_local_finish(struct sk_buff *skb)
 {
 	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 48bc61ebc211..cf88dce0b92b 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -445,6 +445,9 @@ enum net_bridge_opts {
 	BROPT_NO_LL_LEARN,
 	BROPT_VLAN_BRIDGE_BINDING,
 	BROPT_MCAST_VLAN_SNOOPING_ENABLED,
+	BROPT_FLOOD,
+	BROPT_MCAST_FLOOD,
+	BROPT_BCAST_FLOOD,
 };
 
 struct net_bridge {
@@ -720,6 +723,7 @@ int br_boolopt_multi_toggle(struct net_bridge *br,
 void br_boolopt_multi_get(const struct net_bridge *br,
 			  struct br_boolopt_multi *bm);
 void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on);
+int br_flood_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on);
 
 /* br_device.c */
 void br_dev_setup(struct net_device *dev);
-- 
2.25.1


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

* [PATCH v2 net-next 3/5] dsa: Handle the flood flag in the DSA layer.
  2022-03-16 15:30 [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 1/5] switchdev: Add local_receive attribute Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag Mattias Forsblad
@ 2022-03-16 15:30 ` Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 4/5] mv88e6xxx: Offload the flood flag Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 5/5] selftest: Add bridge flood flag tests Mattias Forsblad
  4 siblings, 0 replies; 8+ messages in thread
From: Mattias Forsblad @ 2022-03-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

Add infrastructure to be able to handle the flood
flag in the DSA layer.

Signed-off-by: Mattias Forsblad <mattias.forsblad+netdev@gmail.com>
---
 include/net/dsa.h  |  7 +++++++
 net/dsa/dsa_priv.h |  2 ++
 net/dsa/slave.c    | 18 ++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 9bfe984fcdbf..fcb47dc832e1 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -939,6 +939,13 @@ struct dsa_switch_ops {
 	void	(*get_regs)(struct dsa_switch *ds, int port,
 			    struct ethtool_regs *regs, void *p);
 
+	/*
+	 * Local receive
+	 */
+	int	(*set_flood)(struct dsa_switch *ds, int port,
+				     struct net_device *bridge, unsigned long mask,
+				     unsigned long val);
+
 	/*
 	 * Upper device tracking.
 	 */
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index f20bdd8ea0a8..ca3ea320c8eb 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -234,6 +234,8 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
 			    struct netlink_ext_ack *extack);
 bool dsa_port_skip_vlan_configuration(struct dsa_port *dp);
 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock);
+int dsa_port_set_flood(struct dsa_port *dp, struct net_device *br, unsigned long mask,
+		       unsigned long val);
 int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu,
 			bool targeted_match);
 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index f9cecda791d5..1349dda6b3e6 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -458,6 +458,13 @@ static int dsa_slave_port_attr_set(struct net_device *dev, const void *ctx,
 		ret = dsa_port_vlan_filtering(dp, attr->u.vlan_filtering,
 					      extack);
 		break;
+	case SWITCHDEV_ATTR_ID_BRIDGE_FLOOD:
+		if (!dsa_port_offloads_bridge_dev(dp, attr->orig_dev))
+			return -EOPNOTSUPP;
+
+		ret = dsa_port_set_flood(dp, attr->orig_dev, attr->u.brport_flags.mask,
+					 attr->u.brport_flags.val);
+		break;
 	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
 		if (!dsa_port_offloads_bridge_dev(dp, attr->orig_dev))
 			return -EOPNOTSUPP;
@@ -834,6 +841,17 @@ dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
 		ds->ops->get_regs(ds, dp->index, regs, _p);
 }
 
+int dsa_port_set_flood(struct dsa_port *dp, struct net_device *br, unsigned long mask,
+		       unsigned long val)
+{
+	struct dsa_switch *ds = dp->ds;
+
+	if (ds->ops->set_flood)
+		return ds->ops->set_flood(ds, dp->index, br, mask, val);
+
+	return 0;
+}
+
 static int dsa_slave_nway_reset(struct net_device *dev)
 {
 	struct dsa_port *dp = dsa_slave_to_port(dev);
-- 
2.25.1


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

* [PATCH v2 net-next 4/5] mv88e6xxx: Offload the flood flag
  2022-03-16 15:30 [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
                   ` (2 preceding siblings ...)
  2022-03-16 15:30 ` [PATCH v2 net-next 3/5] dsa: Handle the flood flag in the DSA layer Mattias Forsblad
@ 2022-03-16 15:30 ` Mattias Forsblad
  2022-03-16 15:30 ` [PATCH v2 net-next 5/5] selftest: Add bridge flood flag tests Mattias Forsblad
  4 siblings, 0 replies; 8+ messages in thread
From: Mattias Forsblad @ 2022-03-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

Use the port vlan table to restrict ingressing traffic to the
CPU port if the flood flags are cleared.

Signed-off-by: Mattias Forsblad <mattias.forsblad+netdev@gmail.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 45 ++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 84b90fc36c58..39347a05c3a5 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1384,6 +1384,7 @@ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
 	struct dsa_switch *ds = chip->ds;
 	struct dsa_switch_tree *dst = ds->dst;
 	struct dsa_port *dp, *other_dp;
+	bool flood = true;
 	bool found = false;
 	u16 pvlan;
 
@@ -1425,6 +1426,9 @@ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
 
 	pvlan = 0;
 
+	if (dp->bridge)
+		flood = br_flood_enabled(dp->bridge->dev);
+
 	/* Frames from standalone user ports can only egress on the
 	 * upstream port.
 	 */
@@ -1433,10 +1437,11 @@ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
 
 	/* Frames from bridged user ports can egress any local DSA
 	 * links and CPU ports, as well as any local member of their
-	 * bridge group.
+	 * as well as any local member of their bridge group. However, CPU ports
+	 * are omitted if flood is cleared.
 	 */
 	dsa_switch_for_each_port(other_dp, ds)
-		if (other_dp->type == DSA_PORT_TYPE_CPU ||
+		if ((other_dp->type == DSA_PORT_TYPE_CPU && flood) ||
 		    other_dp->type == DSA_PORT_TYPE_DSA ||
 		    dsa_port_bridge_same(dp, other_dp))
 			pvlan |= BIT(other_dp->index);
@@ -2718,6 +2723,41 @@ static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
 	mv88e6xxx_reg_unlock(chip);
 }
 
+static int mv88e6xxx_set_flood(struct dsa_switch *ds, int port, struct net_device *br,
+			       unsigned long mask, unsigned long val)
+{
+	struct mv88e6xxx_chip *chip = ds->priv;
+	struct dsa_bridge *bridge;
+	struct dsa_port *dp;
+	bool found = false;
+	int err;
+
+	if (!netif_is_bridge_master(br))
+		return 0;
+
+	list_for_each_entry(dp, &ds->dst->ports, list) {
+		if (dp->ds == ds && dp->index == port) {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+		return 0;
+
+	bridge = dp->bridge;
+	if (!bridge)
+		return 0;
+
+	mv88e6xxx_reg_lock(chip);
+
+	err = mv88e6xxx_bridge_map(chip, *bridge);
+
+	mv88e6xxx_reg_unlock(chip);
+
+	return err;
+}
+
 static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
 {
 	if (chip->info->ops->reset)
@@ -6478,6 +6518,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
 	.set_eeprom		= mv88e6xxx_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
+	.set_flood		= mv88e6xxx_set_flood,
 	.get_rxnfc		= mv88e6xxx_get_rxnfc,
 	.set_rxnfc		= mv88e6xxx_set_rxnfc,
 	.set_ageing_time	= mv88e6xxx_set_ageing_time,
-- 
2.25.1


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

* [PATCH v2 net-next 5/5] selftest: Add bridge flood flag tests
  2022-03-16 15:30 [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
                   ` (3 preceding siblings ...)
  2022-03-16 15:30 ` [PATCH v2 net-next 4/5] mv88e6xxx: Offload the flood flag Mattias Forsblad
@ 2022-03-16 15:30 ` Mattias Forsblad
  4 siblings, 0 replies; 8+ messages in thread
From: Mattias Forsblad @ 2022-03-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

Add test to check that the bridge flood flags works correctly.
When the bridge flag {flood,mcast_flood,bcast_flood} are cleared
no packets of the corresponding type should be flooded to the
bridge.

Signed-off-by: Mattias Forsblad <mattias.forsblad+netdev@gmail.com>
---
 .../testing/selftests/net/forwarding/Makefile |   1 +
 .../selftests/net/forwarding/bridge_flood.sh  | 169 ++++++++++++++++++
 tools/testing/selftests/net/forwarding/lib.sh |   8 +
 3 files changed, 178 insertions(+)
 create mode 100755 tools/testing/selftests/net/forwarding/bridge_flood.sh

diff --git a/tools/testing/selftests/net/forwarding/Makefile b/tools/testing/selftests/net/forwarding/Makefile
index 8fa97ae9af9e..24ca6a333edd 100644
--- a/tools/testing/selftests/net/forwarding/Makefile
+++ b/tools/testing/selftests/net/forwarding/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+ OR MIT
 
 TEST_PROGS = bridge_igmp.sh \
+	bridge_flood.sh \
 	bridge_locked_port.sh \
 	bridge_port_isolation.sh \
 	bridge_sticky_fdb.sh \
diff --git a/tools/testing/selftests/net/forwarding/bridge_flood.sh b/tools/testing/selftests/net/forwarding/bridge_flood.sh
new file mode 100755
index 000000000000..ea3e7da139aa
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/bridge_flood.sh
@@ -0,0 +1,169 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+ALL_TESTS="ping_test bridge_flood"
+NUM_NETIFS=4
+CHECK_TC="no"
+source lib.sh
+bridge=br3
+
+h1_create()
+{
+	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
+}
+
+h1_destroy()
+{
+	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
+}
+
+h2_create()
+{
+	simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
+}
+
+h2_destroy()
+{
+	simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
+}
+
+switch_create()
+{
+	ip link add dev $bridge type bridge
+
+	ip link set dev $swp1 master $bridge
+	ip link set dev $swp2 master $bridge
+	ip link set dev $swp1 type bridge_slave learning off
+	ip link set dev $swp2 type bridge_slave learning off
+
+	ip link set dev $bridge type bridge flood 0 mcast_flood 0 bcast_flood 0
+	check_err $? "Can't set bridge flooding off on $bridge"
+
+	ip link set dev $bridge up
+	ip link set dev $bridge promisc on
+	ip link set dev $swp1 up
+	ip link set dev $swp2 up
+}
+
+switch_destroy()
+{
+	ip link set dev $swp2 down
+	ip link set dev $swp1 down
+
+	ip link del dev $bridge
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+	swp1=${NETIFS[p2]}
+
+	swp2=${NETIFS[p3]}
+	h2=${NETIFS[p4]}
+
+	vrf_prepare
+
+	h1_create
+	h2_create
+
+	switch_create
+}
+
+ping_test()
+{
+	echo "Check connectivity /w ping"
+	ping_do $h1 192.0.2.2
+	check_err $? "ping fail"
+	log_test "ping test"
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	switch_destroy
+
+	h2_destroy
+	h1_destroy
+
+	vrf_cleanup
+}
+
+bridge_flood_test_do()
+{
+	local should_flood=$1
+	local mac=$2
+	local ip=$3
+	local host1_if=$4
+	local err=0
+	local vrf_name
+
+
+	# Add an ACL on `host2_if` which will tell us whether the packet
+	# was flooded to it or not.
+	tc qdisc add dev $bridge ingress
+	tc filter add dev $bridge ingress protocol ip pref 1 handle 101 \
+		flower dst_mac $mac action drop
+
+	vrf_name=$(master_name_get $host1_if)
+	ip vrf exec $vrf_name \
+		$MZ $host1_if -c 1 -p 64 -b $mac -B $ip -t ip -q
+	sleep 1
+
+	tc -j -s filter show dev $bridge ingress \
+		| jq -e ".[] | select(.options.handle == 101) \
+		| select(.options.actions[0].stats.packets == 1)" &> /dev/null
+	if [[ $? -ne 0 && $should_flood == "true" || \
+	      $? -eq 0 && $should_flood == "false" ]]; then
+		err=1
+	fi
+
+	tc filter del dev $bridge ingress protocol ip pref 1 handle 101 flower
+	tc qdisc del dev $bridge ingress
+
+	return $err
+}
+
+bridge_flood_test()
+{
+	local mac=$1
+	local ip=$2
+	local flag=$3
+
+	RET=0
+
+	ip link set dev $bridge type bridge $flag 0
+
+	bridge_flood_test_do false $mac $ip $h1 $bridge
+	check_err $? "Packet flooded when should not"
+	log_test "Bridge test flag $flag disabled"
+
+	ip link set dev $bridge type bridge $flag 1
+
+	bridge_flood_test_do true $mac $ip $h1 $bridge
+	check_err $? "Packet was not flooded when should"
+
+	log_test "Bridge test flag $flag enabled"
+}
+
+bridge_flood()
+{
+	RET=0
+
+	check_bridge_flood_support $bridge || return 0
+
+	bridge_flood_test de:ad:be:ef:13:37 192.0.2.100 flood
+
+	bridge_flood_test 01:00:5e:00:00:01 239.0.0.1 mcast_flood
+
+	bridge_flood_test ff:ff:ff:ff:ff:ff 192.0.2.100 bcast_flood
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+
+tests_run
+
+exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 664b9ecaf228..12e69837374e 100644
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -134,6 +134,14 @@ check_locked_port_support()
 	fi
 }
 
+check_bridge_flood_support()
+{
+	if ! ip -d link show dev $1 | grep -q " flood"; then
+		echo "SKIP: iproute2 too old; Bridge flood feature not supported."
+		return $ksft_skip
+	fi
+}
+
 if [[ "$(id -u)" -ne 0 ]]; then
 	echo "SKIP: need root privileges"
 	exit $ksft_skip
-- 
2.25.1


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

* Re: [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag
  2022-03-16 15:30 ` [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag Mattias Forsblad
@ 2022-03-16 20:06   ` Jakub Kicinski
  2022-03-16 20:49   ` kernel test robot
  1 sibling, 0 replies; 8+ messages in thread
From: Jakub Kicinski @ 2022-03-16 20:06 UTC (permalink / raw)
  To: Mattias Forsblad
  Cc: netdev, David S . Miller, Andrew Lunn, Florian Fainelli,
	Vivien Didelot, Roopa Prabhu, Tobias Waldekranz,
	Mattias Forsblad

On Wed, 16 Mar 2022 16:30:56 +0100 Mattias Forsblad wrote:
> This patch implements the bridge flood flags. There are three different
> flags matching unicast, multicast and broadcast. When the corresponding
> flag is cleared packets received on bridge ports will not be flooded
> towards the bridge.
> This makes is possible to only forward selected traffic between the
> port members of the bridge.

net/bridge/br.c: In function ‘br_flood_toggle’:
net/bridge/br.c:347:33: warning: unused variable ‘bm’ [-Wunused-variable]
  347 |         struct br_boolopt_multi bm;
      |                                 ^~

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

* Re: [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag
  2022-03-16 15:30 ` [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag Mattias Forsblad
  2022-03-16 20:06   ` Jakub Kicinski
@ 2022-03-16 20:49   ` kernel test robot
  1 sibling, 0 replies; 8+ messages in thread
From: kernel test robot @ 2022-03-16 20:49 UTC (permalink / raw)
  To: Mattias Forsblad, netdev
  Cc: llvm, kbuild-all, David S . Miller, Jakub Kicinski, Andrew Lunn,
	Florian Fainelli, Vivien Didelot, Roopa Prabhu,
	Tobias Waldekranz, Mattias Forsblad

Hi Mattias,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Mattias-Forsblad/bridge-dsa-switchdev-mv88e6xxx-Implement-bridge-flood-flags/20220316-233416
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 9f01cfbf2922432668c2fd4dfc0413342aaff48b
config: hexagon-randconfig-r045-20220313 (https://download.01.org/0day-ci/archive/20220317/202203170401.hynO2BwT-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project a6ec1e3d798f8eab43fb3a91028c6ab04e115fcb)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/4c003fec67078a4e8c1c6e36c7b9fc6303a3bb6f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Mattias-Forsblad/bridge-dsa-switchdev-mv88e6xxx-Implement-bridge-flood-flags/20220316-233416
        git checkout 4c003fec67078a4e8c1c6e36c7b9fc6303a3bb6f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash net/bridge/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   net/bridge/br.c:347:26: warning: unused variable 'bm' [-Wunused-variable]
           struct br_boolopt_multi bm;
                                   ^
>> net/bridge/br.c:361:2: warning: variable 'bropt' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
           default:
           ^~~~~~~
   net/bridge/br.c:365:20: note: uninitialized use occurs here
           br_opt_toggle(br, bropt, on);
                             ^~~~~
   net/bridge/br.c:348:2: note: variable 'bropt' is declared here
           enum net_bridge_opts bropt;
           ^
   2 warnings generated.


vim +/bropt +361 net/bridge/br.c

   338	
   339	int br_flood_toggle(struct net_bridge *br, enum br_boolopt_id opt,
   340			    bool on)
   341	{
   342		struct switchdev_attr attr = {
   343			.orig_dev = br->dev,
   344			.id = SWITCHDEV_ATTR_ID_BRIDGE_FLOOD,
   345			.flags = SWITCHDEV_F_DEFER,
   346		};
   347		struct br_boolopt_multi bm;
   348		enum net_bridge_opts bropt;
   349		int ret;
   350	
   351		switch (opt) {
   352		case BR_BOOLOPT_FLOOD:
   353			bropt = BROPT_FLOOD;
   354			break;
   355		case BR_BOOLOPT_MCAST_FLOOD:
   356			bropt = BROPT_MCAST_FLOOD;
   357			break;
   358		case BR_BOOLOPT_BCAST_FLOOD:
   359			bropt = BROPT_BCAST_FLOOD;
   360			break;
 > 361		default:
   362			WARN_ON(1);
   363			break;
   364		}
   365		br_opt_toggle(br, bropt, on);
   366	
   367		attr.u.brport_flags.mask = BIT(bropt);
   368		attr.u.brport_flags.val = on << bropt;
   369		ret = switchdev_port_attr_set(br->dev, &attr, NULL);
   370	
   371		return ret;
   372	}
   373	

---
0-DAY CI Kernel Test Service
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

end of thread, other threads:[~2022-03-16 20:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-16 15:30 [PATCH v2 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
2022-03-16 15:30 ` [PATCH v2 net-next 1/5] switchdev: Add local_receive attribute Mattias Forsblad
2022-03-16 15:30 ` [PATCH v2 net-next 2/5] net: bridge: Implement bridge flood flag Mattias Forsblad
2022-03-16 20:06   ` Jakub Kicinski
2022-03-16 20:49   ` kernel test robot
2022-03-16 15:30 ` [PATCH v2 net-next 3/5] dsa: Handle the flood flag in the DSA layer Mattias Forsblad
2022-03-16 15:30 ` [PATCH v2 net-next 4/5] mv88e6xxx: Offload the flood flag Mattias Forsblad
2022-03-16 15:30 ` [PATCH v2 net-next 5/5] selftest: Add bridge flood flag tests Mattias Forsblad

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.