From c09cb2f80f4361b692809e1bb3e7fec65a6b76a3 Mon Sep 17 00:00:00 2001 From: Gennaro Cimmino Date: Fri, 9 Oct 2026 22:25:49 +0200 Subject: [PATCH] realtek: dsa: rtl839x: add a port to its own isolation mask The RTL839x applies a port's isolation mask to every frame that came in on it, routed ones included. The driver leaves the port out of its own mask, so a route offloaded through a gateway behind the port a packet came in on, such as routing between two VLANs of one trunk, drops everything: the kernel shows the route as offloaded, and the drop counter PORT_ISOLATION counts each packet. Keep the port in its own mask, as the GPL SDK does at init (_dal_cypress_port_init_config() sets every port's mask to all ports). A broadcast is still not sent back out of the port it came in on. Only RTL839x changes; the other families keep their masks as they are. Tested on an HPE 1920-48G (RTL8393), with 10.99.1.0/24 routed from VLAN 7 to a gateway on VLAN 3, both behind lan48. On main, 0/8 echo requests reached the gateway, even with IPv4 forwarding on in the kernel. With this change and forwarding off, so that only the hardware path delivers, 8/8 arrived, TTL 63, from the switch MAC. Routing to a gateway behind lan47 still delivers 8/8. Two bursts of 50 broadcasts entering lan48 added nothing to its tx_BroadcastPkts, while the same entering lan47 added 50 and 53. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Gennaro Cimmino Link: https://github.com/openwrt/openwrt/pull/25764 Signed-off-by: Markus Stockhausen --- .../realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c index 82b3be2bb4a..73a356b8d49 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c @@ -97,7 +97,12 @@ static inline int rtl839x_mac_port_ctrl(int p) static void rtl839x_traffic_set(int source, u64 dest_matrix) { - rtl839x_set_port_reg_be(dest_matrix, rtl839x_port_iso_ctrl(source)); + /* The isolation mask also applies to frames routed in hardware, which + * may have to leave through the port they came in on. The SDK keeps a + * port in its own mask; a bridged frame is still not sent back out of + * its ingress port. + */ + rtl839x_set_port_reg_be(dest_matrix | BIT_ULL(source), rtl839x_port_iso_ctrl(source)); } static void rtl839x_traffic_enable(int source, int dest)