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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cacf47599957ac92edddfa372bac5ac9890e4e85.1704449760.git.ante.knezic@helmholz.de>
Date: Fri, 5 Jan 2024 11:46:19 +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 6/6] net: dsa: mv88e6xxx add cross-chip mirroring

modify mv88e6xxx port mirroring to support cross-chip mirroring.
Remove mirror_ingress and mirror_egress as they are no longer
needed.
Do not allow setting dsa ports as mirror source port as
recommended by the Switch Functional Specification.

Signed-off-by: Ante Knezic <ante.knezic@...mholz.de>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 77 +++++++++++++++++++++++++---------------
 drivers/net/dsa/mv88e6xxx/chip.h |  2 --
 drivers/net/dsa/mv88e6xxx/port.c |  5 ---
 3 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ce3a5d61edb4..fab92c3cb511 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3568,6 +3568,28 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
 	return mv88e6xxx_g1_stats_clear(chip);
 }
 
+static int mv88e6xxx_mirror_setup(struct mv88e6xxx_chip *chip)
+{
+	int err, port, i;
+	const enum mv88e6xxx_egress_direction direction[] = {
+		MV88E6XXX_EGRESS_DIR_INGRESS, MV88E6XXX_EGRESS_DIR_EGRESS};
+
+	for (i = 0; i < ARRAY_SIZE(direction); i++) {
+		err = mv88e6xxx_set_egress_port(chip, i,
+						MV88E6XXX_EGRESS_DEST_DISABLE);
+		if (err)
+			return err;
+
+		for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
+			err = mv88e6xxx_port_set_mirror(chip, port, i, false);
+			if (err)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
 /* Check if the errata has already been applied. */
 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
 {
@@ -3966,6 +3988,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	err = mv88e6xxx_mirror_setup(chip);
+	if (err)
+		goto unlock;
+
 unlock:
 	mv88e6xxx_reg_unlock(chip);
 
@@ -6488,31 +6514,26 @@ static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int from_port,
 						MV88E6XXX_EGRESS_DIR_INGRESS :
 						MV88E6XXX_EGRESS_DIR_EGRESS;
 	struct mv88e6xxx_chip *chip = ds->priv;
-	bool other_mirrors = false;
-	int i;
+	int *dest_port;
 	int err;
 
 	mutex_lock(&chip->reg_lock);
-	if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
-	    to_port) {
-		for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
-			other_mirrors |= ingress ?
-					 chip->ports[i].mirror_ingress :
-					 chip->ports[i].mirror_egress;
-
-		/* Can't change egress port when other mirror is active */
-		if (other_mirrors) {
-			err = -EBUSY;
-			goto out;
-		}
+	dest_port = ingress ? &chip->ingress_dest_port : &chip->egress_dest_port;
 
-		err = mv88e6xxx_set_egress_port(chip, direction,
-						to_port);
-		if (err)
-			goto out;
+	/* Can't change egress port when mirroring is active */
+	if (*dest_port != MV88E6XXX_EGRESS_DEST_DISABLE &&
+	    *dest_port != to_port) {
+		err = -EBUSY;
+		goto out;
 	}
 
-	err = mv88e6xxx_port_set_mirror(chip, from_port, direction, true);
+	err = mv88e6xxx_set_egress_port(chip, direction, to_port);
+	if (err)
+		goto out;
+
+	if (dsa_port_is_user(dsa_to_port(ds, from_port)))
+		err = mv88e6xxx_port_set_mirror(chip, from_port, direction, true);
+
 out:
 	mutex_unlock(&chip->reg_lock);
 
@@ -6527,20 +6548,18 @@ static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int from_port,
 						MV88E6XXX_EGRESS_DIR_INGRESS :
 						MV88E6XXX_EGRESS_DIR_EGRESS;
 	struct mv88e6xxx_chip *chip = ds->priv;
-	bool other_mirrors = false;
-	int i;
+	int *dest_port;
 
 	mutex_lock(&chip->reg_lock);
-	if (mv88e6xxx_port_set_mirror(chip, from_port, direction, false))
-		dev_err(ds->dev, "p%d: failed to disable mirroring\n", from_port);
+	dest_port = ingress ? &chip->ingress_dest_port : &chip->egress_dest_port;
 
-	for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
-		other_mirrors |= ingress ?
-				 chip->ports[i].mirror_ingress :
-				 chip->ports[i].mirror_egress;
+	if (!(route_status & DSA_ROUTE_SRC_PORT_BUSY)) {
+		if (mv88e6xxx_port_set_mirror(chip, from_port, direction, false))
+			dev_err(ds->dev, "p%d: failed to disable mirroring\n", from_port);
+	}
 
-	/* Reset egress port when no other mirror is active */
-	if (!other_mirrors) {
+	if (!(route_status & DSA_ROUTE_DEST_PORT_BUSY) &&
+	    *dest_port == to_port) {
 		if (mv88e6xxx_set_egress_port(chip, direction,
 					      MV88E6XXX_EGRESS_DEST_DISABLE))
 			dev_err(ds->dev, "failed to set egress port\n");
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index a73da4e965ec..0000a7aa3fbc 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -284,8 +284,6 @@ struct mv88e6xxx_port {
 	u64 vtu_miss_violation;
 	phy_interface_t interface;
 	u8 cmode;
-	bool mirror_ingress;
-	bool mirror_egress;
 	struct devlink_region *region;
 	void *pcs_private;
 
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 5394a8cf7bf1..777515ee722b 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -1183,7 +1183,6 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
 			      enum mv88e6xxx_egress_direction direction,
 			      bool mirror)
 {
-	bool *mirror_port;
 	u16 reg;
 	u16 bit;
 	int err;
@@ -1195,11 +1194,9 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
 	switch (direction) {
 	case MV88E6XXX_EGRESS_DIR_INGRESS:
 		bit = MV88E6XXX_PORT_CTL2_INGRESS_MONITOR;
-		mirror_port = &chip->ports[port].mirror_ingress;
 		break;
 	case MV88E6XXX_EGRESS_DIR_EGRESS:
 		bit = MV88E6XXX_PORT_CTL2_EGRESS_MONITOR;
-		mirror_port = &chip->ports[port].mirror_egress;
 		break;
 	default:
 		return -EINVAL;
@@ -1210,8 +1207,6 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
 		reg |= bit;
 
 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
-	if (!err)
-		*mirror_port = mirror;
 
 	return err;
 }
-- 
2.11.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ