MWAN Sanity Check - WAN Gateway via LAN Interface?

Hey guys,

Just wanted to quickly wrap my head around a situation that I have. I have an OpenWrt router that has a standard WAN setup, and I have been tasked with setting up a secondary WAN in case our primary connection goes down. There was a Netcomm 4G Wi-Fi Modem Router that was lying around and I figured I could use this as a gateway for a secondary connection by defining a second "WAN interface" on the LAN port (let's call it LWAN), and configuring MWAN so it can use this interface.

The LWAN interface is configured as follows:

Type = Static Address
Interface = br-lan
IP = 192.168.14.253
Gateway = 192.168.14.254 (the 4G router)
Firewall = WAN zone

Normally I would re-assign a LAN port and use this as WAN2, but the location that the main router is situated has no 4G service, and I have to instead place the router in another location which is quite far away, hence why I am in a situation where my secondary gateway is on my LAN.

I have been trying to get this working in a test environment, and I can get OpenWrt to send traffic to the LWAN interface, but something isn't right. Despite my metric configuration, it ALWAYS defaults to the LWAN interface, and never uses my WAN interface. Failover doesn't really work as a result.

My network looks a bit like this:

What am I doing wrong here? I feel like I am missing something. Using OpenWrt 23.05.5, and MWAN is working fine thanks to the nft2ipset scripts. I am open to using VLANs but I don't want to break the LAN and WLAN clients that are currently connected to the Netcomm 4G Modem Wi-Fi Router. Advice appreciated!

There might be a way to do this with routing and configuration on the openwrt router and alias interfaces or something. However I would suggest the following:

  • move all the wired clients on the netcomm onto the unmanaged switch, or on one of the last remaining ports on the openwrt router, or get openwrt router for AP, unmanaged/managed switch etc.
  • Wifi clients can be transitioned with another SSID on the openwrt router. Or on another AP with vlans.
  • Disable wifi on the 4g modem router and put it on another lan port repurposed as another dhcp client port

edit1:
I guess one could start with dumping the config for the openwrt router and the mwan3 config so it's not just some simple configuration.

Thanks for the input. The 4G modem is in another area of the building - it is far from everything else. Are you saying I need to add another Wi-Fi AP with ethernet? Is there no other way?

Ah. I'm suggesting the dumb "throw parts / money" at the problem as that's how I know how to get you a working solution, that is more typical and easier to support =P

Anyway. So we should start with your mwan3 config and see if anyone has some input or done it by routing before.

What I'd think to do is make sure your mwan3 ipv4 rules are correct. Plus the members are configured correctly etc. Plus we need to check the what I assume is static IP alias/veth interface or something on your lan subnet that you will use to forward traffic to the 4G modem.

So I guess start with a uci show ? or cat your /etc/config

But It's not something I've ever tried to do before. Worst case if you can't move the 4G modem and can't run another cable you can split the pairs. But vlan trunking and managed switches and/or another openwrt AP would work too.

I mean I'll do it if I have to - but I would rather use the existing equipment if possible.

Here's the output of UCI show of my "broken" config that insists on using LWAN for everything, snipped some useless info.

root@OpenWrt:~# uci show
dhcp.@dnsmasq[0]=dnsmasq
dhcp.@dnsmasq[0].domainneeded='1'
dhcp.@dnsmasq[0].localise_queries='1'
dhcp.@dnsmasq[0].rebind_protection='1'
dhcp.@dnsmasq[0].rebind_localhost='1'
dhcp.@dnsmasq[0].local='/lan/'
dhcp.@dnsmasq[0].domain='lan'
dhcp.@dnsmasq[0].expandhosts='1'
dhcp.@dnsmasq[0].cachesize='1000'
dhcp.@dnsmasq[0].authoritative='1'
dhcp.@dnsmasq[0].readethers='1'
dhcp.@dnsmasq[0].leasefile='/tmp/dhcp.leases'
dhcp.@dnsmasq[0].resolvfile='/tmp/resolv.conf.d/resolv.conf.auto'
dhcp.@dnsmasq[0].localservice='1'
dhcp.@dnsmasq[0].ednspacket_max='1232'
dhcp.lan=dhcp
dhcp.lan.interface='lan'
dhcp.lan.start='100'
dhcp.lan.limit='125'
dhcp.lan.leasetime='10m'
dhcp.lan.dhcpv4='server'
dhcp.lan.dhcpv6='server'
dhcp.lan.ra='server'
dhcp.lan.ra_flags='managed-config' 'other-config'
dhcp.wan=dhcp
dhcp.wan.interface='wan'
dhcp.wan.ignore='1'
dhcp.odhcpd=odhcpd
dhcp.odhcpd.maindhcp='0'
dhcp.odhcpd.leasefile='/tmp/hosts/odhcpd'
dhcp.odhcpd.leasetrigger='/usr/sbin/odhcpd-update'
dhcp.odhcpd.loglevel='4'
dhcp.@ipset[0]=ipset
dhcp.@ipset[0].name='mwan4'
dhcp.@ipset[0].domain='one.one.one.one'
dhcp.@ipset[0].table_family='inet'
dropbear.@dropbear[0]=dropbear
dropbear.@dropbear[0].PasswordAuth='on'
dropbear.@dropbear[0].RootPasswordAuth='on'
dropbear.@dropbear[0].Port='22'
firewall.@defaults[0]=defaults
firewall.@defaults[0].syn_flood='1'
firewall.@defaults[0].input='REJECT'
firewall.@defaults[0].output='ACCEPT'
firewall.@defaults[0].forward='REJECT'
firewall.@zone[0]=zone
firewall.@zone[0].name='lan'
firewall.@zone[0].network='lan'
firewall.@zone[0].input='ACCEPT'
firewall.@zone[0].output='ACCEPT'
firewall.@zone[0].forward='ACCEPT'
firewall.@zone[1]=zone
firewall.@zone[1].name='wan'
firewall.@zone[1].input='REJECT'
firewall.@zone[1].output='ACCEPT'
firewall.@zone[1].forward='REJECT'
firewall.@zone[1].masq='1'
firewall.@zone[1].mtu_fix='1'
firewall.@zone[1].network='wan' 'wan6' 'LWAN'
firewall.@forwarding[0]=forwarding
firewall.@forwarding[0].src='lan'
firewall.@forwarding[0].dest='wan'
firewall.@rule[0]=rule
firewall.@rule[0].name='Allow-DHCP-Renew'
firewall.@rule[0].src='wan'
firewall.@rule[0].proto='udp'
firewall.@rule[0].dest_port='68'
firewall.@rule[0].target='ACCEPT'
firewall.@rule[0].family='ipv4'
firewall.@rule[1]=rule
firewall.@rule[1].name='Allow-Ping'
firewall.@rule[1].src='wan'
firewall.@rule[1].proto='icmp'
firewall.@rule[1].icmp_type='echo-request'
firewall.@rule[1].family='ipv4'
firewall.@rule[1].target='ACCEPT'
firewall.@rule[2]=rule
firewall.@rule[2].name='Allow-IGMP'
firewall.@rule[2].src='wan'
firewall.@rule[2].proto='igmp'
firewall.@rule[2].family='ipv4'
firewall.@rule[2].target='ACCEPT'
firewall.@rule[3]=rule
firewall.@rule[3].name='Allow-DHCPv6'
firewall.@rule[3].src='wan'
firewall.@rule[3].proto='udp'
firewall.@rule[3].dest_port='546'
firewall.@rule[3].family='ipv6'
firewall.@rule[3].target='ACCEPT'
firewall.@rule[4]=rule
firewall.@rule[4].name='Allow-MLD'
firewall.@rule[4].src='wan'
firewall.@rule[4].proto='icmp'
firewall.@rule[4].src_ip='fe80::/10'
firewall.@rule[4].icmp_type='130/0' '131/0' '132/0' '143/0'
firewall.@rule[4].family='ipv6'
firewall.@rule[4].target='ACCEPT'
firewall.@rule[5]=rule
firewall.@rule[5].name='Allow-ICMPv6-Input'
firewall.@rule[5].src='wan'
firewall.@rule[5].proto='icmp'
firewall.@rule[5].icmp_type='echo-request' 'echo-reply' 'destination-unreachable' 'packet-too-big' 'time-exceeded' 'bad-header' 'unknown-header-type' 'router-solicitation' 'neighbour-solicitation' 'router-advertisement' 'neighbour-advertisement'
firewall.@rule[5].limit='1000/sec'
firewall.@rule[5].family='ipv6'
firewall.@rule[5].target='ACCEPT'
firewall.@rule[6]=rule
firewall.@rule[6].name='Allow-ICMPv6-Forward'
firewall.@rule[6].src='wan'
firewall.@rule[6].dest='*'
firewall.@rule[6].proto='icmp'
firewall.@rule[6].icmp_type='echo-request' 'echo-reply' 'destination-unreachable' 'packet-too-big' 'time-exceeded' 'bad-header' 'unknown-header-type'
firewall.@rule[6].limit='1000/sec'
firewall.@rule[6].family='ipv6'
firewall.@rule[6].target='ACCEPT'
firewall.@rule[7]=rule
firewall.@rule[7].name='Allow-IPSec-ESP'
firewall.@rule[7].src='wan'
firewall.@rule[7].dest='lan'
firewall.@rule[7].proto='esp'
firewall.@rule[7].target='ACCEPT'
firewall.@rule[8]=rule
firewall.@rule[8].name='Allow-ISAKMP'
firewall.@rule[8].src='wan'
firewall.@rule[8].dest='lan'
firewall.@rule[8].dest_port='500'
firewall.@rule[8].proto='udp'
firewall.@rule[8].target='ACCEPT'
firewall.@ipset[0]=ipset
firewall.@ipset[0].name='mwan4'
firewall.@ipset[0].family='ipv4'
firewall.@ipset[0].match='dest_ip'
firewall.@ipset[0].entry='1.1.1.1/30'
firewall.@ipset[0].timeout='60'
mwan3.globals=globals
mwan3.globals.mmx_mask='0x3F00'
mwan3.wan=interface
mwan3.wan.enabled='1'
mwan3.wan.family='ipv4'
mwan3.wan.reliability='2'
mwan3.wan.initial_state='online'
mwan3.wan.track_ip='1.1.1.1' '9.9.9.9'
mwan3.wan.track_method='ping'
mwan3.wan.count='2'
mwan3.wan.size='56'
mwan3.wan.max_ttl='60'
mwan3.wan.timeout='1'
mwan3.wan.interval='1'
mwan3.wan.failure_interval='1'
mwan3.wan.recovery_interval='10'
mwan3.wan.down='5'
mwan3.wan.up='5'
mwan3.wan.flush_conntrack='ifup' 'ifdown' 'connected' 'disconnected'
mwan3.wan_m1_w3=member
mwan3.wan_m1_w3.interface='wan'
mwan3.wan_m1_w3.metric='1'
mwan3.wan_m1_w3.weight='3'
mwan3.https=rule
mwan3.https.sticky='1'
mwan3.https.dest_port='443'
mwan3.https.proto='tcp'
mwan3.https.use_policy='balanced'
mwan3.default_rule_v4=rule
mwan3.default_rule_v4.dest_ip='0.0.0.0/0'
mwan3.default_rule_v4.use_policy='balanced'
mwan3.default_rule_v4.family='ipv4'
mwan3.default_rule_v6=rule
mwan3.default_rule_v6.dest_ip='::/0'
mwan3.default_rule_v6.use_policy='balanced'
mwan3.default_rule_v6.family='ipv6'
mwan3.LWAN=interface
mwan3.LWAN.enabled='1'
mwan3.LWAN.initial_state='online'
mwan3.LWAN.family='ipv4'
mwan3.LWAN.track_ip='1.1.1.1' '9.9.9.9'
mwan3.LWAN.track_method='ping'
mwan3.LWAN.reliability='1'
mwan3.LWAN.count='2'
mwan3.LWAN.size='56'
mwan3.LWAN.max_ttl='60'
mwan3.LWAN.timeout='1'
mwan3.LWAN.interval='1'
mwan3.LWAN.failure_interval='1'
mwan3.LWAN.recovery_interval='5'
mwan3.LWAN.down='2'
mwan3.LWAN.up='5'
mwan3.LWAN.flush_conntrack='ifup' 'ifdown' 'connected' 'disconnected'
mwan3.LWAN_m2_w3=member
mwan3.LWAN_m2_w3.interface='LWAN'
mwan3.LWAN_m2_w3.metric='2'
mwan3.LWAN_m2_w3.weight='3'
mwan3.wan_LWAN=policy
mwan3.wan_LWAN.use_member='wan_m1_w3' 'LWAN_m2_w3'
mwan3.wan_LWAN.last_resort='unreachable'
mwan3.mwan4=rule
mwan3.mwan4.family='ipv4'
mwan3.mwan4.proto='all'
mwan3.mwan4.src_ip='192.168.14.0/24'
mwan3.mwan4.dest_ip='1.1.1.1/30'
mwan3.mwan4.sticky='0'
mwan3.mwan4.ipset='mwan4'
mwan3.mwan4.use_policy='wan_LWAN'
network.loopback=interface
network.loopback.device='lo'
network.loopback.proto='static'
network.loopback.ipaddr='127.0.0.1'
network.loopback.netmask='255.0.0.0'
network.globals=globals
network.globals.ula_prefix='fd3a:896f:8df9::/48'
network.@device[0]=device
network.@device[0].name='br-lan'
network.@device[0].type='bridge'
network.@device[0].ports='eth0.1'
network.lan=interface
network.lan.device='br-lan'
network.lan.proto='static'
network.lan.ipaddr='192.168.14.1'
network.lan.netmask='255.255.255.0'
network.lan.ip6assign='60'
network.lan.dns='192.168.14.1' '9.9.9.9'
network.@device[1]=device
network.@device[1].name='eth0.2'
network.@device[1].macaddr='14:cc:20:ba:73:a1'
network.wan=interface
network.wan.device='eth0.2'
network.wan.proto='dhcp'
network.wan.metric='0'
network.wan.peerdns='0'
network.wan.dns='1.1.1.2' '9.9.9.9'
network.wan6=interface
network.wan6.device='eth0.2'
network.wan6.proto='dhcpv6'
network.@switch[0]=switch
network.@switch[0].name='switch0'
network.@switch[0].reset='1'
network.@switch[0].enable_vlan='1'
network.@switch_vlan[0]=switch_vlan
network.@switch_vlan[0].device='switch0'
network.@switch_vlan[0].vlan='1'
network.@switch_vlan[0].ports='2 3 4 5 0t'
network.@switch_vlan[1]=switch_vlan
network.@switch_vlan[1].device='switch0'
network.@switch_vlan[1].vlan='2'
network.@switch_vlan[1].ports='1 0t'
network.LWAN=interface
network.LWAN.proto='static'
network.LWAN.device='br-lan'
network.LWAN.ipaddr='192.168.14.253'
network.LWAN.netmask='255.255.0.0'
network.LWAN.gateway='192.168.14.254'
network.LWAN.dns='1.1.1.2' '9.9.9.9'
network.LWAN.metric='2'
1 Like

is metric 0 a valid metric for your wan interface? I'd think it would need to be 1.
But LWAN is a different metric of 2 which is good.

Personally I start at 10 and work my way up from there.

Other than something like creating a virtual ethernet adapter IDK where to go from here unless I actually try to replicate your setup. (But I'm doing other dev work at the moment....)

I tried 1 as the metric, made no difference.

1 Like

Cool. Other than check your routing tables and the mwan3 status IDK. Is metric 1 used by something else? Are you getting a port created on br-lan?

Anyway as an aside I quickly drew up two architectures on how I'd achieve the setup normally. (But I'd probably throw in two managed switches, one before the bridged AP, the other to get rid of the unmanaged switch)

Just realised i screwed up on the name of lan4 but eh. I meant lan3.

The second diagram with VLANs is probably my best bet as I won't be blessed with the ability to have a direct connection with the 4G modem. That said I am a bit surprised there is no other way to achieve what I'm trying to do... will be interesting to see if anyone else has managed to get this working somehow, perhaps on a second subnet or something?

We can wait and see. I put it in the too hard basket and "just add more hardware" =P.

I can think with appropriate routing and the creation of appropriate virtual ethernet adapters one could do it. But possible and good idea are two different things =P I've picked up managed switches and openwrt capable AP's for under 20-25AUD so you can make the call on time vs money I guess as well.

edit:
Yeah also if you can live with 100mbit but can't run another cable: Split the pairs in your network cable and add a dumb AP....

Yes, you need a separate interface for the second wan, you cannot run it through the lan.
It can be a simple vlan or even a secondary interface running on the same physical interface (br-lan) or you can separate a port from the switch and allocate it to the new wan.

The latter is what I have in my setup - I suspect that this isn't sufficient and I need to have that interface on a separate VLAN. I'll do some testing and see what I find.

You have an IP address overlapping there. Use 192.168.15.0/24 for LWAN.

Thanks - I tried adjusting it to a separate subnet, unfortunately I have the same issue. All my traffic ends up through that interface when I don't want it to. If I try moving my 4G router to another subnet, I have the opposite issue and it doesn't work at all.

Let's see how it looks like now:

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 mwan3; \
uci export dhcp; uci export firewall; \
ip -4 addr ; ip -4 ro li tab all ; ip -4 ru; \
mwan3 status
1 Like

Here's the report from my router - no need to redact anything as it's just a test environment. My 4G router is currently on 192.168.15.254.

root@OpenWrt:~# ubus call system board; \
> uci export network; uci export mwan3; \
> uci export dhcp; uci export firewall; \
> ip -4 addr ; ip -4 ro li tab all ; ip -4 ru; \
> mwan3 status
{
        "kernel": "5.15.167",
        "hostname": "OpenWrt",
        "system": "Atheros AR9344 rev 2",
        "model": "TP-Link TL-WDR3600 v1",
        "board_name": "tplink,tl-wdr3600-v1",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.5",
                "revision": "r24106-10cc5fcd00",
                "target": "ath79/generic",
                "description": "OpenWrt 23.05.5 r24106-10cc5fcd00"
        }
}
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 'fd3a:896f:8df9::/48'

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

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.14.1'
        option netmask '255.255.255.0'
        option ip6assign '60'
        list dns '192.168.14.1'
        list dns '9.9.9.9'

config device
        option name 'eth0.2'
        option macaddr '14:cc:20:ba:73:a1'

config interface 'wan'
        option device 'eth0.2'
        option proto 'dhcp'
        option metric '1'
        option peerdns '0'
        list dns '1.1.1.2'
        list dns '9.9.9.9'

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

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '2 3 4 5 0t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '1 0t'

config interface 'LWAN'
        option proto 'static'
        option device 'br-lan'
        option gateway '192.168.15.254'
        list dns '1.1.1.2'
        list dns '9.9.9.9'
        option metric '2'
        list ipaddr '192.168.15.1'

package mwan3

config globals 'globals'
        option mmx_mask '0x3F00'

config interface 'wan'
        option enabled '1'
        option family 'ipv4'
        option reliability '2'
        option initial_state 'online'
        list track_ip '1.1.1.1'
        list track_ip '9.9.9.9'
        option track_method 'ping'
        option count '2'
        option size '56'
        option max_ttl '60'
        option timeout '1'
        option interval '1'
        option failure_interval '1'
        option recovery_interval '10'
        option down '5'
        option up '5'
        list flush_conntrack 'ifup'
        list flush_conntrack 'ifdown'
        list flush_conntrack 'connected'
        list flush_conntrack 'disconnected'

config member 'wan_m1_w3'
        option interface 'wan'
        option metric '1'
        option weight '3'

config rule 'https'
        option sticky '1'
        option dest_port '443'
        option proto 'tcp'
        option use_policy 'balanced'

config rule 'default_rule_v4'
        option dest_ip '0.0.0.0/0'
        option use_policy 'balanced'
        option family 'ipv4'

config rule 'default_rule_v6'
        option dest_ip '::/0'
        option use_policy 'balanced'
        option family 'ipv6'

config interface 'LWAN'
        option enabled '1'
        option initial_state 'online'
        option family 'ipv4'
        list track_ip '1.1.1.1'
        list track_ip '9.9.9.9'
        option track_method 'ping'
        option reliability '2'
        option count '2'
        option size '56'
        option max_ttl '60'
        option timeout '1'
        option interval '1'
        option failure_interval '1'
        option recovery_interval '5'
        option down '2'
        option up '5'
        list flush_conntrack 'ifup'
        list flush_conntrack 'ifdown'
        list flush_conntrack 'connected'
        list flush_conntrack 'disconnected'

config member 'LWAN_m2_w3'
        option interface 'LWAN'
        option metric '2'
        option weight '3'

config policy 'wan_LWAN'
        list use_member 'wan_m1_w3'
        list use_member 'LWAN_m2_w3'
        option last_resort 'unreachable'

config rule 'mwan4'
        option family 'ipv4'
        option proto 'all'
        option src_ip '192.168.14.0/24'
        option dest_ip '1.1.1.1/30'
        option sticky '0'
        option ipset 'mwan4'
        option use_policy 'wan_LWAN'

package 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 cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '125'
        option leasetime '10m'
        option dhcpv4 'server'

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 ipset
        list name 'mwan4'
        list domain 'one.one.one.one'
        option table_family 'inet'

package firewall

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

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

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

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 ipset
        option name 'mwan4'
        option family 'ipv4'
        list match 'dest_ip'
        list entry '1.1.1.1/30'
        option timeout '60'

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 192.168.14.1/24 brd 192.168.14.255 scope global br-lan
       valid_lft forever preferred_lft forever
    inet 192.168.15.1/32 brd 255.255.255.255 scope global br-lan
       valid_lft forever preferred_lft forever
8: eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 192.168.20.233/24 brd 192.168.20.255 scope global eth0.2
       valid_lft forever preferred_lft forever
default via 192.168.20.1 dev eth0.2 table 1 proto static src 192.168.20.233 metric 1
192.168.14.0/24 dev br-lan table 1 proto kernel scope link src 192.168.14.1
192.168.20.0/24 dev eth0.2 table 1 proto static scope link metric 1
192.168.14.0/24 dev br-lan table 2 proto kernel scope link src 192.168.14.1
192.168.15.0/24 via 192.168.15.1 dev br-lan table 2 proto static metric 2
192.168.15.1 dev br-lan table 2 proto static scope link metric 2
default via 192.168.20.1 dev eth0.2 proto static src 192.168.20.233 metric 1
192.168.14.0/24 dev br-lan proto kernel scope link src 192.168.14.1
192.168.15.0/24 via 192.168.15.1 dev br-lan proto static metric 2
192.168.15.1 dev br-lan proto static scope link metric 2
192.168.20.0/24 dev eth0.2 proto static scope link metric 1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 192.168.14.1 dev br-lan table local proto kernel scope host src 192.168.14.1
broadcast 192.168.14.255 dev br-lan table local proto kernel scope link src 192.168.14.1
local 192.168.15.1 dev br-lan table local proto kernel scope host src 192.168.15.1
local 192.168.20.233 dev eth0.2 table local proto kernel scope host src 192.168.20.233
broadcast 192.168.20.255 dev eth0.2 table local proto kernel scope link src 192.168.20.233
0:      from all lookup local
1001:   from all iif eth0.2 lookup 1
1002:   from all iif br-lan lookup 2
2001:   from all fwmark 0x100/0x3f00 lookup 1
2002:   from all fwmark 0x200/0x3f00 lookup 2
2061:   from all fwmark 0x3d00/0x3f00 blackhole
2062:   from all fwmark 0x3e00/0x3f00 unreachable
3001:   from all fwmark 0x100/0x3f00 unreachable
3002:   from all fwmark 0x200/0x3f00 unreachable
32766:  from all lookup main
32767:  from all lookup default
Interface status:
 interface wan is online 14h:38m:56s, uptime 14h:39m:08s and tracking is active
 interface LWAN is error (16) and tracking is active

Current ipv4 policies:
wan_LWAN:
 wan (100%)

Current ipv6 policies:
wan_LWAN:
 unreachable

Directly connected ipv4 networks:
127.0.0.0/8
224.0.0.0/3
192.168.20.0/24
192.168.14.1
127.0.0.1
192.168.15.0/24
192.168.20.233
192.168.20.255
192.168.14.0/24
127.255.255.255
192.168.15.1
192.168.14.255

Directly connected ipv6 networks:
fd3a:896f:8df9::/64
fe80::/64

Active ipv4 user rules:

Active ipv6 user rules:

Netmask is missing from LWAN interface and /32 is assumed.

Apologies, I missed that. I changed it back to a /24 and LWAN is back up, but all my traffic is now forced through the LWAN interface despite having WAN as the priority via metric.

Edit: I also tried changing the interface from br-lan to eth0 and eth0.1 and neither configuration yeilded a connection. Only using br-lan allows LWAN connectivity, but at the cost of all my traffic being routed through it.

I feel like this is technically possible without additional VLANs and equipment but I am stumped. Any other ideas? Perhaps I need to be manually configuring routes? Or maybe it's an MWAN issue? Here's my MWAN troubleshooting output:

MultiWAN Manager - Troubleshooting
Software-Version
-------------------------------------------------
OpenWrt - 23.05.5

Output of "ip -4 a show"
-------------------------------------------------
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 192.168.14.1/24 brd 192.168.14.255 scope global br-lan
       valid_lft forever preferred_lft forever
    inet 192.168.15.1/24 brd 192.168.15.255 scope global br-lan
       valid_lft forever preferred_lft forever
8: eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 192.168.20.233/24 brd 192.168.20.255 scope global eth0.2
       valid_lft forever preferred_lft forever

Output of "ip -4 route show"
-------------------------------------------------
default via 192.168.20.1 dev eth0.2 proto static src 192.168.20.233 metric 1 
default via 192.168.15.254 dev br-lan proto static metric 2 
192.168.14.0/24 dev br-lan proto kernel scope link src 192.168.14.1 
192.168.15.0/24 dev br-lan proto static scope link metric 2 
192.168.20.0/24 dev eth0.2 proto static scope link metric 1 

Output of "ip -4 rule show"
-------------------------------------------------
0:	from all lookup local
1001:	from all iif eth0.2 lookup 1
1002:	from all iif br-lan lookup 2
2001:	from all fwmark 0x100/0x3f00 lookup 1
2002:	from all fwmark 0x200/0x3f00 lookup 2
2061:	from all fwmark 0x3d00/0x3f00 blackhole
2062:	from all fwmark 0x3e00/0x3f00 unreachable
3001:	from all fwmark 0x100/0x3f00 unreachable
3002:	from all fwmark 0x200/0x3f00 unreachable
32766:	from all lookup main
32767:	from all lookup default

Output of "ip -4 route list table 1-250"
-------------------------------------------------
Routing table 1:
default via 192.168.20.1 dev eth0.2 proto static src 192.168.20.233 metric 1 
192.168.14.0/24 dev br-lan proto kernel scope link src 192.168.14.1 
192.168.20.0/24 dev eth0.2 proto static scope link metric 1 

Routing table 2:
default via 192.168.15.254 dev br-lan proto static metric 2 
192.168.14.0/24 dev br-lan proto kernel scope link src 192.168.14.1 
192.168.15.0/24 dev br-lan proto static scope link metric 2 

Output of "iptables -t mangle -w -L -v -n"
-------------------------------------------------
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 615K  711M mwan3_hook  all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 6109 1614K mwan3_hook  all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain mwan3_connected_ipv4 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
 406K  599M MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_connected_ipv4 dst MARK or 0x3f00

Chain mwan3_custom_ipv4 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_custom_ipv4 dst MARK or 0x3f00

Chain mwan3_dynamic_ipv4 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_dynamic_ipv4 dst MARK or 0x3f00

Chain mwan3_hook (2 references)
 pkts bytes target     prot opt in     out     source               destination         
 618K  712M CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00 CONNMARK restore mask 0x3f00
 5657 1735K mwan3_ifaces_in  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00
 1740  198K mwan3_custom_ipv4  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00
 1740  198K mwan3_connected_ipv4  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00
 1097 92307 mwan3_dynamic_ipv4  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00
 1097 92307 mwan3_rules  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00
 621K  712M CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK save mask 0x3f00
 490K  603M mwan3_custom_ipv4  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match ! 0x3f00/0x3f00
 490K  603M mwan3_connected_ipv4  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match ! 0x3f00/0x3f00
85258 4771K mwan3_dynamic_ipv4  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match ! 0x3f00/0x3f00

Chain mwan3_iface_in_LWAN (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  br-lan *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_custom_ipv4 src mark match 0x0/0x3f00 /* default */ MARK or 0x3f00
  101  8525 MARK       all  --  br-lan *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_connected_ipv4 src mark match 0x0/0x3f00 /* default */ MARK or 0x3f00
    0     0 MARK       all  --  br-lan *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_dynamic_ipv4 src mark match 0x0/0x3f00 /* default */ MARK or 0x3f00
   42  1680 MARK       all  --  br-lan *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00 /* LWAN */ MARK xset 0x200/0x3f00

Chain mwan3_iface_in_wan (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  eth0.2 *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_custom_ipv4 src mark match 0x0/0x3f00 /* default */ MARK or 0x3f00
 3238 1336K MARK       all  --  eth0.2 *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_connected_ipv4 src mark match 0x0/0x3f00 /* default */ MARK or 0x3f00
    0     0 MARK       all  --  eth0.2 *       0.0.0.0/0            0.0.0.0/0            match-set mwan3_dynamic_ipv4 src mark match 0x0/0x3f00 /* default */ MARK or 0x3f00
  534  190K MARK       all  --  eth0.2 *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00 /* wan */ MARK xset 0x100/0x3f00

Chain mwan3_ifaces_in (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 5420 1696K mwan3_iface_in_LWAN  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00
 5062 1620K mwan3_iface_in_wan  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00

Chain mwan3_policy_wan_LWAN (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0x3f00 /* wan 3 3 */ MARK xset 0x100/0x3f00

Chain mwan3_rules (1 references)
 pkts bytes target     prot opt in     out     source               destination         

I don't think what you want to achieve can be done this way.

You want to use br-lan as an inbound and outbound interface and that breaks mwan3, because everything arriving from br-lan is forwarded directly to routing table 2.

Also, the mwan3 rule is not created. This could be because options src_ip and ipset overlap, or because 1.1.1.1/30 is not valid CIDR notation.