Untagged vlan ports not being routed to vlan interface

Hi, I am debugging an issue which has gone beyond my experience level, any help appreciated, thanks.

tl;dr;

Look at this line from an iptables trace and note the interface vlan interface br-lan.99 source

May 10 18:39:54 turris kernel: [88215.170984] TRACE: raw:PREROUTING:rule:6 IN=br-lan.99 OUT= MAC=<mac> SRC=192.168.1.2 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=51679 DF PROTO=TCP SPT=50868 DPT=4567 SEQ=2655642190 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080ABD91B5470000000001030307) 

Here's another one from a different client in the same subnet which is coming in via the br-lan bridge itself not the vlan interface.

May 10 18:38:49 turris kernel: [88150.006717] TRACE: raw:PREROUTING:rule:6 IN=br-lan OUT= PHYSIN=lan2 MAC=<mac> SRC=192.168.1.138 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=5988 DF PROTO=TCP SPT=49846 DPT=4567 SEQ=1976936805 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080AFB5B50DA0000000001030305)

I'm trying to figure out why this is happening.

Setup

I have 2 DSA openwrt devices.

Device 1 is a router
Device 2 is a dumb AP

They are linked with a VLAN trunk.

Server A is connected to an untagged port on Device 2.

Client A is connected to Device 1 untagged
Client B is connected to Device 2 untagged.

The untagged vlan is 99, this is my default lan subnet, so for the purposes of this post everything is using the same subnet.

I am running an http service on Server A (192.168.1.35) on port 4567. I'm using a basic echo server for testing purposes. I set up a port forward on Device 1 (192.168.1.1) 4567->192.168.1.35.


           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β”‚            β”‚                                       β”‚              β”‚
           β”‚ client B   β”‚                                       β”‚   client A   β”‚
           β”‚            β”‚                                       β”‚              β”‚
           β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                                       β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                β”‚                                                      β”‚
                β”‚                                                      β”‚
                β”‚                                                      β”‚
                β”‚                                                      β”‚
                β”‚                                                      β”‚
                β”‚                                                      β”‚
            β”Œβ”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                      β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚             β”‚             VLAN Trunk               β”‚              β”‚
            β”‚  AP (2)     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Router (1)   │◄──────────port 4567
            β”‚             β”‚                                      β”‚              β”‚
            β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                β”‚
                β”‚
                β”‚
                β”‚
                β”‚port 4567
            β”Œβ”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
            β”‚          β”‚
            β”‚          β”‚
            β”‚ server A β”‚
            β”‚          β”‚
            β”‚          β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The problem

I curl the echo service from client B using <wan ip>:4567. This works.
I curl the echo service from client A using <wan ip>:4567. This generates a connection refused error.

I want to be able to access the service on server A from a client connected to Device 1 using my public IP. This is simply so that I can use one url no matter if I am inside my house or out.

Debugging

I assumed the issue was firewall related so I added a TRACE rule

iptables -t raw -I PREROUTING -p tcp --destination 0.0.0.0/0 --dport 4567 -j TRACE

The difference between the curl from client A and B is interesting. This is what happens on the client that works:

May 10 18:39:54 turris kernel: [88215.170984] TRACE: raw:PREROUTING:rule:6 IN=br-lan.99 OUT= MAC=<mac> SRC=192.168.1.2 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=51679 DF PROTO=TCP SPT=50868 DPT=4567 SEQ=2655642190 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080ABD91B5470000000001030307) 
#... 4 unrelated rules removed
May 10 18:39:54 turris kernel: [88215.308981] TRACE: nat:PREROUTING:rule:3 IN=br-lan.99 OUT= MAC=<mac> SRC=192.168.1.2 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=51679 DF PROTO=TCP SPT=50868 DPT=4567 SEQ=2655642190 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080ABD91B5470000000001030307) 
#...
May 10 18:39:54 turris kernel: [88215.393192] TRACE: nat:zone_lan_prerouting:rule:10 IN=br-lan.99 OUT= MAC=<mac> SRC=192.168.1.2 DST=86.20.35.0 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=51679 DF PROTO=TCP SPT=50868 DPT=4567 SEQ=2655642190 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080ABD91B5470000000001030307) 
#num  target     prot opt source               destination
#10   DNAT       tcp  --  192.168.1.0/24       <public ip>           tcp dpt:4567 /* !fw3: WHOAMI TEST (reflection) */ to:192.168.1.35:4567
May 10 18:39:54 turris kernel: [88215.421654] TRACE: mangle:FORWARD:rule:3 IN=br-lan.99 OUT=br-lan.99 MAC=<mac> SRC=192.168.1.2 DST=192.168.1.35 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=51679 DF PROTO=TCP SPT=50868 DPT=4567 SEQ=2655642190 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080ABD91B5470000000001030307) 

And this is what happens for the client which disconnects

May 10 18:38:49 turris kernel: [88150.006717] TRACE: raw:PREROUTING:rule:6 IN=br-lan OUT= PHYSIN=lan2 MAC=<mac> SRC=192.168.1.138 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=5988 DF PROTO=TCP SPT=49846 DPT=4567 SEQ=1976936805 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080AFB5B50DA0000000001030305) 
#...same 4 unrelated rules
May 10 18:38:49 turris kernel: [88150.149078] TRACE: nat:PREROUTING:rule:8 IN=br-lan OUT= PHYSIN=lan2 MAC=<mac> SRC=192.168.1.138 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=5988 DF PROTO=TCP SPT=49846 DPT=4567 SEQ=1976936805 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080AFB5B50DA0000000001030305) 
#rule 8 is just the policy rule (ACCEPT) so no NAT happens in this case
May 10 18:38:49 turris kernel: [88150.177530] TRACE: filter:INPUT:rule:2 IN=br-lan.99 OUT= MAC=<mac> SRC=192.168.1.138 DST=<public ip> LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=5988 DF PROTO=TCP SPT=49846 DPT=4567 SEQ=1976936805 ACK=0 WINDOW=64240 RES=0x00 SYN URGP=0 OPT (020405B40402080AFB5B50DA0000000001030305) 

So here are the things I don't understand:

  1. Why does the input arrive on the lan bridge br-lan for a client connected directly to the router? If the port is marked as untagged for br-lan.99 I would expect the packet to arrive on the vlan interface before it gets to iptables.
  2. If this is working as intended and I have simply misunderstood how VLANs work then why don't I get a NAT in the second case?

I feel I have debugged this setup as far as I can, I can't reconcile my understanding of how I think this works with what I'm actually seing, any help appreciated.

This has nothing to do with VLANs.

The port forward you created here does nothing because the traffic is on the same L2 (switched) network and thus never reaches the firewall (since it is not routed at L3).

What you probably need to do is related to NAT reflection:

1 Like

Thanks for the suggestions psherman, I will read up on NAT reflection.

The port forward you created here does nothing because the traffic is on the same L2 (switched) network and thus never reaches the firewall (since it is not routed at L3).

This is interesting, I am definitely seeing an iptables trace when I hit this port so it looks to me that something is happening at L3 level. If I hit the server IP directly then everything happens in L2 as you say, there is no trace.

Maybe I misunderstood where your port forward is happening... is it on the main router, or somewhere else? Maybe my comment was on a bad assumption... I'd have to see your config to know for sure.

I think that the issue you're describing is still related to nat reflection, though.

The port forward is on the main router (1).

Here's another way to show the problem of the missing nat:

 sudo iptables -t nat  -vL  --line-numbers -n                                                                                                                                                                             
Chain PREROUTING (policy ACCEPT 106K packets, 12M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1    44416 2535K DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
2     109K   12M prerouting_rule  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* !fw3: Custom prerouting rule chain */
3    73830 9756K zone_lan_prerouting  all  --  br-lan.99 *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */
4    26739 1239K zone_wan_prerouting  all  --  eth2   *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */
5     1739  146K zone_tr_guest_prerouting  all  --  br-lan.3 *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */
6        0     0 zone_docker_prerouting  all  --  docker0 *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */
7        6  2016 zone_IoT_prerouting  all  --  br-lan.4 *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */

...

Chain zone_lan_prerouting (1 references)
num   pkts bytes target     prot opt in     out     source               destination
...
10       0     0 DNAT       tcp  --  *      *       192.168.1.0/24       <public ip>           tcp dpt:4567 /* !fw3: WHOAMI TEST (reflection) */ to:192.168.1.35:4567
11       0     0 DNAT       udp  --  *      *       192.168.1.0/24       <public ip>           udp dpt:4567 /* !fw3: WHOAMI TEST (reflection) */ to:192.168.1.35:4567
...

So rule 3 is the desired NAT rule that all lan traffic (br-lan.99) should pass through. The port forwarding I set up in luci is expressed as a DNAT rule in zone_lan_prerouting. So going back to the traces posted above if a packet comes in on the br-lan interface instead of br-lan.99 then rule 3 is not applied therefore no nat target is hit and the port forward is never applied.

So rephrasing my original question, why am I getting packets on the br-lan device at all?

Here's the relevant parts of /etc/config/network that shows the bridge and vlan 99 setup

config interface 'lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option device 'br-lan.99'

config device 'br_lan'
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan0'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'

config bridge-vlan
        option device 'br-lan'
        option vlan '99'
        list ports 'lan0:t'
        list ports 'lan1:u*'
        list ports 'lan2:u*'
        list ports 'lan3:u*'
        list ports 'lan4:u*'

I'm investigating adding an explicit nat rule to route packets on br-lan through the same logic as br-lan.99 but I feel like I shouldn't have to do this. As i understand vlans (which is clearly not very well) untagged traffic on lan ports 1-4 should end up in vlan 99 anyway, and as that is happening at layer 2 I shouldn't be seeing traffic on br-lan at iptables layer 3?

Thanks for reading my ramblings.

OK I have a workaround

I added a new interface in addition to the lan interface above

config interface 'LANU'
	option proto 'static'
	option device 'br-lan'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'

And then I added this interface to the lan firewall zone. This added an extra rule to the nat table to catch the packets coming in on the bridge

sudo iptables -t nat  -vL  --line-numbers -n | grep zone_lan_prerouting                                    ─╯
3     1625  114K zone_lan_prerouting  all  --  br-lan *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */
4      157 22655 zone_lan_prerouting  all  --  br-lan.99 *       0.0.0.0/0            0.0.0.0/0            /* !fw3 */

So now I have the correct nat happening and all is well.

This is pretty unsatisyfing though, I really feel like the traffic coming in on lan ports 1-4 should be assigned to br-lan.99 not br-lan, if anyone can shed light on why I'm wrong I'd appreciate it.

For now I guess a workaround is better than nothing. Thanks.

Please copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall
sudo cat /etc/config/network                                                                               ─╯

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'aaaa:bbbb:cccc::/48'

config interface 'lan'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option device 'br-lan.99'

config interface 'wan'
	option device 'eth2'
	option proto 'dhcp'
	option ipv6 '1'

config interface 'guest_turris'
	option proto 'static'
	option ipaddr '10.111.222.1'
	option netmask '255.255.255.0'
	option ip6assign '64'
	option enabled '1'
	option device 'br-lan.3'

config device 'br_guest_turris'
	option name 'br-guest-turris'
	option type 'bridge'
	option bridge_empty '1'

config device 'br_lan'
	option name 'br-lan'
	option type 'bridge'
	list ports 'lan0'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'lan4'

config interface 'wan6'
	option device '@wan'
	option proto 'dhcpv6'

config device 'dev_wan'
	option name 'eth2'

config bridge-vlan
	option device 'br-lan'
	option vlan '4'
	list ports 'lan0:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '99'
	list ports 'lan0:t'
	list ports 'lan1:u*'
	list ports 'lan2:u*'
	list ports 'lan3:u*'
	list ports 'lan4:u*'

config bridge-vlan
	option device 'br-lan'
	option vlan '3'
	list ports 'lan0:t'

config interface 'docker'
	option device 'docker0'
	option proto 'none'
	option auto '0'

config device
	option type 'bridge'
	option name 'docker0'

config interface 'IoT'
	option proto 'static'
	option ipaddr '10.20.30.40'
	option netmask '255.255.255.0'
	option device 'br-lan.4'

sudo cat /etc/config/firewall

config defaults
	option input 'ACCEPT'
	option output 'ACCEPT'
	option synflood_protect '1'
	option forward 'REJECT'

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'lan'

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	list network 'wan6'

config forwarding
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config rule
	option name 'Support-UDP-Traceroute'
	option src 'wan'
	option dest_port '33434:33689'
	option proto 'udp'
	option family 'ipv4'
	option target 'REJECT'
	option enabled '0'

config zone 'guest_turris'
	option name 'tr_guest'
	option input 'REJECT'
	option forward 'REJECT'
	option output 'ACCEPT'
	option enabled '1'
	list network 'guest_turris'

config forwarding 'guest_turris_forward_wan'
	option name 'guest to wan forward'
	option src 'tr_guest'
	option dest 'wan'
	option enabled '1'

config rule 'guest_turris_dns_rule'
	option name 'guest dns rule'
	option src 'tr_guest'
	option proto 'tcpudp'
	option dest_port '53'
	option target 'ACCEPT'

config rule 'guest_turris_dhcp_rule'
	option name 'guest dhcp rule'
	option src 'tr_guest'
	option proto 'udp'
	option src_port '67-68'
	option dest_port '67-68'
	option target 'ACCEPT'

config rule 'guest_turris_Allow_DHCPv6'
	option src 'tr_guest'
	option proto 'udp'
	option src_ip 'fe80::/10'
	option src_port '546-547'
	option dest_ip 'fe80::/10'
	option dest_port '546-547'
	option family 'ipv6'
	option target 'ACCEPT'

config rule 'guest_turris_Allow_MLD'
	option src 'tr_guest'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	option family 'ipv6'
	option target 'ACCEPT'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'

config rule 'guest_turris_Allow_ICMPv6_Input'
	option src 'tr_guest'
	option proto 'icmp'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'

config include
	option path '/etc/firewall.user'

config include 'bcp38'
	option type 'script'
	option path '/usr/lib/bcp38/run.sh'
	option family 'IPv4'
	option reload '1'

config zone 'docker'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option name 'docker'
	list network 'docker'

config zone
	option input 'ACCEPT'
	option forward 'REJECT'
	option name 'IoT'
	option output 'ACCEPT'
	list network 'IoT'

config forwarding
	option dest 'IoT'
	option src 'lan'

config forwarding
	option dest 'lan'
	option src 'IoT'

config zone 'turris_vpn_client'
	option name 'tr_vpn_cl'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'

config forwarding 'turris_vpn_client_forward'
	option src 'lan'
	option dest 'tr_vpn_cl'

config redirect
	option dest_port '4567'
	option src 'wan'
	option name 'WHOAMI TEST'
	option src_dport '4567'
	option dest 'lan'
	option target 'DNAT'
	option dest_ip '192.168.1.35'

config rule
	option dest 'lan'
	option src 'lan'
	option target 'ACCEPT'
	option dest_port '4567'


sudo cat /etc/config/dhcp                                                                                  ─╯

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
	option localservice '1'
	option ednspacket_max '1232'
	option port '0'

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv4 'server'
	option dhcpv6 'server'
	option ra 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	list dhcp_option '6,192.168.1.1'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'

config host
	option mac 'D8:5E:D3:8A:9E:88'
	option name 'host1'
	option dns '1'
	option ip '192.168.1.35'

config host
	option mac 'F2:C6:47:2B:2A:3C'
	option name 'host2'
	option dns '1'
	option ip '192.168.1.30'

config host
	option mac 'D0:50:99:33:F5:8D'
	option name 'host3'
	option dns '1'
	option ip '192.168.1.2'

config dhcp 'guest_turris'
	option interface 'guest_turris'
	option start '100'
	option limit '150'
	option leasetime '3600'
	option dhcpv6 'server'
	option ra 'server'
	list dhcp_option '6,10.111.222.1'

config dhcp 'IoT'
	option start '100'
	option leasetime '12h'
	option limit '150'
	option interface 'IoT'
	list ra_flags 'none'

sudo cat /etc/config/wireless

config wifi-device 'radio0'
	option type 'mac80211'
	option path 'soc/soc:pcie/pci0000:00/0000:00:02.0/0000:02:00.0'
	option channel '36'
	option band '5g'
	option htmode 'HE80'
	option country 'GB'
	option cell_density '0'

config wifi-iface 'default_radio0'
	option device 'radio0'
	option network 'lan'
	option mode 'ap'
	option ssid 'ssid1'
	option wpa_group_rekey '86400'
	option key 'redacted'
	option encryption 'psk2'
	option ft_over_ds '0'
	option ft_psk_generate_local '1'
	option ieee80211r '1'

config wifi-device 'radio1'
	option type 'mac80211'
	option path 'soc/soc:pcie/pci0000:00/0000:00:01.0/0000:01:00.0'
	option band '2g'
	option htmode 'HT20'
	option country 'GB'
	option cell_density '0'
	option channel '2'

config wifi-iface 'default_radio1'
	option device 'radio1'
	option network 'lan'
	option mode 'ap'
	option ssid 'ssid1'
	option wpa_group_rekey '86400'
	option key 'redacted'
	option encryption 'psk2'
	option ft_over_ds '0'
	option ft_psk_generate_local '1'
	option ieee80211r '1'

config wifi-iface 'guest_iface_0'
	option device 'radio0'
	option mode 'ap'
	option ssid 'ssid2'
	option network 'guest_turris'
	option wpa_group_rekey '86400'
	option key 'redacted'
	option ifname 'guest_turris_0'
	option encryption 'psk2'
	option ft_over_ds '0'
	option ft_psk_generate_local '1'
	option ieee80211r '1'

config wifi-iface 'guest_iface_1'
	option device 'radio1'
	option mode 'ap'
	option ssid 'ssid2'
	option network 'guest_turris'
	option wpa_group_rekey '86400'
	option key 'redacted'
	option ifname 'guest_turris_1'
	option encryption 'psk2'
	option ft_over_ds '0'
	option ft_psk_generate_local '1'
	option ieee80211r '1'

config wifi-iface 'wifinet4'
	option ssid 'ssid3'
	option encryption 'psk2'
	option device 'radio1'
	option mode 'ap'
	option network 'IoT'
	option key 'redacted'

I've reworked the workaround above so instead of creating a dummy interface and assigning that in the firewall rules I just use a single extra iptables rule in /etc/firewall.user. This just applies exactly the same nat logic to packets on br-lan as happens on br-lan.99. this seems to work so far but I'm sure it'll break something important.

sudo cat /etc/firewall.user                                                                                ─╯

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.

iptables -t nat -A PREROUTING -i br-lan -m comment --comment "Fudge to work around switch ports not being vlanned for some reason" -j zone_lan_prerouting
1 Like