mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
98 lines
3.3 KiB
Diff
98 lines
3.3 KiB
Diff
From 04823fe9ff9c611478db9eb97281da93f4cb49d0 Mon Sep 17 00:00:00 2001
|
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
|
Date: Wed, 24 Apr 2024 22:41:04 +0200
|
|
Subject: [PATCH 18/50] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
|
|
ports on 6393X
|
|
|
|
For packets with a DA in the IEEE reserved L2 group range, originating
|
|
from a CPU, forward it as normal, rather than classifying it as
|
|
management.
|
|
|
|
Example use-case:
|
|
|
|
bridge (group_fwd_mask 0x4000)
|
|
/ | \
|
|
swp1 swp2 tap0
|
|
\ /
|
|
(mv88e6xxx)
|
|
|
|
We've created a bridge with a non-zero group_fwd_mask (allowing LLDP
|
|
in this example) containing a set of ports managed by mv88e6xxx and
|
|
some foreign interface (e.g. an L2 VPN tunnel).
|
|
|
|
Since an LLDP packet coming in to the bridge from the other side of
|
|
tap0 is eligable for tx forward offloading, a FORWARD frame destined
|
|
for swp1 and swp2 would be send to the conduit interface.
|
|
|
|
Before this change, due to rsvd2cpu being enabled on the CPU port, the
|
|
switch would try to trap it back to the CPU. Given that the CPU is
|
|
trusted, instead assume that it indeed meant for the packet to be
|
|
forwarded like any other.
|
|
---
|
|
drivers/net/dsa/mv88e6xxx/port.c | 31 +++++++++++++++++++++++++------
|
|
1 file changed, 25 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
|
|
index 66b1b7277281..df19dfa5cc3d 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/port.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/port.c
|
|
@@ -1434,6 +1434,23 @@ static int mv88e6393x_port_policy_write_all(struct mv88e6xxx_chip *chip,
|
|
return 0;
|
|
}
|
|
|
|
+static int mv88e6393x_port_policy_write_user(struct mv88e6xxx_chip *chip,
|
|
+ u16 pointer, u8 data)
|
|
+{
|
|
+ int err, port;
|
|
+
|
|
+ for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
|
|
+ if (!dsa_is_user_port(chip->ds, port))
|
|
+ continue;
|
|
+
|
|
+ err = mv88e6393x_port_policy_write(chip, port, pointer, data);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
|
|
enum mv88e6xxx_egress_direction direction,
|
|
int port)
|
|
@@ -1475,26 +1492,28 @@ int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
|
|
int err;
|
|
|
|
/* Consider the frames with reserved multicast destination
|
|
- * addresses matching 01:80:c2:00:00:00 and
|
|
- * 01:80:c2:00:00:02 as MGMT.
|
|
+ * addresses matching 01:80:c2:00:00:00 and 01:80:c2:00:00:02
|
|
+ * as MGMT when received on user ports. Forward as normal on
|
|
+ * CPU/DSA ports, to support bridges with non-zero
|
|
+ * group_fwd_masks.
|
|
*/
|
|
ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XLO;
|
|
- err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
|
|
+ err = mv88e6393x_port_policy_write_user(chip, ptr, 0xff);
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XHI;
|
|
- err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
|
|
+ err = mv88e6393x_port_policy_write_user(chip, ptr, 0xff);
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XLO;
|
|
- err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
|
|
+ err = mv88e6393x_port_policy_write_user(chip, ptr, 0xff);
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XHI;
|
|
- err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
|
|
+ err = mv88e6393x_port_policy_write_user(chip, ptr, 0xff);
|
|
if (err)
|
|
return err;
|
|
|