lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e315723f5bf03efcf7819d1740ad2cd1b2aac2c9.1704449760.git.ante.knezic@helmholz.de>
Date: Fri, 5 Jan 2024 11:46:17 +0100
From: Ante Knezic <ante.knezic@...mholz.de>
To: <netdev@...r.kernel.org>
CC: <andrew@...n.ch>, <f.fainelli@...il.com>, <olteanv@...il.com>,
	<davem@...emloft.net>, <edumazet@...gle.com>, <kuba@...nel.org>,
	<pabeni@...hat.com>, <ante.knezic@...mholz.de>
Subject: [RFC PATCH net-next 4/6] net: dsa: check for busy mirror ports when removing mirroring action

Check if the source/destination mirror ports are being used by
another mirroring route. This is necessary as otherwise we
might be interfering with mirroring operation of another mirror
route.

Signed-off-by: Ante Knezic <ante.knezic@...mholz.de>
---
 drivers/net/dsa/b53/b53_common.c       |  3 ++-
 drivers/net/dsa/b53/b53_priv.h         |  2 +-
 drivers/net/dsa/microchip/ksz_common.c |  3 ++-
 drivers/net/dsa/mt7530.c               |  3 ++-
 drivers/net/dsa/mv88e6xxx/chip.c       |  3 ++-
 drivers/net/dsa/ocelot/felix.c         |  3 ++-
 drivers/net/dsa/qca/qca8k-common.c     |  3 ++-
 drivers/net/dsa/qca/qca8k.h            |  3 ++-
 drivers/net/dsa/sja1105/sja1105_main.c |  3 ++-
 include/net/dsa.h                      | 10 +++++++++-
 net/dsa/switch.c                       | 34 +++++++++++++++++++++++++++++++++-
 11 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 993adbc81339..79b2c9dab77d 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2155,7 +2155,8 @@ int b53_mirror_add(struct dsa_switch *ds, int from_port,
 EXPORT_SYMBOL(b53_mirror_add);
 
 void b53_mirror_del(struct dsa_switch *ds, int from_port,
-		    int to_port, bool ingress)
+		    int to_port, bool ingress,
+		    enum dsa_route_status route_status)
 {
 	struct b53_device *dev = ds->priv;
 	bool loc_disable = false, other_loc_disable = false;
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index 625dafcd757b..d78b3d04ffe0 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -391,7 +391,7 @@ int b53_mirror_add(struct dsa_switch *ds, int from_port,
 enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
 					   enum dsa_tag_protocol mprot);
 void b53_mirror_del(struct dsa_switch *ds, int from_port, int to_port,
-		    bool ingress);
+		    bool ingress, enum dsa_route_status route_status);
 int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
 void b53_disable_port(struct dsa_switch *ds, int port);
 void b53_brcm_hdr_setup(struct dsa_switch *ds, int port);
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 824bfb0ed0ad..ab2a65ba498c 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2783,7 +2783,8 @@ static int ksz_port_mirror_add(struct dsa_switch *ds, int from_port,
 }
 
 static void ksz_port_mirror_del(struct dsa_switch *ds, int from_port,
-				int to_port, bool ingress)
+				int to_port, bool ingress,
+				enum dsa_route_status route_status)
 {
 	struct ksz_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 9e284edfbd0e..aba020687427 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1799,7 +1799,8 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int from_port,
 }
 
 static void mt753x_port_mirror_del(struct dsa_switch *ds, int from_port,
-				   int to_port, bool ingress)
+			   int to_port, bool ingress,
+			   enum dsa_route_status route_status)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 val;
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index b8820b31d05b..1938f0b1644f 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -6520,7 +6520,8 @@ static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int from_port,
 }
 
 static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int from_port,
-				      int to_port, bool ingress)
+				      int to_port, bool ingress,
+				      enum dsa_route_status route_status)
 {
 	enum mv88e6xxx_egress_direction direction = ingress ?
 						MV88E6XXX_EGRESS_DIR_INGRESS :
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index c3d21e06bde3..0ba9a79316d3 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1864,7 +1864,8 @@ static int felix_port_mirror_add(struct dsa_switch *ds, int from_port,
 }
 
 static void felix_port_mirror_del(struct dsa_switch *ds, int from_port,
-				  int to_port, bool ingress)
+				  int to_port, bool ingress,
+				  enum dsa_route_status route_status)
 {
 	struct ocelot *ocelot = ds->priv;
 
diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
index 4ff6763a81ce..fc009f3c460a 100644
--- a/drivers/net/dsa/qca/qca8k-common.c
+++ b/drivers/net/dsa/qca/qca8k-common.c
@@ -940,7 +940,8 @@ int qca8k_port_mirror_add(struct dsa_switch *ds, int from_port,
 }
 
 void qca8k_port_mirror_del(struct dsa_switch *ds, int from_port,
-			   int to_port, bool ingress)
+			   int to_port, bool ingress,
+			   enum dsa_route_status route_status)
 {
 	struct qca8k_priv *priv = ds->priv;
 	u32 reg, val;
diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
index 7c6e75a37e13..7a4ac5d4a505 100644
--- a/drivers/net/dsa/qca/qca8k.h
+++ b/drivers/net/dsa/qca/qca8k.h
@@ -573,7 +573,8 @@ int qca8k_port_mirror_add(struct dsa_switch *ds, int from_port,
 			  int to_port, bool ingress,
 			  struct netlink_ext_ack *extack);
 void qca8k_port_mirror_del(struct dsa_switch *ds, int from_port,
-			   int to_port, bool ingress);
+			   int to_port, bool ingress,
+			   enum dsa_route_status route_status);
 
 /* Common port VLAN function */
 int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 7f4cb3a1f39d..bb4a703174c5 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -2903,7 +2903,8 @@ static int sja1105_mirror_add(struct dsa_switch *ds, int from_port, int to_port,
 }
 
 static void sja1105_mirror_del(struct dsa_switch *ds, int from_port,
-			       int to_port, bool ingress)
+			       int to_port, bool ingress,
+			       enum dsa_route_status route_status)
 {
 	sja1105_mirror_apply(ds->priv, from_port, to_port,
 			     ingress, false);
diff --git a/include/net/dsa.h b/include/net/dsa.h
index aa0e97150bc3..f17da56d138d 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -88,6 +88,13 @@ enum dsa_tag_protocol {
 	DSA_TAG_PROTO_LAN937X		= DSA_TAG_PROTO_LAN937X_VALUE,
 };
 
+enum dsa_route_status {
+	DSA_ROUTE_UNUSED = 0,
+	DSA_ROUTE_SRC_PORT_BUSY = BIT(0),
+	DSA_ROUTE_DEST_PORT_BUSY = BIT(1),
+	DSA_ROUTE_BUSY = (BIT(0) | BIT(1))
+};
+
 struct dsa_switch;
 
 struct dsa_device_ops {
@@ -1120,7 +1127,8 @@ struct dsa_switch_ops {
 				   int to_port, bool ingress,
 				   struct netlink_ext_ack *extack);
 	void	(*port_mirror_del)(struct dsa_switch *ds, int from_port,
-				   int to_port, bool ingress);
+				   int to_port, bool ingress,
+				   enum dsa_route_status route_status);
 	int	(*port_policer_add)(struct dsa_switch *ds, int port,
 				    struct dsa_mall_policer_tc_entry *policer);
 	void	(*port_policer_del)(struct dsa_switch *ds, int port);
diff --git a/net/dsa/switch.c b/net/dsa/switch.c
index 5a81742cb139..17d71bde5df5 100644
--- a/net/dsa/switch.c
+++ b/net/dsa/switch.c
@@ -148,9 +148,38 @@ static int dsa_switch_mirror_add(struct dsa_switch *ds,
 	return 0;
 }
 
+static enum dsa_route_status dsa_route_get_status(struct dsa_switch *ds,
+						  const struct dsa_mirror *dm,
+						  int from_port, int to_port)
+{
+	enum dsa_route_status ret;
+	struct dsa_mirror *m;
+	struct dsa_route *r;
+
+	ret = DSA_ROUTE_UNUSED;
+	list_for_each_entry(m, &ds->dst->mirrors, list) {
+		if (m == dm)
+			continue;
+		if (m->ingress != dm->ingress)
+			continue;
+
+		list_for_each_entry(r, &m->route, list) {
+			if (r->sw_index == ds->index) {
+				if (r->from_local_p == from_port)
+					ret |= DSA_ROUTE_SRC_PORT_BUSY;
+				if (r->to_local_p == to_port)
+					ret |= DSA_ROUTE_DEST_PORT_BUSY;
+			}
+		}
+	}
+
+	return ret;
+}
+
 static int dsa_switch_mirror_del(struct dsa_switch *ds,
 				 struct dsa_notifier_mirror_info *info)
 {
+	enum dsa_route_status status;
 	struct dsa_route *dr;
 	struct dsa_port *dp;
 	bool ingress;
@@ -162,9 +191,12 @@ static int dsa_switch_mirror_del(struct dsa_switch *ds,
 			ingress = info->mirror->ingress;
 			dp = dsa_to_port(ds, dr->to_local_p);
 			to_port = dp->index;
+			status = dsa_route_get_status(ds, info->mirror,
+						      dr->from_local_p,
+						      dr->to_local_p);
 
 			ds->ops->port_mirror_del(ds, dr->from_local_p,
-						 to_port, ingress);
+						 to_port, ingress, status);
 		}
 	}
 
-- 
2.11.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ