MR8300, bridging: eth0 vs VLAN eth0.1, why does eth0 work?

Just installed "OpenWrt 21.02-SNAPSHOT r16172-2aba3e9784"
built with image-builder for Linksys MR8300.

This device is set up to be a wifi access point, with ethernet connection to the main router.
dnsmasq is disabled (DNS service comes from the main router).

Main router is Netgear R7800 running "OpenWrt 19.07.7 r11306-c4a6851c72".

The main router has a VLAN-tagged network port, connected to a TP-Link tl-sg108e, with tagged ports (802.1Q VLAN configuration) connected to the main router (R7800) & the access point (MR8300).

The MR8300 has one ethernet connection, VLAN-tagged, to the main router. No other ethernet connections currently, although I've set it up so some of the ports are assigned untagged to either interface 'iot' or 'lan'.

I've got it working doing what I want, but the ethernet switch and bridge configuration on the MR8300 doesn't make sense to me.

Here's what LuCI shows for the VLAN configs on the switch:

VLAN 1: home LAN network
VLAN 2: WAN (not used by MR8300)
VLAN 3: IOT network

and here's /etc/config/network, /etc/config/wireless, /etc/config/dhcp, /etc/config/firewall

/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 'fd39:d1ef:ed7a::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'dhcp'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'
	option auto '0'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'
	option auto '0'
	option reqaddress 'try'
	option reqprefix 'auto'

config switch
	option name 'switch0'
	option reset '1'
	option enable_vlan '1'

config switch_vlan
	option device 'switch0'
	option vlan '1'
	option vid '1'
	option description 'LAN'
	option ports '0t 1t 3 4'

config switch_vlan
	option device 'switch0'
	option vlan '2'
	option vid '2'
	option description 'WAN'

config switch_vlan
	option device 'switch0'
	option vlan '3'
	option vid '3'
	option description 'IOT'
	option ports '0t 1t 2'

config device
	option type 'bridge'
	option name 'br-iot'
	list ports 'eth0.3'
	option bridge_empty '1'

config interface 'iot'
	option device 'br-iot'
	option proto 'dhcp'
	option hostname 'linksysAP-IOT'

/etc/config/wireless

config wifi-device 'radio0'
	option type 'mac80211'
	option hwmode '11a'
	option path 'soc/40000000.pci/pci0000:00/0000:00:00.0/0000:01:00.0'
	option cell_density '0'
	option channel 'auto'
	option htmode 'VHT80'

config wifi-device 'radio1'
	option type 'mac80211'
	option hwmode '11g'
	option path 'platform/soc/a000000.wifi'
	option cell_density '0'
	option channel '1'
	option htmode 'HT20'

config wifi-iface 'default_radio1'
	option device 'radio1'
	option mode 'ap'
	option key '***elided***'
	option network 'iot'
	option encryption 'psk2+ccmp'
	option ssid 'KohlIOT'

config wifi-device 'radio2'
	option type 'mac80211'
	option channel '36'
	option hwmode '11a'
	option path 'platform/soc/a800000.wifi'
	option htmode 'VHT80'
	option cell_density '0'

config wifi-iface 'wifinet2'
	option device 'radio2'
	option mode 'ap'
	option encryption 'sae-mixed'
	option key '***elided***'
	option ieee80211w '1'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'
	option ssid 'james-street-lake-5G'

config wifi-iface 'wifinet3'
	option device 'radio0'
	option mode 'ap'
	option network 'lan'
	option encryption 'sae-mixed'
	option key '***elided***'
	option ieee80211w '1'
	option wpa_disable_eapol_key_retries '1'
	option ssid 'james-street-lake-5G'

config wifi-iface 'wifinet4'
	option device 'radio1'
	option mode 'ap'
	option ssid 'james-street-lake'
	option encryption 'sae-mixed'
	option key '***elided***'
	option ieee80211w '1'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'

config wifi-iface 'wifinet5'
	option device 'radio2'
	option mode 'ap'
	option ssid 'OpenWrt-5G'
	option encryption 'sae-mixed'
	option key '***elided***'
	option ieee80211w '1'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'

config wifi-iface 'wifinet6'
	option device 'radio1'
	option mode 'ap'
	option ssid 'OpenWrt-2.4G'
	option encryption 'sae-mixed'
	option key '***elided***'
	option ieee80211w '1'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'

config wifi-iface 'wifinet7'
	option device 'radio0'
	option mode 'ap'
	option ssid 'OpenWrt-5G-low'
	option encryption 'sae-mixed'
	option key '***elided***'
	option ieee80211w '1'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'

/etc/config/dhcp

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

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv4 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ignore '1'
	option ra 'hybrid'
	option dhcpv6 'hybrid'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'
	list ra_flags 'none'

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 syn_flood	1
	option input		ACCEPT
	option output		ACCEPT
	option forward		REJECT
# Uncomment this line to disable ipv6 rules
#	option disable_ipv6	1

config zone
	option name		lan
	list   network		'lan'
	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 forwarding
	option src		lan
	option dest		wan

# We need to accept udp packets on port 68,
# see https://dev.openwrt.org/ticket/4108
config rule
	option name		Allow-DHCP-Renew
	option src		wan
	option proto		udp
	option dest_port	68
	option target		ACCEPT
	option family		ipv4

# Allow IPv4 ping
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

# Allow DHCPv6 replies
# see https://dev.openwrt.org/ticket/10381
config rule
	option name		Allow-DHCPv6
	option src		wan
	option proto		udp
	option src_ip		fc00::/6
	option dest_ip		fc00::/6
	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

# Allow essential incoming IPv6 ICMP traffic
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

# Allow essential forwarded IPv6 ICMP traffic
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

# allow interoperability with traceroute classic
# note that traceroute uses a fixed port range, and depends on getting
# back ICMP Unreachables.  if we're operating in DROP mode, it won't
# work so we explicitly REJECT packets on these ports.
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		false

# include a file with users custom iptables rules
config include
	option path /etc/firewall.user


### EXAMPLE CONFIG SECTIONS
# do not allow a specific ip to access wan
#config rule
#	option src		lan
#	option src_ip	192.168.45.2
#	option dest		wan
#	option proto	tcp
#	option target	REJECT

# block a specific mac on wan
#config rule
#	option dest		wan
#	option src_mac	00:11:22:33:44:66
#	option target	REJECT

# block incoming ICMP traffic on a zone
#config rule
#	option src		lan
#	option proto	ICMP
#	option target	DROP

# port redirect port coming in on wan to lan
#config redirect
#	option src			wan
#	option src_dport	80
#	option dest			lan
#	option dest_ip		192.168.16.235
#	option dest_port	80
#	option proto		tcp

# port redirect of remapped ssh port (22001) on wan
#config redirect
#	option src		wan
#	option src_dport	22001
#	option dest		lan
#	option dest_port	22
#	option proto		tcp

### FULL CONFIG SECTIONS
#config rule
#	option src		lan
#	option src_ip	192.168.45.2
#	option src_mac	00:11:22:33:44:55
#	option src_port	80
#	option dest		wan
#	option dest_ip	194.25.2.129
#	option dest_port	120
#	option proto	tcp
#	option target	REJECT

#config redirect
#	option src		lan
#	option src_ip	192.168.45.2
#	option src_mac	00:11:22:33:44:55
#	option src_port		1024
#	option src_dport	80
#	option dest_ip	194.25.2.129
#	option dest_port	120
#	option proto	tcp

br-iot makes sense to me: it is bridging Switch VLAN eth0.3 and one wifi network, on interface 'iot'

br-lan doesn't make sense to me: it is bridging eth0, and several wifi networks on interface 'lan'.

I expected that I should have br-lan bridging Switch VLAN eth0.1, not eth0. When I change the br-lan config to bridge eth0.1 instead of eth0, it drops off the lan network. The 'iot' interface, accessed through the tagged port, still responds to ping.

From tcpdump output observing br-lan traffic, it looks like the lan interface is not receiving unicast packets in this configuration, only receiving broadcasts.

/etc/config/network looks like this in that configuration:

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 'fd39:d1ef:ed7a::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'dhcp'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'
	option auto '0'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'
	option auto '0'
	option reqaddress 'try'
	option reqprefix 'auto'

config switch
	option name 'switch0'
	option reset '1'
	option enable_vlan '1'

config switch_vlan
	option device 'switch0'
	option vlan '1'
	option vid '1'
	option description 'LAN'
	option ports '0t 1t 3 4'

config switch_vlan
	option device 'switch0'
	option vlan '2'
	option vid '2'
	option description 'WAN'

config switch_vlan
	option device 'switch0'
	option vlan '3'
	option vid '3'
	option description 'IOT'
	option ports '0t 1t 2'

config device
	option type 'bridge'
	option name 'br-iot'
	list ports 'eth0.3'
	option bridge_empty '1'

config interface 'iot'
	option device 'br-iot'
	option proto 'dhcp'
	option hostname 'linksysAP-IOT'

What I don't understand is why the 'lan' network works when br-lan bridges eth0? Shouldn't it be bridging eth0.1?

I think you need to add eth0.1 to the bridge LAN as a device and not add eth0.1 as a separate interface.

I believe that is what this part of the config is doing:

My router is missing the 'option bridge_empty '1'' command.

Why is the LAN set to DHCP? Mine is configured as 'static' with the LAN's network IP address. Do you have an upstream DHCP server?

config interface 'lan'
	option device 'br-lan'
	option proto 'dhcp'

I have a separate switch and don't configure it using OpenWRT. This is my config:

Port 1 = VID 10, VLAN 10, untagged
Port 2 - VID 1, VLAN 1 tagged and VLAN 10 tagged.
Ports 3-5 = VID 1, VLAN 1, untagged.

That's all working with

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 'fd94:9be3:80bd::/48'

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

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option netmask 'redacted'
        option ip6assign '60'
        option ipaddr 'redacted'

config interface 'WAN'
        option proto 'pppoe'
        option device 'eth0.10'
        option username 'redacted'
        option password 'redacted'
        option ipv6 'auto'
        option peerdns '0'
        list dns '1.1.1.1'

After a whole bunch of fiddling around, I discovered that this seems to be some oddity of my VLAN switch. It has separate settings for egress default tagging on untagged ports, and I think that was related to the problem.
It might also be something special about VLAN ID 1. When I switched everything for the LAN to VLAN ID 4 and set up the egress settings on the switch, now it all works as expected with br-lan bridging to eth0.4