VLAN setup with managed switch running OpenWrt 22.03

Hi, I'm trying to get VPN split tunneling working with a VLAN, where untagged traffic on the network goes through the VPN and traffic in the VLAN is unencrypted with a separate local dns server for each interface.

I have a Zyxel GS1900-8 running the openwrt 22.03.3 as a managed switch with the following network config:

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 'PREFIX::/48'

config device 'switch'
	option name 'switch'
	option type 'bridge'
	option macaddr '5c:6a:80:ff:d2:97'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'lan4'
	list ports 'lan5'
	list ports 'lan6'
	list ports 'lan7'
	list ports 'lan8'
	option bridge_empty '1'

config bridge-vlan 'lan_vlan'
	option device 'switch'
	option vlan '1'
	list ports 'lan1:u*'
	list ports 'lan2:u*'
	list ports 'lan3:u*'

config device
	option name 'switch.1'
	option macaddr 'MACADDR'

config interface 'lan'
	option device 'switch.1'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'
	option ip6assign '60'

config device
	option name 'lan1'

config device
	option name 'lan4'

config bridge-vlan
	option device 'switch'
	option vlan '100'
	list ports 'lan4:t*'

This is the config for the router, which is a Raspberry Pi 4B running openwrt 22.03.3:

#
# /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 'PREFIX::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '192.168.99.1'
	option ip6assign '64'
	option ip6hint 'AA'
	list ip6class 'local'

config interface 'wan'
	option device 'eth1'
	option proto 'static'
	option netmask '255.255.255.0'
	option gateway '192.168.1.254'
	option ipaddr '192.168.1.100'
	list dns '9.9.9.9'
	list dns '149.112.112.112'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'
	option peerdns '0'
	list dns '2606:4700:4700::64'
	list dns '2606:4700:4700::6400'

config interface 'wg'
	option proto 'wireguard'
	option private_key 'PRIVATEKEY'
	list addresses 'ADDRESS/32'
	list addresses 'ADDRESS/128'
	option force_link '1'

config wireguard_wg
	option description 'wg-endpoint'
	option public_key 'KEY'
	option route_allowed_ips '1'
	option endpoint_port '51820'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option endpoint_host 'HOST'

config route6
	option target '::/0'
	option interface 'wg'

config interface 'vlan'
	option proto 'static'
	option type 'bridge'
	option ipaddr '194.168.100.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option device 'eth0.100'

#
# /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 localservice '1'
	option ednspacket_max '1232'
	option confdir '/tmp/dnsmasq.d'
	option cachesize '10000'
	option strictorder '1'
	option quietdhcp '1'
	option port '54'
	list server '127.0.0.1'
	list server '::1'
	option noresolv '1'

config dnsmasq 'vlan'
	list interface 'vlan'
	list notinterface 'loopback'
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/local/'
	option domain 'local'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp-vlan.leases'
	option localservice '1'
	option ednspacket_max '1232'
	option confdir '/tmp/dnsmasq-vlan.d'
	option cachesize '10000'
	option strictorder '1'
	option quietdhcp '1'
	option port '53'
	list server '127.0.0.1'
	list server '::1'
	option noresolv '1'
	option nonwildcard '1'

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'
	option force '1'
	list dhcp_option '6,192.168.99.1'
	option ra_default '1'

config dhcp 'vlan'
	option interface 'vlan'
	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'
	option force '1'
	list dhcp_option '6,192.168.100.1'
	option ra_default '1'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'
	option start '100'
	option limit '150'
	option leasetime '12h'

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

#
# /etc/config/firewall
#

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

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

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

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

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 'vlan'
	option proto 'esp'
	option target 'ACCEPT'

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

config zone
	option name 'wgwan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option masq6 '1'
	option masq6_privacy '1'
	option mtu_fix '1'
	list network 'wg'

config forwarding
	option src 'lan'
	option dest 'wgwan'

config forwarding
	option src 'vlan'
	option dest 'wan'

I'm also running adguardhome for DNS, which is why dnsmasq is running on port 54 on the lan interface.

Eventually I'd like to also add another VLAN to replace the WAN port on the router, which is currently a USB ethernet adapter. Everything is working as-is for untagged traffic, but when I plug an ethernet cable into port 4 I can’t get an IP through DHCP or any connection if assigning one manually. I don't see any errors in the log but RX always shows 0 packets for the interface in the router.

I've messed with it for a while but am not sure how to troubleshoot, any advice?

I would really advise against trying to perfrom any routing on your switch. The switch hardware is designed for switching only... routing will be very very slow, and wireguard even slower.

Do you have a regular router (including an all-in-one consumer wifi router) that can run OpenWrt... that is how you should be doing this.

1 Like

That's all it's doing, I posted the full config above. I'm using a Raspberry Pi 4B as a router, and the switch is just supposed to add a tagged vlan 100 on port 4 to split the traffic.

Edit: clarified original post

Ok... perfect. Sorry if I misunderstood.

VLAN 100 only appears on a single port on the switch right now. What is the physical uplink port (i.e. what port on the switch connects to the Pi router)?

And what is downstream of the switch on port 4? Is it a computer? another managed switch? an AP?

No problem. I'm pretty new to openwrt and this level of networking so please let me know if I'm doing something wrong.

VLAN 100 only appears on a single port on the switch right now. What is the physical uplink port (i.e. what port on the switch connects to the Pi router)?

The physical uplink port I'm using is port 2, but it seems to work when connected to any untagged port. The Pi router is connected back to the switch via ETH0 (the built-in port), and to the WAN via ETH1 (the USB ethernet adapter).

And what is downstream of the switch on port 4? Is it a computer? another managed switch? an AP?

Right now just my computer to test it out, but once I get a proof of concept working I'd like to add devices to it that should bypass the VPN (e.g. gaming consoles, media players, etc.).

For your main network, yes, any untagged port will work. But, you need to tell the switch to expect VLAN100 tagged on the relevant port that connects to the router.

Your computer is not likely VLAN aware, or at least not by default. So it must be untagged on the corresponding port (i.e. port 4, if that's where the computer is connecting).

This will require policy based routing. But that will be another thing. Let's just worry about getting the network functioning in general.

delete these to device declarations.

Now, edit the vlan 100 definition so that it looks like this:

config bridge-vlan
	option device 'switch'
	option vlan '100'
	list ports 'lan2:t'
	list ports 'lan4:u*'

Try that... if it doesn't work, keep reading

You might possibly need to add a network interface (unmanged) to this...

config interface 'vlan100'
	option device 'switch.100'
	option proto 'none'

Ok, so that successfully assigns an IP to my computer via DHCP (which is progress!) both with and without the interface in the footer, but I can't connect to any servers aside from my router which I can access on either interface.

$ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
^C
--- 1.1.1.1 ping statistics ---
4 packets transmitted, 0 packets received, 100.0% packet loss
$ ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1): 56 data bytes
Request timeout for icmp_seq 0
$ ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1): 56 data bytes
64 bytes from 192.168.100.1: icmp_seq=0 ttl=64 time=2.088 ms
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=0.848 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.702 ms
--- 192.168.100.1 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.702/1.213/2.088/0.622 ms
$ ping 192.168.99.1
PING 192.168.99.1 (192.168.99.1): 56 data bytes
64 bytes from 192.168.99.1: icmp_seq=0 ttl=64 time=2.039 ms
64 bytes from 192.168.99.1: icmp_seq=1 ttl=64 time=0.809 ms
64 bytes from 192.168.99.1: icmp_seq=2 ttl=64 time=0.771 ms
--- 192.168.99.1 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.771/1.206/2.039/0.589 ms

Also just realized there was a typo in the vlan interface under the router network config. I wrote option ipaddr '194.168.100.1', but it should be 192.168.100.1. That didn't seem to fix the issue though.

On the pi in the /etc/config/network file, remove option type 'bridge' from the vlan network interface. obviously you also said that you found and corrected the typo here so that the address is 192.168.100.1

config interface 'vlan'
	option proto 'static'
	option type 'bridge'
	option ipaddr '194.168.100.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option device 'eth0.100'

Restart the pi and then test again.

Same issue, IP is assigned via DHCP but can't connect to outbound servers. Also, there doesn't seem to be an IPv6 address assigned, even though the range on the Pi's VLAN interface in the web portal looks correct and consistent with WAN6.

let's the latest complete files from the Pi...

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/dhcp
cat /etc/config/firewall

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'
	# d prefix required for Wireguard NAT66
	# See https://openwrt.org/docs/guide-user/network/ipv6/ipv6_extras#using_ipv6_by_default
	option ula_prefix 'dd6c:3cb8:420f::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '192.168.99.1'
	option ip6assign '64'
	option ip6hint 'AA'
	list ip6class 'local'

config interface 'wan'
	option device 'eth1'
	option proto 'static'
	option netmask '255.255.255.0'
	option gateway '192.168.1.254'
	option ipaddr '192.168.1.100'
	list dns '9.9.9.9'
	list dns '149.112.112.112'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'
	option peerdns '0'
	list dns '2606:4700:4700::64'
	list dns '2606:4700:4700::6400'

config interface 'wg'
	option proto 'wireguard'
	option private_key 'KEY'
	list addresses 'ADDRESS/32'
	list addresses 'ADDRESS/128'
	option force_link '1'

config wireguard_wg
	option description 'wg-endpoint'
	option public_key 'KEY'
	option route_allowed_ips '1'
	option endpoint_port '51820'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option endpoint_host 'HOST'

config route6
	option target '::/0'
	option interface 'wg'

config interface 'vlan'
	option proto 'static'
	option ipaddr '192.168.100.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option device 'eth0.100'

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 localservice '1'
	option ednspacket_max '1232'
	option confdir '/tmp/dnsmasq.d'
	option cachesize '10000'
	option strictorder '1'
	option quietdhcp '1'
	option port '54'
	list server '127.0.0.1'
	list server '::1'
	option noresolv '1'

config dnsmasq 'vlan'
	list interface 'vlan'
	list notinterface 'loopback'
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/local/'
	option domain 'local'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp-vlan.leases'
	option localservice '1'
	option ednspacket_max '1232'
	option confdir '/tmp/dnsmasq-vlan.d'
	option cachesize '10000'
	option strictorder '1'
	option quietdhcp '1'
	option port '53'
	list server '127.0.0.1'
	list server '::1'
	option noresolv '1'
	option nonwildcard '1'

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'
	option force '1'
	list dhcp_option '6,192.168.99.1'
	option ra_default '1'

config dhcp 'vlan'
	option interface 'vlan'
	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'
	option force '1'
	list dhcp_option '6,192.168.100.1'
	option ra_default '1'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'
	option start '100'
	option limit '150'
	option leasetime '12h'

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

cat /etc/config/firewall

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

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

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

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

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 'vlan'
	option proto 'esp'
	option target 'ACCEPT'

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

config zone
	option name 'wgwan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option masq6 '1'
	option masq6_privacy '1'
	option mtu_fix '1'
	list network 'wg'

config forwarding
	option src 'lan'
	option dest 'wgwan'

config forwarding
	option src 'vlan'
	option dest 'wan'

Ok... i think everything is actually okay for IPv4, but your internet access is not working from the vlan network because you're not allowing vlan > wgwan forwarding. With the WG tunnel running, all traffic is routed by default through that tunnel... so if your firewall doesn't allow it, no traffic will flow (solution for this is PBR).

If you disable your wireguard interface (and restart the wan interface), you should have access to the internet. Alternatively, you can allow vlan > wgwan forwarding like this:

config forwarding
	option src 'vlan'
	option dest 'wgwan'

and that will allow internet access. Once this has been proven out (either method), you can consider your IPv4 to be working as expected.

Your next step will be to install policy based routing and define rules to route the lan and vlan as desired.

On IPv6, I am not an expert on this. My recommendation would be to mark this solved (once you've established that IPv4 is working properly based on the above discussion), then open a thread about IPv6 (which will be purely related to the Pi's configuration), and if you need help with PBR, you can open a thread for that, too.

When you're ready....

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

In general, the most important aspect for IPv6 (apart from the general routing rules of not letting subnets overlap) would be not to block ICMPv6 too much, as IPv6 relies to a major extent on that to work, end-to-end.

1 Like

Thank you. This did indeed allow connections to go through, although DNS on the interface seems to be down. I'm going to experiment a bit more with this and PBR and open a new thread when I have more to work with.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.