Bridge WAN and LAN and still see packets in the CPU until flowoffload

Hi,

my use-case is that I would like to use one of my OpenWRT devices as a 'inspection bridge', so it sits between my router and my lan and should just bridge between its wan and lan port while inspecting the packets in the CPU. I know this is not a normal OpenWRT use-case, but I really want to use one of my OpenWRT devices for this instead of another box with two LAN ports.

On 19.07 I could, using a device with a mt7530 switch, simply move the WAN port to br-lan and and bridge packets between WAN and LAN and still see all packets in the CPU. In the CPU I could then offload specific flows to hardware when I had seen enough.
I did the following:

uci set dhcp.lan.ignore=1
uci set dhcp.wan.ignore=1
uci set network.lan.proto=dhcp
uci set network.wan.ifname=none
uci set network.lan.ifname="eth0.1 eth0.2"

On 21.02 using the same device I can still bridge WAN and LAN but I never see packets in the CPU, they stay on the switch.. tcpdump -i br-lan show nothing

Does anyone have a clue how to make my use-case work in 21.02? I need 21.02 because HW offload doesn't work well in 19.07.

Thanks

But what "hardware offload" does is precisely to offload (part of) the traffic to the internal switch, so the CPU does not have to deal with it.

1 Like

Yes, but the problem is that I want to control when offload should happen. If I route the packets, I can per flow control what get offloaded and what doesn't, but in bridgemode it seems the switch always perform L2 offload based on mac learning so even if I wanted to send everything to iptables, I cannot.
In 19.07 I could send all traffic to iptables and then per flow control what and when to offload also in bridgemode.

Don't recall offhand, but maybe:

config bridge-vlan
	option local '0'

assuming DSA

Sadly no.
I assume that moving to DSA means that 'bridge hw offload' is enabled so it is doing MAC learning in HW, which is great, I just need to disable that because I need to do DPI on packets on LAN.
I tried to disable learning on the bridge ports, but was just given the "bridge flag offload is not supported".

Ok, I spent some more time on this and got it to work, but I had to change the kernel (mt7530.c and tag_mkt.c) to disable the bridge join/leave functions, disable learning and don't set the offload flag.
With this the ports stay independant even if I bridge them together. The bridge now receive every packet and br_netfilter works again and I can implement my bridge firewall. Once a flow is ESTABLISHED I can HW offload it... Perfect... I just wished there was a mode to disable the offload without this hack, but I will keep looking.

Hello @mlilja01 would you share your patch ?
thanks

Sure, the patch is below.. It's for 21.03, I have not yet moved to 22.03.

--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1288,6 +1288,11 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
+#if 1 // TMS CHANGE
+              /* Disable auto learning on the cpu port */
+                mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+#endif
+
 		if (dsa_is_cpu_port(ds, i))
 			mt7530_cpu_port_enable(priv, i);
 		else
@@ -1608,11 +1613,13 @@ static const struct dsa_switch_ops mt753
 	.port_enable		= mt7530_port_enable,
 	.port_disable		= mt7530_port_disable,
 	.port_stp_state_set	= mt7530_stp_state_set,
+#if 0 // TMS CHANGE
 	.port_bridge_join	= mt7530_port_bridge_join,
 	.port_bridge_leave	= mt7530_port_bridge_leave,
 	.port_fdb_add		= mt7530_port_fdb_add,
 	.port_fdb_del		= mt7530_port_fdb_del,
 	.port_fdb_dump		= mt7530_port_fdb_dump,
+#endif
 	.port_vlan_filtering	= mt7530_port_vlan_filtering,
 	.port_vlan_prepare	= mt7530_port_vlan_prepare,
 	.port_vlan_add		= mt7530_port_vlan_add,
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -104,10 +104,11 @@ static struct sk_buff *mtk_tag_rcv(struc
 	if (!skb->dev)
 		return NULL;
 
+#if 0 // TMS CHANGE
 	/* Only unicast or broadcast frames are offloaded */
 	if (likely(!is_multicast_skb))
 		skb->offload_fwd_mark = 1;
-
+#endif
 	return skb;
 }

Enjoy

1 Like

you are a lifesaver :slight_smile:
thanks alot