[<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