DHCP not working when using multiple switch ports on Fritzbox 7530

Hi,

I'm using OpenWrt Snapshot r24154 on my AVM FirtzBox 7530.

Everything works fine, except for one thing: When I use more than one LAN port on one interface, DHCP is not working anymore.

Here is my 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 'fd93:e570:1faf::1/64'

config atm-bridge 'atm'
        option vpi '1'
        option vci '32'
        option encaps 'llc'
        option payload 'bridged'
        option nameprefix 'dsl'

config dsl 'dsl'
        option annex 'j'
        option tone 'bv'
        option ds_snr_offset '0'
        option firmware '/lib/firmware/xcpe_8.B.2.6.0.7_8.B.0.B.0.2.bin'

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

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

config interface 'wan'
        option device 'dsl0.7'
        option proto 'pppoe'
        option username '***'
        option password '***'
        option ipv6 '1'

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

config interface 'guestlan'
        option proto 'static'
        option device 'br-guest'
        option ipaddr '192.168.201.1'
        option netmask '255.255.255.0'

config device
        option type 'bridge'
        option name 'br-guest'
        option bridge_empty '1'
        list ports 'br-main.20'

config device
        option type 'bridge'
        option name 'br-main'
        list ports 'lan2'

config bridge-vlan
        option device 'br-main'
        option vlan '1'
        list ports 'lan2:u*'

config bridge-vlan
        option device 'br-main'
        option vlan '20'
        list ports 'lan2:t'

config interface 'shellylan'
        option proto 'static'
        option device 'br-shellylan'
        option ipaddr '172.19.12.1'
        option netmask '255.255.255.0'

config device
        option type 'bridge'
        option name 'br-shellylan'
        list ports 'lan4'

And here the dhcp config:

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/***/'
        option domain '***'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '0'
        option ednspacket_max '1232'
        list server '2003:180:2:a000::53'
        list server '217.237.151.142'
        list server '217.237.150.188'
        list server '2003:180:2:b000::53'

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

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 dhcp 'guestlan'
        option interface 'guestlan'
        option start '20'
        option limit '150'
        option leasetime '1h'

config domain
        option name 'openwrt2'
        option ip '172.19.10.2'

config dhcp 'shellylan'
        option interface 'shellylan'
        option start '100'
        option limit '150'
        option leasetime '12h'

On lan2 I have all my devices (through unmanaged switches) and that works flawlessly. On lan4 I have a single device directly connected. On lan1 I have another unmanaged switch to currently a single device (here currently unconfigured)
I have built a VLAN (1 for normal traffic, 20 for Guest Wi-Fi), there is also a second OpenWrt device acting as a dumb AP on lan2 -> unmanaged switch.
I created a second subnet on lan4 as a workaround, but I hope that it can be avoided.
As soon as I put lan1 or lan4 into the br-main (with the correct VLAN settings) or into the br-lan (to exclude them from the VLANs), DHCP is not working anymore, and the system log is full of DHCPREQUEST/DHCPOFFER of devices which ask for a IP address.
Did I miss something in the config?

Thanks in advance and greetings,
Sid

Did you restart dnsmasq after the changes?
Does it work if you setup static IP settings?

I did restart dnsmasq, but this doesn't help.
And devices with static IPs work as well, but everything using DHCP doesn't get IP addresses anymore (except from devices directly connected via Wi-Fi, devices connecting via the dumb AP don't get IP addresses like the other devices connected via the lan ports).

My current workaround would be to put each LAN port into its own subnet, but that's suboptimal in my opinion.

Apply the configuration you tried. Then please run the following commands (copy-paste the whole block) and paste the output here, using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have

ubus call system board; \
uci export network; uci export wireless; \
uci export dhcp; uci export firewall; \
nft list ruleset; \
ip -4 addr ; ip -4 ro li tab all ; ip -4 ru; \
service dnsmasq restart; logread -e dnsmasq

Any specific reason for running a snapshot? Your device supports current stable.

So, here are all the configs and stuff up to the dnsmasq logs after applying the config:


        "kernel": "6.1.57",
        "hostname": "OpenWrt",
        "system": "ARMv7 Processor rev 5 (v7l)",
        "model": "AVM FRITZ!Box 7530",
        "board_name": "avm,fritzbox-7530",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "SNAPSHOT",
                "revision": "r24154-6f31941d38",
                "target": "ipq40xx/generic",
                "description": "OpenWrt SNAPSHOT r24154-6f31941d38"
        }
}
package 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 'fd93:e570:1faf::1/64'

config atm-bridge 'atm'
        option vpi '1'
        option vci '32'
        option encaps 'llc'
        option payload 'bridged'
        option nameprefix 'dsl'

config dsl 'dsl'
        option annex 'j'
        option tone 'bv'
        option ds_snr_offset '0'
        option firmware '/lib/firmware/xcpe_8.B.2.6.0.7_8.B.0.B.0.2.bin'

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

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

config device
        option name 'dsl0'
        option macaddr '***'

config interface 'wan'
        option device 'dsl0.7'
        option proto 'pppoe'
        option username '***'
        option password '***'
        option ipv6 '1'

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

config interface 'guestlan'
        option proto 'static'
        option device 'br-guest'
        option ipaddr '192.168.201.1'
        option netmask '255.255.255.0'

config device
        option type 'bridge'
        option name 'br-guest'
        option bridge_empty '1'
        list ports 'br-main.20'

config device
        option type 'bridge'
        option name 'br-main'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'

config bridge-vlan
        option device 'br-main'
        option vlan '1'
        list ports 'lan1:u*'
        list ports 'lan2:u*'
        list ports 'lan3:u*'
        list ports 'lan4:u*'

config bridge-vlan
        option device 'br-main'
        option vlan '20'
        list ports 'lan1:t'
        list ports 'lan2:t'
        list ports 'lan3:t'

config interface 'wireguard'
        option proto 'wireguard'
        option private_key '***'
        option listen_port '51830'
        list addresses '192.168.101.1'

config wireguard_wireguard
        option description '***'
        option public_key '***'
        option private_key '***'
        option preshared_key '***'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '192.168.101.10/32'

package wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path 'platform/soc/a000000.wifi'
        option channel 'auto'
        option band '2g'
        option htmode 'HT20'
        option cell_density '0'

config wifi-device 'radio1'
        option type 'mac80211'
        option path 'platform/soc/a800000.wifi'
        option channel 'auto'
        option band '5g'
        option htmode 'VHT80'
        option cell_density '0'

config wifi-iface 'wifinet0'
        option device 'radio0'
        option mode 'ap'
        option ssid '***'
        option encryption 'sae-mixed'
        option key '***'
        option network 'lan'

config wifi-iface 'wifinet1'
        option device 'radio0'
        option mode 'ap'
        option ssid '*** Guests'
        option encryption 'psk-mixed'
        option isolate '1'
        option key '***'
        option network 'guestlan'

config wifi-iface 'wifinet2'
        option device 'radio1'
        option mode 'ap'
        option ssid '***'
        option encryption 'sae-mixed'
        option key '***'
        option network 'lan'

config wifi-iface 'wifinet3'
        option device 'radio1'
        option mode 'ap'
        option ssid '*** Guests'
        option encryption 'psk-mixed'
        option isolate '1'
        option key '***'
        option network 'guestlan'

package dhcp

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/***/'
        option domain '***'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '0'
        option ednspacket_max '1232'
        list server '2003:180:2:a000::53'
        list server '217.237.151.142'
        list server '217.237.150.188'
        list server '2003:180:2:b000::53'

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

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 dhcp 'guestlan'
        option interface 'guestlan'
        option start '20'
        option limit '150'
        option leasetime '1h'

config domain
        option name 'openwrt2'
        option ip '172.19.10.2'

package firewall

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

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

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 redirect
        option dest 'lan'
        option target 'DNAT'
        option name 'HASS Let'\''s Encrypt'
        list proto 'tcp'
        option src 'wan'
        option src_dport '80'
        option dest_ip '172.19.11.94'
        option dest_port '80'

config redirect
        option dest 'lan'
        option target 'DNAT'
        option name 'HASS website'
        list proto 'tcp'
        option src 'wan'
        option src_dport '443'
        option dest_ip '172.19.11.94'
        option dest_port '443'

config rule
        option name 'Allow-WireGuard'
        option src 'wan'
        option dest_port '51830'
        option target 'ACCEPT'

config zone
        option name 'guest'
        option input 'DROP'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'guestlan'

config forwarding
        option src 'guest'
        option dest 'wan'

config rule
        option name 'Guest DNS'
        option src 'guest'
        option dest_port '53'
        option target 'ACCEPT'

config rule
        option name 'Guest DHCP'
        list proto 'udp'
        option src 'guest'
        option dest_port '67'
        option target 'ACCEPT'

config rule
        option name 'Guest ICMP'
        list proto 'icmp'
        option src 'guest'
        option target 'ACCEPT'

table inet fw4 {
        chain input {
                type filter hook input priority filter; policy drop;
                iifname "lo" accept comment "!fw4: Accept traffic from loopback"
                ct state established,related accept comment "!fw4: Allow inbound established and related flows"
                tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
                iifname { "lan1", "br-lan", "wireguard" } jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
                iifname "pppoe-wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
                iifname "br-guest" jump input_guest comment "!fw4: Handle guest IPv4/IPv6 input traffic"
        }

        chain forward {
                type filter hook forward priority filter; policy drop;
                ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
                iifname { "lan1", "br-lan", "wireguard" } jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
                iifname "pppoe-wan" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
                iifname "br-guest" jump forward_guest comment "!fw4: Handle guest IPv4/IPv6 forward traffic"
                jump handle_reject
        }

        chain output {
                type filter hook output priority filter; policy accept;
                oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
                ct state established,related accept comment "!fw4: Allow outbound established and related flows"
                oifname { "lan1", "br-lan", "wireguard" } jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
                oifname "pppoe-wan" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
                oifname "br-guest" jump output_guest comment "!fw4: Handle guest IPv4/IPv6 output traffic"
        }

        chain prerouting {
                type filter hook prerouting priority filter; policy accept;
                iifname { "lan1", "br-lan", "wireguard" } jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
                iifname "br-guest" jump helper_guest comment "!fw4: Handle guest IPv4/IPv6 helper assignment"
        }

        chain handle_reject {
                meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
                reject comment "!fw4: Reject any other traffic"
        }

        chain syn_flood {
                limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
                drop comment "!fw4: Drop excess packets"
        }

        chain input_lan {
                ct status dnat accept comment "!fw4: Accept port redirections"
                jump accept_from_lan
        }

        chain output_lan {
                jump accept_to_lan
        }

        chain forward_lan {
                jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
                ct status dnat accept comment "!fw4: Accept port forwards"
                jump accept_to_lan
        }

        chain helper_lan {
        }

        chain accept_from_lan {
                iifname { "lan1", "br-lan", "wireguard" } counter packets 21661 bytes 2081138 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
        }

        chain accept_to_lan {
                oifname { "lan1", "br-lan", "wireguard" } counter packets 7853 bytes 803374 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
        }

        chain input_wan {
                meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
                icmp type echo-request counter packets 15 bytes 506 accept comment "!fw4: Allow-Ping"
                meta nfproto ipv4 meta l4proto igmp counter packets 0 bytes 0 accept comment "!fw4: Allow-IGMP"
                meta nfproto ipv6 udp dport 546 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCPv6"
                ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
                icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 21 bytes 2856 accept comment "!fw4: Allow-ICMPv6-Input"
                icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
                tcp dport 51830 counter packets 0 bytes 0 accept comment "!fw4: Allow-WireGuard"
                udp dport 51830 counter packets 0 bytes 0 accept comment "!fw4: Allow-WireGuard"
                ct status dnat accept comment "!fw4: Accept port redirections"
                jump reject_from_wan
        }

        chain output_wan {
                jump accept_to_wan
        }

        chain forward_wan {
                icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 7 bytes 756 accept comment "!fw4: Allow-ICMPv6-Forward"
                icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
                meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
                udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
                ct status dnat accept comment "!fw4: Accept port forwards"
                jump reject_to_wan
        }

        chain accept_to_wan {
                meta nfproto ipv4 oifname "pppoe-wan" ct state invalid counter packets 683 bytes 35087 drop comment "!fw4: Prevent NAT leakage"
                oifname "pppoe-wan" counter packets 34980 bytes 5511971 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
        }

        chain reject_from_wan {
                iifname "pppoe-wan" counter packets 2253 bytes 100501 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
        }

        chain reject_to_wan {
                oifname "pppoe-wan" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
        }

        chain input_guest {
                tcp dport 53 counter packets 0 bytes 0 accept comment "!fw4: Guest DNS"
                udp dport 53 counter packets 0 bytes 0 accept comment "!fw4: Guest DNS"
                udp dport 67 counter packets 0 bytes 0 accept comment "!fw4: Guest DHCP"
                meta l4proto { icmp, ipv6-icmp } counter packets 0 bytes 0 accept comment "!fw4: Guest ICMP"
                jump drop_from_guest
        }

        chain output_guest {
                jump accept_to_guest
        }

        chain forward_guest {
                jump accept_to_wan comment "!fw4: Accept guest to wan forwarding"
                jump reject_to_guest
        }

        chain helper_guest {
        }

        chain accept_to_guest {
                oifname "br-guest" counter packets 0 bytes 0 accept comment "!fw4: accept guest IPv4/IPv6 traffic"
        }

        chain reject_to_guest {
                oifname "br-guest" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject guest IPv4/IPv6 traffic"
        }

        chain drop_from_guest {
                iifname "br-guest" counter packets 0 bytes 0 drop comment "!fw4: drop guest IPv4/IPv6 traffic"
        }

        chain dstnat {
                type nat hook prerouting priority dstnat; policy accept;
                iifname { "lan1", "br-lan", "wireguard" } jump dstnat_lan comment "!fw4: Handle lan IPv4/IPv6 dstnat traffic"
                iifname "pppoe-wan" jump dstnat_wan comment "!fw4: Handle wan IPv4/IPv6 dstnat traffic"
        }

        chain srcnat {
                type nat hook postrouting priority srcnat; policy accept;
                oifname { "lan1", "br-lan", "wireguard" } jump srcnat_lan comment "!fw4: Handle lan IPv4/IPv6 srcnat traffic"
                oifname "pppoe-wan" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
        }

        chain dstnat_lan {
                ip saddr { 172.19.10.0-172.19.12.255, 192.168.101.1 } ip daddr *** tcp dport 80 dnat ip to 172.19.11.94:80 comment "!fw4: HASS Let's Encrypt (reflection)"
                ip saddr { 172.19.10.0-172.19.12.255, 192.168.101.1 } ip daddr *** tcp dport 443 dnat ip to 172.19.11.94:443 comment "!fw4: HASS website (reflection)"
        }

        chain srcnat_lan {
                ip saddr { 172.19.10.0-172.19.12.255, 192.168.101.1 } ip daddr 172.19.11.94 tcp dport 80 snat ip to 172.19.10.1 comment "!fw4: HASS Let's Encrypt (reflection)"
                ip saddr { 172.19.10.0-172.19.12.255, 192.168.101.1 } ip daddr 172.19.11.94 tcp dport 443 snat ip to 172.19.10.1 comment "!fw4: HASS website (reflection)"
        }

        chain dstnat_wan {
                meta nfproto ipv4 tcp dport 80 counter packets 11 bytes 542 dnat ip to 172.19.11.94:80 comment "!fw4: HASS Let's Encrypt"
                meta nfproto ipv4 tcp dport 443 counter packets 52 bytes 2984 dnat ip to 172.19.11.94:443 comment "!fw4: HASS website"
        }

        chain srcnat_wan {
                meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
        }

        chain raw_prerouting {
                type filter hook prerouting priority raw; policy accept;
        }

        chain raw_output {
                type filter hook output priority raw; policy accept;
        }

        chain mangle_prerouting {
                type filter hook prerouting priority mangle; policy accept;
        }

        chain mangle_postrouting {
                type filter hook postrouting priority mangle; policy accept;
        }

        chain mangle_input {
                type filter hook input priority mangle; policy accept;
        }

        chain mangle_output {
                type route hook output priority mangle; policy accept;
        }

        chain mangle_forward {
                type filter hook forward priority mangle; policy accept;
                iifname "pppoe-wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
                oifname "pppoe-wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
        }
}
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
7: br-guest: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 192.168.201.1/24 brd 192.168.201.255 scope global br-guest
       valid_lft forever preferred_lft forever
10: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 172.19.10.1/23 brd 172.19.11.255 scope global br-lan
       valid_lft forever preferred_lft forever
12: wireguard: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN qlen 1000
    inet 192.168.101.1/32 brd 255.255.255.255 scope global wireguard
       valid_lft forever preferred_lft forever
43: pppoe-wan: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN qlen 3
    inet *** peer ***/32 scope global pppoe-wan
       valid_lft forever preferred_lft forever
default via *** dev pppoe-wan
*** dev pppoe-wan scope link  src ***
172.19.10.0/23 dev br-lan scope link  src 172.19.10.1
192.168.101.10 dev wireguard scope link
192.168.201.0/24 dev br-guest scope link  src 192.168.201.1
local *** dev pppoe-wan table local scope host  src ***
local 127.0.0.0/8 dev lo table local scope host  src 127.0.0.1
local 127.0.0.1 dev lo table local scope host  src 127.0.0.1
broadcast 127.255.255.255 dev lo table local scope link  src 127.0.0.1
local 172.19.10.1 dev br-lan table local scope host  src 172.19.10.1
broadcast 172.19.11.255 dev br-lan table local scope link  src 172.19.10.1
local 192.168.101.1 dev wireguard table local scope host  src 192.168.101.1
local 192.168.201.1 dev br-guest table local scope host  src 192.168.201.1
broadcast 192.168.201.255 dev br-guest table local scope link  src 192.168.201.1
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

And here are the logs:

Tue Oct 31 09:28:50 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: started, version 2.89 cachesize 1000
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-nftset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq-dhcp[1]: DHCP, IP range 192.168.201.20 -- 192.168.201.169, lease time 1h
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq-dhcp[1]: DHCP, IP range 172.19.11.9 -- 172.19.11.158, lease time 1h
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 2003:180:2:a000::53#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 217.237.151.142#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 217.237.150.188#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 2003:180:2:b000::53#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for internal.***
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 2003:180:2:a000::53#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 217.237.151.142#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 217.237.150.188#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 2003:180:2:b000::53#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 217.237.151.142#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 217.237.150.188#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 2003:180:2:a000::53#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using nameserver 2003:180:2:b000::53#53
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: using only locally-known addresses for internal.***
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: read /etc/hosts - 12 names
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 8 names
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq[1]: read /tmp/hosts/odhcpd - 16 names
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq-dhcp[1]: read /etc/ethers - 0 addresses
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:28:58 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:00 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:00 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:02 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:02 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:03 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:03 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:05 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:05 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:09 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:09 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:19 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:19 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:20 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:20 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:22 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:22 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:26 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:26 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:27 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:27 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:28 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.60 7c:c7:09:06:40:81
Tue Oct 31 09:29:28 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.60 7c:c7:09:06:40:81 osmini
Tue Oct 31 09:29:29 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:29 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:31 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:31 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:32 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:32 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:34 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:34 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:37 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:37 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:48 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:48 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:49 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:49 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:51 2023 daemon.info dnsmasq-dhcp[1]: DHCPREQUEST(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:51 2023 daemon.info dnsmasq-dhcp[1]: DHCPACK(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:53 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:53 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:54 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:54 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:56 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:29:56 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac
Tue Oct 31 09:30:00 2023 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) 2c:be:eb:20:d2:ac
Tue Oct 31 09:30:00 2023 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 172.19.11.54 2c:be:eb:20:d2:ac

The last bit shows my phone trying to get an IP address after disconnecting from Wi-Fi and connecting again (via the dumb AP)

The reason for snapshot is that the VDSL modem is only supported in Snapshot (and 23.05, but that stable version is only a few days old)

Change vlan 1 to 10

Note: VLANs can be any number, except 1 and 2 - 10 and 20 are just an example.

I have done it, still the same problem unfortunately.

The DHCP server is answering to the client with an offer, as we can see from the logs. Why is it lost is another question. You can try to run a tcpdump on br-lan interface, filter udp port 67, and verify that you see the packets in and out.

Can you draw a diagram of your phyiscal network topology?

You've mentioned that you have unmanaged switches... this is going to present a few problems.

  1. unmanaged switches are not designed to work with tagged networks. The behavior is undefined and can actually cause problems.

  2. with unmanaged switches, you cannot assign port-vlan memberships, so this means that you don't have the ability to control if a VLAN is tagged or untagged on a given port nor can you control which ports carry a VLAN.

The other big thing I see is that your lan dhcp server is invalid. You have a start value of 265 -- this is > 254, which is the max address for a /24 subnet.

The equation is:

start to (start + limit - 1)

So you need to change your start value at the very least (and it must be below 105 if you keep the limit value the same).

Running tcpdump on the interface shows on the router that the packets are coming in and going out, but the AP only shows the Request going to the router. When I remove everything but lan2 from the bridge, the AP shows the request and the reply.

@psherman here is a simple drawing:

And I use a /23, so the DHCP settings are working.

It also doesn't work if I put lan1-4 into br-lan directly (and so doing no VLAN tagging)

Thanks.

You should not be using unmanaged switches here, but it is possible that these are not the cause of the problem... regardless, I would still recommend replacing any switch(es) that will need to pass tagged networks with managed units.

Thank you, my mistake. I misread your configuration.

So, I think the issue is that you're actually creating bridges of bridges... let's fix that:

Delete this:

And delete this:

Now, edit your lan to use br-main.1 like this:

config interface 'lan'
        option device 'br-main.1'
        option proto 'static'
        option ipaddr '172.19.10.1'
        option netmask '255.255.254.0'
        option ip6assign '60'

And likewise with the guest network, br-main.20:

config interface 'guestlan'
        option proto 'static'
        option device 'br-main.20'
        option ipaddr '192.168.201.1'
        option netmask '255.255.255.0'

Then reboot and try again.

So, I have now removed all the VLAN stuff, rebooted and it is still the same.

My current config is this:

package 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 'fd93:e570:1faf::1/64'

config atm-bridge 'atm'
	option vpi '1'
	option vci '32'
	option encaps 'llc'
	option payload 'bridged'
	option nameprefix 'dsl'

config dsl 'dsl'
	option annex 'j'
	option tone 'bv'
	option ds_snr_offset '0'
	option firmware '/lib/firmware/xcpe_8.B.2.6.0.7_8.B.0.B.0.2.bin'

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

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

config device
	option name 'dsl0'
	option macaddr '***'

config interface 'wan'
	option device 'dsl0.7'
	option proto 'pppoe'
	option username '***'
	option password '***'
	option ipv6 '1'

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

config interface 'guestlan'
	option proto 'static'
	option device 'br-main.20'
	option ipaddr '192.168.201.1'
	option netmask '255.255.255.0'

config interface 'wireguard'
	option proto 'wireguard'
	option private_key '***'
	option listen_port '51830'
	list addresses '192.168.101.1'

config wireguard_wireguard
	option description '***'
	option public_key '***'
	option private_key '***'
	option preshared_key '***'
	option route_allowed_ips '1'
	option persistent_keepalive '25'
	list allowed_ips '192.168.101.10/32'

package wireless

config wifi-device 'radio0'
	option type 'mac80211'
	option path 'platform/soc/a000000.wifi'
	option channel 'auto'
	option band '2g'
	option htmode 'HT20'
	option cell_density '0'

config wifi-device 'radio1'
	option type 'mac80211'
	option path 'platform/soc/a800000.wifi'
	option channel 'auto'
	option band '5g'
	option htmode 'VHT80'
	option cell_density '0'

config wifi-iface 'wifinet0'
	option device 'radio0'
	option mode 'ap'
	option ssid '***'
	option encryption 'sae-mixed'
	option key '***'
	option network 'lan'

config wifi-iface 'wifinet1'
	option device 'radio0'
	option mode 'ap'
	option ssid '*** Guests'
	option encryption 'psk-mixed'
	option isolate '1'
	option key '***'
	option network 'guestlan'

config wifi-iface 'wifinet2'
	option device 'radio1'
	option mode 'ap'
	option ssid '***'
	option encryption 'sae-mixed'
	option key '***'
	option network 'lan'

config wifi-iface 'wifinet3'
	option device 'radio1'
	option mode 'ap'
	option ssid '***'
	option encryption 'psk-mixed'
	option isolate '1'
	option key '***'
	option network 'guestlan'

package dhcp

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/internal.***/'
	option domain 'internal.***'
	option expandhosts '1'
	option cachesize '1000'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
	option localservice '0'
	option ednspacket_max '1232'
	list server '2003:180:2:a000::53'
	list server '217.237.151.142'
	list server '217.237.150.188'
	list server '2003:180:2:b000::53'

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

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 dhcp 'guestlan'
	option interface 'guestlan'
	option start '20'
	option limit '150'
	option leasetime '1h'

config domain
	option name 'openwrt2'
	option ip '172.19.10.2'

config domain
	option name 'camera-door'
	option ip '172.19.10.11'

package firewall

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

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

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 redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'HASS Let'\''s Encrypt'
	list proto 'tcp'
	option src 'wan'
	option src_dport '80'
	option dest_ip '172.19.11.94'
	option dest_port '80'

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'HASS website'
	list proto 'tcp'
	option src 'wan'
	option src_dport '443'
	option dest_ip '172.19.11.94'
	option dest_port '443'

config rule
	option name 'Allow-WireGuard'
	option src 'wan'
	option dest_port '51830'
	option target 'ACCEPT'

config zone
	option name 'guest'
	option input 'DROP'
	option output 'ACCEPT'
	option forward 'REJECT'
	list network 'guestlan'

config forwarding
	option src 'guest'
	option dest 'wan'

config rule
	option name 'Guest DNS'
	option src 'guest'
	option dest_port '53'
	option target 'ACCEPT'

config rule
	option name 'Guest DHCP'
	list proto 'udp'
	option src 'guest'
	option dest_port '67'
	option target 'ACCEPT'

config rule
	option name 'Guest ICMP'
	list proto 'icmp'
	option src 'guest'
	option target 'ACCEPT'

table inet fw4 {
	chain input {
		type filter hook input priority filter; policy drop;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname { "br-lan", "wireguard" } jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "pppoe-wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
		iifname "br-main.20" jump input_guest comment "!fw4: Handle guest IPv4/IPv6 input traffic"
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname { "br-lan", "wireguard" } jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "pppoe-wan" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		iifname "br-main.20" jump forward_guest comment "!fw4: Handle guest IPv4/IPv6 forward traffic"
		jump handle_reject
	}

	chain output {
		type filter hook output priority filter; policy accept;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		oifname { "br-lan", "wireguard" } jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "pppoe-wan" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
		oifname "br-main.20" jump output_guest comment "!fw4: Handle guest IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname { "br-lan", "wireguard" } jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
		iifname "br-main.20" jump helper_guest comment "!fw4: Handle guest IPv4/IPv6 helper assignment"
	}

	chain handle_reject {
		meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
		reject comment "!fw4: Reject any other traffic"
	}

	chain syn_flood {
		limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
		drop comment "!fw4: Drop excess packets"
	}

	chain input_lan {
		ct status dnat accept comment "!fw4: Accept port redirections"
		jump accept_from_lan
	}

	chain output_lan {
		jump accept_to_lan
	}

	chain forward_lan {
		jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
		ct status dnat accept comment "!fw4: Accept port forwards"
		jump accept_to_lan
	}

	chain helper_lan {
	}

	chain accept_from_lan {
		iifname { "br-lan", "wireguard" } counter packets 951 bytes 111542 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain accept_to_lan {
		oifname { "br-lan", "wireguard" } counter packets 321 bytes 44463 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain input_wan {
		meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
		icmp type echo-request counter packets 0 bytes 0 accept comment "!fw4: Allow-Ping"
		meta nfproto ipv4 meta l4proto igmp counter packets 0 bytes 0 accept comment "!fw4: Allow-IGMP"
		meta nfproto ipv6 udp dport 546 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCPv6"
		ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
		tcp dport 51830 counter packets 0 bytes 0 accept comment "!fw4: Allow-WireGuard"
		udp dport 51830 counter packets 0 bytes 0 accept comment "!fw4: Allow-WireGuard"
		ct status dnat accept comment "!fw4: Accept port redirections"
		jump reject_from_wan
	}

	chain output_wan {
		jump accept_to_wan
	}

	chain forward_wan {
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
		udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
		ct status dnat accept comment "!fw4: Accept port forwards"
		jump reject_to_wan
	}

	chain accept_to_wan {
		meta nfproto ipv4 oifname "pppoe-wan" ct state invalid counter packets 61 bytes 3127 drop comment "!fw4: Prevent NAT leakage"
		oifname "pppoe-wan" counter packets 1409 bytes 120735 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain reject_from_wan {
		iifname "pppoe-wan" counter packets 121 bytes 5388 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain reject_to_wan {
		oifname "pppoe-wan" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain input_guest {
		tcp dport 53 counter packets 0 bytes 0 accept comment "!fw4: Guest DNS"
		udp dport 53 counter packets 0 bytes 0 accept comment "!fw4: Guest DNS"
		udp dport 67 counter packets 0 bytes 0 accept comment "!fw4: Guest DHCP"
		meta l4proto { icmp, ipv6-icmp } counter packets 0 bytes 0 accept comment "!fw4: Guest ICMP"
		jump drop_from_guest
	}

	chain output_guest {
		jump accept_to_guest
	}

	chain forward_guest {
		jump accept_to_wan comment "!fw4: Accept guest to wan forwarding"
		jump reject_to_guest
	}

	chain helper_guest {
	}

	chain accept_to_guest {
		oifname "br-main.20" counter packets 0 bytes 0 accept comment "!fw4: accept guest IPv4/IPv6 traffic"
	}

	chain reject_to_guest {
		oifname "br-main.20" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject guest IPv4/IPv6 traffic"
	}

	chain drop_from_guest {
		iifname "br-main.20" counter packets 0 bytes 0 drop comment "!fw4: drop guest IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
		iifname { "br-lan", "wireguard" } jump dstnat_lan comment "!fw4: Handle lan IPv4/IPv6 dstnat traffic"
		iifname "pppoe-wan" jump dstnat_wan comment "!fw4: Handle wan IPv4/IPv6 dstnat traffic"
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname { "br-lan", "wireguard" } jump srcnat_lan comment "!fw4: Handle lan IPv4/IPv6 srcnat traffic"
		oifname "pppoe-wan" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
	}

	chain dstnat_lan {
		ip saddr { 172.19.10.0/23, 192.168.101.1 } ip daddr *** tcp dport 80 dnat ip to 172.19.11.94:80 comment "!fw4: HASS Let's Encrypt (reflection)"
		ip saddr { 172.19.10.0/23, 192.168.101.1 } ip daddr *** tcp dport 443 dnat ip to 172.19.11.94:443 comment "!fw4: HASS website (reflection)"
	}

	chain srcnat_lan {
		ip saddr { 172.19.10.0/23, 192.168.101.1 } ip daddr 172.19.11.94 tcp dport 80 snat ip to 172.19.10.1 comment "!fw4: HASS Let's Encrypt (reflection)"
		ip saddr { 172.19.10.0/23, 192.168.101.1 } ip daddr 172.19.11.94 tcp dport 443 snat ip to 172.19.10.1 comment "!fw4: HASS website (reflection)"
	}

	chain dstnat_wan {
		meta nfproto ipv4 tcp dport 80 counter packets 0 bytes 0 dnat ip to 172.19.11.94:80 comment "!fw4: HASS Let's Encrypt"
		meta nfproto ipv4 tcp dport 443 counter packets 8 bytes 480 dnat ip to 172.19.11.94:443 comment "!fw4: HASS website"
	}

	chain srcnat_wan {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
	}

	chain raw_prerouting {
		type filter hook prerouting priority raw; policy accept;
	}

	chain raw_output {
		type filter hook output priority raw; policy accept;
	}

	chain mangle_prerouting {
		type filter hook prerouting priority mangle; policy accept;
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "pppoe-wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname "pppoe-wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
	}
}
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
7: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 172.19.10.1/23 brd 172.19.11.255 scope global br-lan
       valid_lft forever preferred_lft forever
8: wireguard: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN qlen 1000
    inet 192.168.101.1/32 brd 255.255.255.255 scope global wireguard
       valid_lft forever preferred_lft forever
17: pppoe-wan: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN qlen 3
    inet *** peer 62.155.245.86/32 scope global pppoe-wan
       valid_lft forever preferred_lft forever
default via 62.155.245.86 dev pppoe-wan 
62.155.245.86 dev pppoe-wan scope link  src *** 
172.19.10.0/23 dev br-lan scope link  src 172.19.10.1 
192.168.101.10 dev wireguard scope link 
local *** dev pppoe-wan table local scope host  src *** 
local 127.0.0.0/8 dev lo table local scope host  src 127.0.0.1 
local 127.0.0.1 dev lo table local scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo table local scope link  src 127.0.0.1 
local 172.19.10.1 dev br-lan table local scope host  src 172.19.10.1 
broadcast 172.19.11.255 dev br-lan table local scope link  src 172.19.10.1 
local 192.168.101.1 dev wireguard table local scope host  src 192.168.101.1 
0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default 

Still, when I add lan1 or lan4 to br-lan, DHCP replys are not received anymore, and as soon as I remove all interfaces except lan2, everything works again.

One thing is to avoid using vlans 1 and 2 in this router. The second thing is to capture the packets on every link to see where is it lost. I would also remove the switch during testing, as it is not managed, and no one knows how it handles tagged frames.

What happens if you restore br-lan to the default condition... should look like this:

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

Also, since we're getting rid of the vlans for now... delete this:

I have done this, still the same problem. As long as only one of the lan ports is used, everything works fine, as soon as I use another port as well, DHCP replys are not received anymore.
My current workaround is using another switch directly at the router and connecting everything through that, which works perfectly but is of course suboptimal.

The VLAN 1 and 2 issues for ipq40xx devices are gone with 23.05 DSA-based builds.
(otherwise I couldn't post here)

The configuration you have doesn't define the necessary bridge-vlans within br-main.
Add this:

config bridge-vlan
    option device 'br-main'
    option vlan '1'
    list ports 'lan1:u'

config bridge-vlan
    option device 'br-main'
    option vlan '20'
    list ports 'lan2:u'
    list ports 'lan3:u'

or whichever vlan you want the external ports in. If you use 'lan2:t', tagged packets will be input and output from the port-- that would be part of a trunking scheme with a VLAN aware device on the other end of the cable.

DSA hardware switching between ports only works if they are in only one bridge, the same bridge with the port you want to switch to. So the simplest thing to do is have only one bridge globally.

Ok... let's try this...

Starting with this configuration on the bridge:

and this for the lan network interface...

we should now have what amounts to a default DSA situation (all ports untagged on br-lan, no VLANs defined at all).

Then...
unplug all of your downstream switches and try connecting a computer directly to port lan1 on the router. Does it get a DHCP address? If so, move on to port lan2, and so on.

Let's see if that is working as expected.