PBR version 1.1.7-59: MAC address based routing policy not doing anything

Hi Forum,

I herewith more or less revisit a problem that I have sought help about before (Failing (again) to get IPv6 working with PBR). To summarise, at the time my trials to have a policy route the traffic generated by my laptop both over IPv4 and IPv6 to a VPN server other than the one that acted as my default gateway, consistently failed. Thanks to the help of @egc I finally got things sorted out, and for some time I was able to let my laptop connect to a different server than my desktops which were not subject to my policy.

Things changed when I updated the pbr and luci-app-pbr packages from version 1.1.1-7 to the next. Now I not only noted the highly erratic behaviour of the policy routing tab under ‘Services' in LuCi that others have reported about as well (on which I’ll come back in a separate thread), I also couldn’t get my policy to work anymore, whatever I tried. I more or less gave up on the pbr package at the time, made the VPN server my laptop is supposed to connect to my default gateway, and sort of called it quits. Thereafter, however, I also began to run into trouble with the sinking ship that was my VPN provider (Perfect Privacy), which finally led me to switch this week to AirVPN. Now again being on a stable VPN, I decided to reinstall pbr and luci-app-pbr again, and see whether I could make things behave like I want.

Unfortunately, I cannot. While assigning a default gateway seems to work, resulting in traffic generated by both my desktops being routed through the chosen server (both over IPv4 and IPv6), the policy that I created based on the MAC address of my laptop, and which is meant to route the latter’s traffic through a different server, simply doesn’t do anything; traffic from my laptop also consistently runs through my default gateway (both over IPv4 and IPv6, that is).

Please note that even while this screenshot shows pbr is running in 'fw4 nft file mode', in /etc/config/pbr the option enabled consistently shows as set to '0' (for which see the contents of this file at the end), which may well be the result of the erratic behaviour of the UI of luci-app-pbr package as referred to above. Setting it manually to '1' in Terminal doesn't solve my problem, however.

As per the advice of @egc, given in thread 204457, I amended AirVPN’s OpenVPN configuration script for what is meant to be my default gateway (‘the Netherlands’) with the following lines:

  • redirect-gateway def1
  • redirect-gateway ipv6
  • server-poll-timeout 10

whereas the following lines were added to AirVPN’s OpenVPN configuration scripts of all other VPN servers, and hence the server (‘Sweden’) traffic from my laptop is meant being routed through:

  • pull-filter ignore “redirect-gateway"
  • pull-filter ignore "redirect-gateway ipv6”

Like said, while still on pbr version 1.1.1-7 this configuration worked, but now, while on version 1.1.7-59, it doesn’t. I haven’t got a clue as to why, and I am therefore warmly welcoming any suggestions that could help me to make my routing policy work .

To enable you to analyse my current setup, the following output. In case any additional information is needed, feel free to let me know.

ubus call system board
root@OpenWrt:~# ubus call system board

{
	"kernel": "5.15.167",
	"hostname": "OpenWrt",
	"system": "Intel(R) Celeron(R) J6412 @ 2.00GHz",
	"model": "Protectli VP2420",
	"board_name": "protectli-vp2420",
	"rootfs_type": "ext4",
	"release": {
		"distribution": "OpenWrt",
		"version": "23.05.5",
		"revision": "r24106-10cc5fcd00",
		"target": "x86/64",
		"description": "OpenWrt 23.05.5 r24106-10cc5fcd00"
	}
}
root@OpenWrt:~#
cat /etc/config/network
root@OpenWrt:~#  cat /etc/config/network

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

config globals 'globals'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ip6assign '60'
	option broadcast ‘redacted.255'
	list ipaddr 'redacted.1/24'
	list dns '45.90.28.234'
	list dns '45.90.30.234'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'
	option peerdns '0'
	list dns '45.90.28.234'
	list dns '45.90.30.234'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'
	option reqaddress 'try'
	option reqprefix 'auto'
	option peerdns '0'
	list dns '2a07:a8c0::49:2c58'
	list dns '2a07:a8c1::49:2c58'

config device
	option name 'tun0'

config device
	option name 'eth0'

config interface 'vpnclient0'
	option proto 'none'
	option device 'vpn_belgium'

config interface 'vpnclient1'
	option proto 'none'
	option device 'vpn_germany'

config interface 'vpnclient2'
	option proto 'none'
	option device 'vpn_netherlands'

config interface 'vpnclient3'
	option proto 'none'
	option device 'vpn_norway'

config interface 'vpnclient4'
	option proto 'none'
	option device 'vpn_sweden'

root@OpenWrt:~#
cat /etc/config/dhcp
root@OpenWrt:~# cat /etc/config/dhcp

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option cachesize '1000'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option localservice '1'
	option ednspacket_max '1232'
	list dhcp_option '6,45.90.28.234,45.90.30.234'
	list server '127.0.0.1#5054'
	list server '/mask.icloud.com/'
	list server '/mask-h2.icloud.com/'
	list server '/use-application-dns.net/'
	list server '127.0.0.1#5053'
	option resolvfile '/tmp/resolv.conf.vpn'
	option doh_backup_noresolv '-1'
	option noresolv '1'
	list doh_backup_server '127.0.0.1#5054'
	list doh_backup_server '/mask.icloud.com/'
	list doh_backup_server '/mask-h2.icloud.com/'
	list doh_backup_server '/use-application-dns.net/'
	list doh_backup_server '127.0.0.1#5053'
	list doh_server '127.0.0.1#5053'

config dhcp 'lan'
	option interface 'lan'
	option start '2'
	option limit '49'
	option leasetime '2m'
	option dhcpv4 'server'
	option dhcpv6 'server'
	option ra 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option preferred_lifetime '12h'
	option force '1'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'
	option preferred_lifetime '12h'

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

config host
	option name 'MacBook-Pro-M3'
	option ip ‘redacted.2’
	list mac 'redacted'
	option leasetime 'infinite'
	option duid 'redacted'

config host
	option name 'Mac-Mini-M1'
	option ip 'redacted.15'
	option duid 'redacted'
	list tag 'Mac'
	list mac 'redacted'
	option leasetime 'infinite'

config host
	option name 'Mac-Studio-M1-Max'
	option ip 'redacted.29'
	option duid 'redacted'
	list mac 'redacted'
	list tag 'Mac'

config host
	option ip 'redacted.42'
	option name 'iPhone-13-mini'
	list mac 'redacted'
	option duid 'redacted'
	list tag 'iPhone'

config host
	option ip 'redacted.23'
	option name 'MikroTik-CRS305-1G-4'
	list mac 'redacted'
	list tag 'Switch'

config host
	option name 'QNAP-QSW-M408-4C'
	option ip 'redacted.16'
	list mac 'redacted'
	list tag 'Switch'

config host
	option name 'QNAP-TS453DU-NAS'
	option ip 'redacted.19'
	list tag 'NAS'
	list mac 'redacted'
	option leasetime 'infinite'

config host
	option name 'Fitlet2-NAA'
	option ip 'redacted.47'
	list tag 'NAA'
	list mac 'redacted'
	option duid 'redacted'

config host
	option name 'Apple-Airport-Time-Capsule'
	option ip 'redacted.44'
	option duid 'redacted'
	list mac 'redacted'
	list tag 'Airport'

config host
	option duid 'redacted'
	option mac 'redacted'

root@OpenWrt:~#
cat /etc/config/firewall
root@OpenWrt:~# cat /etc/config/firewall

config defaults
	option input 'REJECT'
	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'

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

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 zone
	option name 'vpn_fw'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option masq6 '1'
	option mtu_fix '1'
	list network 'vpnclient0'
	list network 'vpnclient1'
	list network 'vpnclient2'
	list network 'vpnclient3'
	list network 'vpnclient4'

config forwarding
	option src 'lan'
	option dest 'vpn_fw'

config include 'pbr'
	option fw4_compatible '1'
	option type 'script'
	option path '/usr/share/pbr/firewall.include'

root@OpenWrt:~#
cat /etc/config/pbr
root@OpenWrt:~# cat /etc/config/pbr

config pbr 'config'
	option enabled '0'
	option verbosity '2'
	option strict_enforcement '1'
	option resolver_set 'dnsmasq.nftset'
	list resolver_instance '*'
	option ipv6_enabled '1'
	list ignored_interface 'vpnserver'
	option boot_timeout '30'
	option rule_create_option 'add'
	option procd_boot_delay '0'
	option procd_reload_delay '1'
	option webui_show_ignore_target '0'
	option nft_rule_counter '0'
	option nft_set_auto_merge '1'
	option nft_set_counter '0'
	option nft_set_flags_interval '1'
	option nft_set_flags_timeout '0'
	option nft_set_policy 'performance'
	list webui_supported_protocol 'all'
	list webui_supported_protocol 'tcp'
	list webui_supported_protocol 'udp'
	list webui_supported_protocol 'tcp udp'
	list webui_supported_protocol 'icmp'
	list supported_interface 'vpn_belgium vpn_germany vpn_netherlands vpn_norway vpn_sweden'

config policy
	option name 'MacBook Pro M3'
	option src_addr ‘redacted'
	option interface 'vpnclient4'

root@OpenWrt:~#
opkg list-installed
root@OpenWrt:~# opkg list-installed
ath10k-firmware-qca6174 - 20230804-1
attendedsysupgrade-common - 8
auc - 0.3.2-1
base-files - 1562-r24106-10cc5fcd00
bnx2-firmware - 20230804-1
busybox - 1.36.1-1
ca-bundle - 20230311-1
cgi-io - 2022-08-10-901b0f04-21
dnsmasq-full - 2.90-2
dropbear - 2022.82-6
e2fsprogs - 1.47.0-2
firewall4 - 2023-09-01-598d9fbb-1
fstools - 2023-02-28-bfe882d5-1
fwtool - 2019-11-12-8f7fe925-1
getrandom - 2022-08-13-4c7b720b-2
grub2 - 2.06-5
grub2-bios-setup - 2.06-5
grub2-efi - 2.06-5
hostapd-common - 2023-09-08-e5ccbfc6-8
https-dns-proxy - 2023.12.26-1
ip-full - 6.3.0-1
ipset - 7.17-1
iw - 5.19-1
iwinfo - 2023-07-01-ca79f641-1
jansson4 - 2.14-3
jshn - 2023-05-23-75a3b870-1
jsonfilter - 2024-01-23-594cfa86-1
kernel - 5.15.167-1-59d1431675acc6823a33c7eb2323daeb
kmod-amazon-ena - 5.15.167-1
kmod-amd-xgbe - 5.15.167-1
kmod-ath - 5.15.167+6.1.110-1-1
kmod-ath10k - 5.15.167+6.1.110-1-1
kmod-bnx2 - 5.15.167-1
kmod-button-hotplug - 5.15.167-3
kmod-cfg80211 - 5.15.167+6.1.110-1-1
kmod-crypto-acompress - 5.15.167-1
kmod-crypto-aead - 5.15.167-1
kmod-crypto-ccm - 5.15.167-1
kmod-crypto-cmac - 5.15.167-1
kmod-crypto-crc32c - 5.15.167-1
kmod-crypto-ctr - 5.15.167-1
kmod-crypto-gcm - 5.15.167-1
kmod-crypto-gf128 - 5.15.167-1
kmod-crypto-ghash - 5.15.167-1
kmod-crypto-hash - 5.15.167-1
kmod-crypto-hmac - 5.15.167-1
kmod-crypto-manager - 5.15.167-1
kmod-crypto-null - 5.15.167-1
kmod-crypto-rng - 5.15.167-1
kmod-crypto-seqiv - 5.15.167-1
kmod-crypto-sha512 - 5.15.167-1
kmod-e1000 - 5.15.167-1
kmod-e1000e - 5.15.167-1
kmod-forcedeth - 5.15.167-1
kmod-fs-vfat - 5.15.167-1
kmod-hwmon-core - 5.15.167-1
kmod-i2c-algo-bit - 5.15.167-1
kmod-i2c-core - 5.15.167-1
kmod-igb - 5.15.167-1
kmod-igc - 5.15.167-1
kmod-input-core - 5.15.167-1
kmod-ip6tables - 5.15.167-1
kmod-ipt-conntrack - 5.15.167-1
kmod-ipt-core - 5.15.167-1
kmod-ipt-ipset - 5.15.167-1
kmod-ipt-nat - 5.15.167-1
kmod-ipt-nat6 - 5.15.167-1
kmod-ixgbe - 5.15.167-1
kmod-lib-crc-ccitt - 5.15.167-1
kmod-lib-crc32c - 5.15.167-1
kmod-lib-lzo - 5.15.167-1
kmod-libphy - 5.15.167-1
kmod-mac80211 - 5.15.167+6.1.110-1-1
kmod-mdio - 5.15.167-1
kmod-mdio-devres - 5.15.167-1
kmod-mii - 5.15.167-1
kmod-nf-conntrack - 5.15.167-1
kmod-nf-conntrack-netlink - 5.15.167-1
kmod-nf-conntrack6 - 5.15.167-1
kmod-nf-flow - 5.15.167-1
kmod-nf-ipt - 5.15.167-1
kmod-nf-ipt6 - 5.15.167-1
kmod-nf-log - 5.15.167-1
kmod-nf-log6 - 5.15.167-1
kmod-nf-nat - 5.15.167-1
kmod-nf-nat6 - 5.15.167-1
kmod-nf-reject - 5.15.167-1
kmod-nf-reject6 - 5.15.167-1
kmod-nfnetlink - 5.15.167-1
kmod-nft-core - 5.15.167-1
kmod-nft-fib - 5.15.167-1
kmod-nft-nat - 5.15.167-1
kmod-nft-offload - 5.15.167-1
kmod-nls-base - 5.15.167-1
kmod-nls-cp437 - 5.15.167-1
kmod-nls-iso8859-1 - 5.15.167-1
kmod-nls-utf8 - 5.15.167-1
kmod-phy-realtek - 5.15.167-1
kmod-ppp - 5.15.167-1
kmod-pppoe - 5.15.167-1
kmod-pppox - 5.15.167-1
kmod-pps - 5.15.167-1
kmod-ptp - 5.15.167-1
kmod-r8169 - 5.15.167-1
kmod-slhc - 5.15.167-1
kmod-tg3 - 5.15.167-1
kmod-tun - 5.15.167-1
libblkid1 - 2.39-2
libblobmsg-json20230523 - 2023-05-23-75a3b870-1
libbpf1 - 1.2.2-1
libc - 1.2.4-4
libcares - 1.27.0-1
libcomerr0 - 1.47.0-2
libcurl4 - 8.7.1-r1
libelf1 - 0.189-1
libev - 4.33-2
libext2fs2 - 1.47.0-2
libf2fs6 - 1.16.0-1
libgcc1 - 12.3.0-4
libgmp10 - 6.2.1-1
libipset13 - 7.17-1
libiwinfo-data - 2023-07-01-ca79f641-1
libiwinfo20230701 - 2023-07-01-ca79f641-1
libjson-c5 - 0.16-3
libjson-script20230523 - 2023-05-23-75a3b870-1
liblua5.1.5 - 5.1.5-11
liblucihttp-lua - 2023-03-15-9b5b683f-1
liblucihttp-ucode - 2023-03-15-9b5b683f-1
liblucihttp0 - 2023-03-15-9b5b683f-1
liblzo2 - 2.10-4
libmbedtls12 - 2.28.9-1
libmnl0 - 1.0.5-1
libncurses6 - 6.4-2
libnetfilter-conntrack3 - 1.0.9-2
libnettle8 - 3.9.1-1
libnfnetlink0 - 1.0.2-1
libnftnl11 - 1.2.6-1
libnghttp2-14 - 1.57.0-1
libnl-tiny1 - 2023-07-27-bc92a280-1
libopenssl3 - 3.0.15-1
libpcre2 - 10.42-1
libpthread - 1.2.4-4
librt - 1.2.4-4
libsmartcols1 - 2.39-2
libss2 - 1.47.0-2
libubox20230523 - 2023-05-23-75a3b870-1
libubus-lua - 2023-06-05-f787c97b-1
libubus20230605 - 2023-06-05-f787c97b-1
libuci20130104 - 2023-08-10-5781664d-1
libuclient20201210 - 2023-04-13-007d9454-1
libucode20230711 - 2024-07-11-1a8a0bcf-3
libustream-mbedtls20201210 - 2023-02-25-498f6e26-1
libuuid1 - 2.39-2
logd - 2022-08-13-4c7b720b-2
lua - 5.1.5-11
luci - git-24.322.79771-ee4c08d
luci-app-attendedsysupgrade - git-24.322.79771-ee4c08d
luci-app-firewall - git-24.322.79771-ee4c08d
luci-app-https-dns-proxy - 2023.12.26-1
luci-app-openvpn - git-24.322.79771-ee4c08d
luci-app-opkg - git-24.322.79771-ee4c08d
luci-app-pbr - 1.1.7-59
luci-base - git-24.322.79771-ee4c08d
luci-compat - git-24.322.79771-ee4c08d
luci-lib-base - git-24.322.79771-ee4c08d
luci-lib-ip - git-24.322.79771-ee4c08d
luci-lib-jsonc - git-24.322.79771-ee4c08d
luci-lib-nixio - git-24.322.79771-ee4c08d
luci-light - git-24.322.79771-ee4c08d
luci-lua-runtime - git-24.322.79771-ee4c08d
luci-mod-admin-full - git-24.322.79771-ee4c08d
luci-mod-network - git-24.322.79771-ee4c08d
luci-mod-status - git-24.322.79771-ee4c08d
luci-mod-system - git-24.322.79771-ee4c08d
luci-proto-ipv6 - git-24.322.79771-ee4c08d
luci-proto-ppp - git-24.322.79771-ee4c08d
luci-ssl - git-24.322.79771-ee4c08d
luci-theme-bootstrap - git-24.322.79771-ee4c08d
mkf2fs - 1.16.0-1
mtd - 26
nano-full - 8.2-1
netifd - 2024-01-04-c18cc79d-2
nftables-json - 1.0.8-1
odhcp6c - 2023-05-12-bcd28363-20
odhcpd-ipv6only - 2023-10-24-d8118f6e-1
openvpn-openssl - 2.5.8-5
openwrt-keyring - 2022-03-25-62471e69-2
opkg - 2022-02-24-d038e5b6-2
partx-utils - 2.39-2
pbr - 1.1.7-59
ppp - 2.4.9.git-2021-01-04-4
ppp-mod-pppoe - 2.4.9.git-2021-01-04-4
procd - 2023-06-25-2db83655-2
procd-seccomp - 2023-06-25-2db83655-2
procd-ujail - 2023-06-25-2db83655-2
px5g-mbedtls - 10
r8169-firmware - 20230804-1
resolveip - 2
rpcd - 2023-07-01-c07ab2f9-1
rpcd-mod-file - 2023-07-01-c07ab2f9-1
rpcd-mod-iwinfo - 2023-07-01-c07ab2f9-1
rpcd-mod-luci - 20240305-1
rpcd-mod-rpcsys - 2023-07-01-c07ab2f9-1
rpcd-mod-rrdns - 20170710
rpcd-mod-ucode - 2023-07-01-c07ab2f9-1
terminfo - 6.4-2
ubox - 2022-08-13-4c7b720b-2
ubus - 2023-06-05-f787c97b-1
ubusd - 2023-06-05-f787c97b-1
uci - 2023-08-10-5781664d-1
uclient-fetch - 2023-04-13-007d9454-1
ucode - 2024-07-11-1a8a0bcf-3
ucode-mod-fs - 2024-07-11-1a8a0bcf-3
ucode-mod-html - 1
ucode-mod-lua - 1
ucode-mod-math - 2024-07-11-1a8a0bcf-3
ucode-mod-nl80211 - 2024-07-11-1a8a0bcf-3
ucode-mod-rtnl - 2024-07-11-1a8a0bcf-3
ucode-mod-ubus - 2024-07-11-1a8a0bcf-3
ucode-mod-uci - 2024-07-11-1a8a0bcf-3
ucode-mod-uloop - 2024-07-11-1a8a0bcf-3
uhttpd - 2023-06-25-34a8a74d-2
uhttpd-mod-ubus - 2023-06-25-34a8a74d-2
urandom-seed - 3
urngd - 2023-11-01-44365eb1-1
usign - 2020-05-23-f1f65026-1
wget-ssl - 1.21.4-1
wireless-regdb - 2024.10.07-1
wpad-mini - 2023-09-08-e5ccbfc6-8
zlib - 1.2.13-1
root@OpenWrt:~#

You should not Masquerade IPv6 on the WAN zone, only on VPN zone, so disable option masq6.

However that should not be your problem.

I have 1.1.7-59 running with IPv6 both WireGuard and OpenVPN and that works without a problem so it should be possible.

Please also post:

ip route show
ip route show table all
ip rule show
nft list ruleset
/etc/init.d/pbr status
cat /var/run/pbr.nft

Will have a look tomorrow

Check that MacBook Pro M3 has the designated IP address and is using the MAC address you think it should use, most clients nowadays have random MAC addresses

Thank you @egc for your first quick glance into my problem. In reply to this, the following.

As per your advice, I uncheckedf IPv6 masquerading for the WAN zone, but as you already suggested, this didn't change anything.

The MAC address of my MacBook M3 my routing policy is based upon is a fixed one, which also holds true for its IP address, so this is shouldn't be the reason my policy doesn't work. When it still worked earlier this year, my policy rule was exactly the same and based upon the same MAC address.

As to the additional information you requested, please see below. My sincere thanks in advance for looking into this.

ip route show
root@OpenWrt:~# ip route show
0.0.0.0/1 via 10.23.102.1 dev vpn_netherlands 
default via 192.168.188.1 dev eth1 proto static src 192.168.188.54 
10.12.54.0/24 dev vpn_norway proto kernel scope link src 10.12.54.59 
10.12.182.0/24 dev vpn_belgium proto kernel scope link src 10.12.182.74 
10.21.6.0/24 dev vpn_sweden proto kernel scope link src 10.21.6.112 
10.23.102.0/24 dev vpn_netherlands proto kernel scope link src 10.23.102.188 
10.26.22.0/24 dev vpn_germany proto kernel scope link src 10.26.22.139 
redacted.0/24 dev br-lan proto kernel scope link src redacted.1 
128.0.0.0/1 via 10.23.102.1 dev vpn_netherlands 
192.168.188.0/24 dev eth1 proto kernel scope link src 192.168.188.54 
213.152.187.237 via 192.168.188.1 dev eth1 
root@OpenWrt:~#
ip route show table all
root@OpenWrt:~# ip route show table all
0.0.0.0/1 via 10.23.102.1 dev vpn_netherlands 
default via 192.168.188.1 dev eth1 proto static src 192.168.188.54 
10.12.54.0/24 dev vpn_norway proto kernel scope link src 10.12.54.59 
10.12.182.0/24 dev vpn_belgium proto kernel scope link src 10.12.182.74 
10.21.6.0/24 dev vpn_sweden proto kernel scope link src 10.21.6.112 
10.23.102.0/24 dev vpn_netherlands proto kernel scope link src 10.23.102.188 
10.26.22.0/24 dev vpn_germany proto kernel scope link src 10.26.22.139 
redacted.0/24 dev br-lan proto kernel scope link src redacted.1 
128.0.0.0/1 via 10.23.102.1 dev vpn_netherlands 
192.168.188.0/24 dev eth1 proto kernel scope link src 192.168.188.54 
213.152.187.237 via 192.168.188.1 dev eth1 
local 10.12.54.59 dev vpn_norway table local proto kernel scope host src 10.12.54.59 
broadcast 10.12.54.255 dev vpn_norway table local proto kernel scope link src 10.12.54.59 
local 10.12.182.74 dev vpn_belgium table local proto kernel scope host src 10.12.182.74 
broadcast 10.12.182.255 dev vpn_belgium table local proto kernel scope link src 10.12.182.74 
local 10.21.6.112 dev vpn_sweden table local proto kernel scope host src 10.21.6.112 
broadcast 10.21.6.255 dev vpn_sweden table local proto kernel scope link src 10.21.6.112 
local 10.23.102.188 dev vpn_netherlands table local proto kernel scope host src 10.23.102.188 
broadcast 10.23.102.255 dev vpn_netherlands table local proto kernel scope link src 10.23.102.188 
local 10.26.22.139 dev vpn_germany table local proto kernel scope host src 10.26.22.139 
broadcast 10.26.22.255 dev vpn_germany table local proto kernel scope link src 10.26.22.139 
local redacted.1 dev br-lan table local proto kernel scope host src redacted.1 
broadcast redacted.255 dev br-lan table local proto kernel scope link src redacted.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.188.54 dev eth1 table local proto kernel scope host src 192.168.188.54 
broadcast 192.168.188.255 dev eth1 table local proto kernel scope link src 192.168.188.54 
default from 2a02:a464:c5d0:1:6662:66ff:fe22:d598 via fe80::2e91:abff:fe45:f3b5 dev eth1 proto static metric 384 pref medium
default from 2a02:a464:c5d0:fc::/62 via fe80::2e91:abff:fe45:f3b5 dev eth1 proto static metric 384 pref medium
::/3 dev vpn_netherlands metric 1024 pref medium
2a02:a464:c5d0::/48 from 2a02:a464:c5d0:1:6662:66ff:fe22:d598 via fe80::2e91:abff:fe45:f3b5 dev eth1 proto static metric 384 pref medium
2a02:a464:c5d0::/48 from 2a02:a464:c5d0:fc::/62 via fe80::2e91:abff:fe45:f3b5 dev eth1 proto static metric 384 pref medium
2a02:a464:c5d0:1::/64 dev eth1 proto static metric 256 pref medium
2a02:a464:c5d0:fc::/64 dev br-lan proto static metric 1024 pref medium
2a02:a464:c5d0:fe::/63 via fe80::201:c0ff:fe2b:de0f dev br-lan proto static metric 1024 pref medium
unreachable 2a02:a464:c5d0:fc::/62 dev lo proto static metric 2147483647 pref medium
2000::/4 dev vpn_netherlands metric 1024 pref medium
3000::/4 dev vpn_netherlands metric 1024 pref medium
fde6:7a:7d20:836::/64 dev vpn_norway proto kernel metric 256 pref medium
fde6:7a:7d20:8b6::/64 dev vpn_belgium proto kernel metric 256 pref medium
fde6:7a:7d20:1106::/64 dev vpn_sweden proto kernel metric 256 pref medium
fde6:7a:7d20:1366::/64 dev vpn_netherlands proto kernel metric 256 pref medium
fde6:7a:7d20:1616::/64 dev vpn_germany proto kernel metric 256 pref medium
fc00::/7 dev vpn_netherlands metric 1024 pref medium
fe80::/64 dev phy0-ap0 proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
fe80::/64 dev vpn_netherlands proto kernel metric 256 pref medium
fe80::/64 dev vpn_sweden proto kernel metric 256 pref medium
fe80::/64 dev vpn_germany proto kernel metric 256 pref medium
fe80::/64 dev vpn_norway proto kernel metric 256 pref medium
fe80::/64 dev vpn_belgium proto kernel metric 256 pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
local 2a02:a464:c5d0:1:6662:66ff:fe22:d598 dev eth1 table local proto kernel metric 0 pref medium
anycast 2a02:a464:c5d0:fc:: dev br-lan table local proto kernel metric 0 pref medium
local 2a02:a464:c5d0:fc::1 dev br-lan table local proto kernel metric 0 pref medium
anycast fde6:7a:7d20:836:: dev vpn_norway table local proto kernel metric 0 pref medium
local fde6:7a:7d20:836::1039 dev vpn_norway table local proto kernel metric 0 pref medium
anycast fde6:7a:7d20:8b6:: dev vpn_belgium table local proto kernel metric 0 pref medium
local fde6:7a:7d20:8b6::1048 dev vpn_belgium table local proto kernel metric 0 pref medium
anycast fde6:7a:7d20:1106:: dev vpn_sweden table local proto kernel metric 0 pref medium
local fde6:7a:7d20:1106::106e dev vpn_sweden table local proto kernel metric 0 pref medium
anycast fde6:7a:7d20:1366:: dev vpn_netherlands table local proto kernel metric 0 pref medium
local fde6:7a:7d20:1366::10ba dev vpn_netherlands table local proto kernel metric 0 pref medium
anycast fde6:7a:7d20:1616:: dev vpn_germany table local proto kernel metric 0 pref medium
local fde6:7a:7d20:1616::1089 dev vpn_germany table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan table local proto kernel metric 0 pref medium
anycast fe80:: dev phy0-ap0 table local proto kernel metric 0 pref medium
anycast fe80:: dev vpn_netherlands table local proto kernel metric 0 pref medium
anycast fe80:: dev vpn_sweden table local proto kernel metric 0 pref medium
anycast fe80:: dev eth1 table local proto kernel metric 0 pref medium
anycast fe80:: dev vpn_germany table local proto kernel metric 0 pref medium
anycast fe80:: dev vpn_norway table local proto kernel metric 0 pref medium
anycast fe80:: dev vpn_belgium table local proto kernel metric 0 pref medium
local fe80::215:61ff:fe23:d3ac dev phy0-ap0 table local proto kernel metric 0 pref medium
local fe80::12e8:98b8:761b:1677 dev vpn_sweden table local proto kernel metric 0 pref medium
local fe80::40db:d62c:6db4:da95 dev vpn_netherlands table local proto kernel metric 0 pref medium
local fe80::6662:66ff:fe22:d597 dev br-lan table local proto kernel metric 0 pref medium
local fe80::6662:66ff:fe22:d598 dev eth1 table local proto kernel metric 0 pref medium
local fe80::930f:ff6c:bca3:11d9 dev vpn_norway table local proto kernel metric 0 pref medium
local fe80::b181:669a:fca0:bcb9 dev vpn_belgium table local proto kernel metric 0 pref medium
local fe80::fa7f:80b2:e281:b1b3 dev vpn_germany table local proto kernel metric 0 pref medium
multicast ff00::/8 dev phy0-ap0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev br-lan table local proto kernel metric 256 pref medium
multicast ff00::/8 dev eth1 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev vpn_netherlands table local proto kernel metric 256 pref medium
multicast ff00::/8 dev vpn_sweden table local proto kernel metric 256 pref medium
multicast ff00::/8 dev vpn_germany table local proto kernel metric 256 pref medium
multicast ff00::/8 dev vpn_norway table local proto kernel metric 256 pref medium
multicast ff00::/8 dev vpn_belgium table local proto kernel metric 256 pref medium
root@OpenWrt:~#
ip rule show
root@OpenWrt:~# ip rule show
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default
root@OpenWrt:~#
nft list ruleset
root@OpenWrt:~# nft list ruleset
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" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "eth1" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
		iifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } jump input_vpn_fw comment "!fw4: Handle vpn_fw IPv4/IPv6 input traffic"
		jump handle_reject
	}

	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" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "eth1" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		iifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } jump forward_vpn_fw comment "!fw4: Handle vpn_fw 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" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "eth1" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
		oifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } jump output_vpn_fw comment "!fw4: Handle vpn_fw IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname "br-lan" jump helper_lan comment "!fw4: Handle lan 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 {
		tcp dport 853 counter packets 24 bytes 1536 jump handle_reject comment "!fw4: ubus:https-dns-proxy[instance1] rule 1"
		udp dport 853 counter packets 0 bytes 0 jump handle_reject comment "!fw4: ubus:https-dns-proxy[instance1] rule 1"
		jump accept_to_vpn_fw comment "!fw4: Accept lan to vpn_fw forwarding"
		ct status dnat accept comment "!fw4: Accept port forwards"
		jump accept_to_lan
	}

	chain helper_lan {
	}

	chain accept_from_lan {
		iifname "br-lan" counter packets 7384 bytes 759600 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain accept_to_lan {
		oifname "br-lan" counter packets 3974 bytes 402036 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 89 bytes 3204 accept comment "!fw4: Allow-IGMP"
		meta nfproto ipv6 udp dport 546 counter packets 6 bytes 1524 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 23 bytes 3864 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 12 bytes 816 accept comment "!fw4: Allow-ICMPv6-Input"
		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"
		jump reject_to_wan
	}

	chain accept_to_wan {
		oifname "eth1" ct state invalid counter packets 0 bytes 0 drop comment "!fw4: Prevent NAT leakage"
		oifname "eth1" counter packets 66 bytes 6474 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain reject_from_wan {
		iifname "eth1" counter packets 36 bytes 1944 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

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

	chain input_vpn_fw {
		jump reject_from_vpn_fw
	}

	chain output_vpn_fw {
		jump accept_to_vpn_fw
	}

	chain forward_vpn_fw {
		jump reject_to_vpn_fw
	}

	chain accept_to_vpn_fw {
		oifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } ct state invalid counter packets 60 bytes 4605 drop comment "!fw4: Prevent NAT leakage"
		oifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } counter packets 3829 bytes 252951 accept comment "!fw4: accept vpn_fw IPv4/IPv6 traffic"
	}

	chain reject_from_vpn_fw {
		iifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } counter packets 1 bytes 60 jump handle_reject comment "!fw4: reject vpn_fw IPv4/IPv6 traffic"
	}

	chain reject_to_vpn_fw {
		oifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject vpn_fw IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
		iifname "br-lan" jump dstnat_lan comment "!fw4: Handle lan IPv4/IPv6 dstnat traffic"
		jump pbr_dstnat comment "Jump into pbr dstnat chain"
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "eth1" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
		oifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } jump srcnat_vpn_fw comment "!fw4: Handle vpn_fw IPv4/IPv6 srcnat traffic"
	}

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

	chain srcnat_vpn_fw {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 vpn_fw traffic"
		meta nfproto ipv6 masquerade comment "!fw4: Masquerade IPv6 vpn_fw 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;
		jump pbr_prerouting comment "Jump into pbr prerouting chain"
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
		jump pbr_postrouting comment "Jump into pbr postrouting chain"
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
		jump pbr_input comment "Jump into pbr input chain"
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
		jump pbr_output comment "Jump into pbr output chain"
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "eth1" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname "eth1" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
		iifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone vpn_fw IPv4/IPv6 ingress MTU fixing"
		oifname { "vpn_sweden", "vpn_norway", "vpn_belgium", "vpn_germany", "vpn_netherlands" } tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone vpn_fw IPv4/IPv6 egress MTU fixing"
		jump pbr_forward comment "Jump into pbr forward chain"
	}

	chain pbr_dstnat {
	}

	chain pbr_forward {
	}

	chain pbr_input {
	}

	chain pbr_output {
	}

	chain pbr_prerouting {
		ether saddr redacted goto pbr_mark_0x060000 comment "MacBook Pro M3"
	}

	chain pbr_postrouting {
	}

	chain pbr_mark_0x010000 {
		meta mark set meta mark & 0xff01ffff | 0x00010000
		return
	}

	chain pbr_mark_0x020000 {
		meta mark set meta mark & 0xff02ffff | 0x00020000
		return
	}

	chain pbr_mark_0x030000 {
		meta mark set meta mark & 0xff03ffff | 0x00030000
		return
	}

	chain pbr_mark_0x040000 {
		meta mark set meta mark & 0xff04ffff | 0x00040000
		return
	}

	chain pbr_mark_0x050000 {
		meta mark set meta mark & 0xff05ffff | 0x00050000
		return
	}

	chain pbr_mark_0x060000 {
		meta mark set meta mark & 0xff06ffff | 0x00060000
		return
	}

	chain dstnat_lan {
		tcp dport 53 counter packets 0 bytes 0 redirect to :53 comment "!fw4: ubus:https-dns-proxy[instance1] redirect 0"
		udp dport 53 counter packets 3408 bytes 301288 redirect to :53 comment "!fw4: ubus:https-dns-proxy[instance1] redirect 0"
	}
}
root@OpenWrt:~#
/etc/init.d/pbr status
root@OpenWrt:~# /etc/init.d/pbr status

pbr - environment
pbr 1.1.7-59 running on OpenWrt 23.05.5.

Dnsmasq version 2.90  Copyright (c) 2000-2024 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack no-ipset nftset auth cryptohash DNSSEC no-ID loop-detect inotify dumpfile

pbr fw4 nft file: /usr/share/nftables.d/ruleset-post/30-pbr.nft
add chain inet fw4 pbr_mark_0x010000
add rule inet fw4 pbr_mark_0x010000  mark set mark and 0xff00ffff xor 0x010000
add rule inet fw4 pbr_mark_0x010000 return
add chain inet fw4 pbr_mark_0x020000
add rule inet fw4 pbr_mark_0x020000  mark set mark and 0xff00ffff xor 0x020000
add rule inet fw4 pbr_mark_0x020000 return
add chain inet fw4 pbr_mark_0x030000
add rule inet fw4 pbr_mark_0x030000  mark set mark and 0xff00ffff xor 0x030000
add rule inet fw4 pbr_mark_0x030000 return
add chain inet fw4 pbr_mark_0x040000
add rule inet fw4 pbr_mark_0x040000  mark set mark and 0xff00ffff xor 0x040000
add rule inet fw4 pbr_mark_0x040000 return
add chain inet fw4 pbr_mark_0x050000
add rule inet fw4 pbr_mark_0x050000  mark set mark and 0xff00ffff xor 0x050000
add rule inet fw4 pbr_mark_0x050000 return
add chain inet fw4 pbr_mark_0x060000
add rule inet fw4 pbr_mark_0x060000  mark set mark and 0xff00ffff xor 0x060000
add rule inet fw4 pbr_mark_0x060000 return
add rule inet fw4 pbr_prerouting ether saddr { redacted }  goto pbr_mark_0x060000 comment "MacBook Pro M3"

pbr chains - policies
	chain pbr_forward { # handle 37
	}
	chain pbr_input { # handle 38
	}
	chain pbr_output { # handle 39
	}
	chain pbr_postrouting { # handle 41
	}
	chain pbr_prerouting { # handle 40
		ether saddr redacted goto pbr_mark_0x060000 comment "MacBook Pro M3" # handle 1454
	}
	chain pbr_dstnat { # handle 36
	}

pbr chains - marking
	chain pbr_mark_0x010000 { # handle 90
		meta mark set meta mark & 0xff01ffff | 0x00010000 # handle 1442
		return # handle 1443
	}
	chain pbr_mark_0x020000 { # handle 93
		meta mark set meta mark & 0xff02ffff | 0x00020000 # handle 1444
		return # handle 1445
	}
	chain pbr_mark_0x030000 { # handle 96
		meta mark set meta mark & 0xff03ffff | 0x00030000 # handle 1446
		return # handle 1447
	}
	chain pbr_mark_0x040000 { # handle 99
		meta mark set meta mark & 0xff04ffff | 0x00040000 # handle 1448
		return # handle 1449
	}
	chain pbr_mark_0x050000 { # handle 102
		meta mark set meta mark & 0xff05ffff | 0x00050000 # handle 1450
		return # handle 1451
	}
	chain pbr_mark_0x060000 { # handle 105
		meta mark set meta mark & 0xff06ffff | 0x00060000 # handle 1452
		return # handle 1453
	}

pbr nft sets

Error: ipv4: FIB table does not exist.
Dump terminated
IPv4 table 256 route: 
IPv4 table 256 rule(s):
Error: ipv4: FIB table does not exist.
Dump terminated
IPv4 table 257 route: 
IPv4 table 257 rule(s):
Error: ipv4: FIB table does not exist.
Dump terminated
IPv4 table 258 route: 
IPv4 table 258 rule(s):
Error: ipv4: FIB table does not exist.
Dump terminated
IPv4 table 259 route: 
IPv4 table 259 rule(s):
Error: ipv4: FIB table does not exist.
Dump terminated
IPv4 table 260 route: 
IPv4 table 260 rule(s):
Error: ipv4: FIB table does not exist.
Dump terminated
IPv4 table 261 route: 
IPv4 table 261 rule(s):
root@OpenWrt:~#
cat /var/run/pbr.nft
root@OpenWrt:~# cat /var/run/pbr.nft
cat: can't open '/var/run/pbr.nft': No such file or directory
root@OpenWrt:~#

First some small other things which are also not related:
You probably can/should remove:

Furthermore you are using vpn_xxxx as device names for the tun interface, that should not cause trouble here but is not recommended, not all OS's can deal with this better is to use tun-xxxx, also as PBR will check for tun if something is OpenVPN
If you do not start the device name with tun then make sure to always add to the openvpn config: dev-type tun in addition to dev vpn_xxxxx

As a side note and also not related why are you using OpenVPN instead of WireGuard, which is easier to setup and three times as fast as OpenVPN?

There are no routing rules made and no iptables which is related to the above error.
So no wonder it is not working.

Maybe @stangri has an idea

Edit: could be related to the fact that you are not using tun-XXX as device names, you are adding the interfaces as supported but you are using the device names and maybe you should use the interface names?

@egc: thank you for these first bits of advice, I'll dwell upon them one by one.

I removed these two lines from /etc/config/network and rebooted the router. Like you already suggested, this didn't make a difference (but it didn't worsen my situation either :wink:).

When things were still working as I wanted (which was with PBR version 1.1.1-7 and before), I applied a comparable naming scheme (vpn_amsterdam, vpn_stockholm etc., instead of tun0, tun1 etc.), because this made it easier for me to experiment with policies. Like you suggested, for each VPN client the line dev-type 'tun' was indeed added to /etc/config/openvpn, as an example of which the following:

config openvpn 'PP_Amsterdam'
option config '/etc/openvpn/PP_Amsterdam.ovpn'
option enabled '1'
option dev_type 'tun'
option dev 'vpn_amsterdam'

Understanding now that this approach may unnecessarily complicate things, or in any case make troubleshooting more difficult, I have now restored things back to how I started out earlier this week (but when my routing policy also didn't work). My current situation is as follows:

cat /etc/config/network
root@OpenWrt:/# cat etc/config/network

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

config globals 'globals'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ip6assign '60'
	option broadcast ‘redacted.255'
	list ipaddr ‘redacted.1/24'
	list dns '45.90.28.234'
	list dns '45.90.30.234'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'
	option peerdns '0'
	list dns '45.90.28.234'
	list dns '45.90.30.234'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'
	option reqaddress 'try'
	option reqprefix 'auto'
	option peerdns '0'
	list dns '2a07:a8c0::49:2c58'
	list dns '2a07:a8c1::49:2c58'

config device
	option name 'eth0'

config interface 'vpnclient0'
	option proto 'none'
	option device 'tun0'

config interface 'vpnclient1'
	option proto 'none'
	option device 'tun1'

config interface 'vpnclient2'
	option proto 'none'
	option device 'tun2'

config interface 'vpnclient3'
	option proto 'none'
	option device 'tun3'

config interface 'vpnclient4'
	option proto 'none'
	option device 'tun4'

root@OpenWrt:/#

and:

cat etc/config/openvpn
root@OpenWrt:/# cat etc/config/openvpn
config openvpn 'AirVPN_Belgium'
	option config '/etc/openvpn/AirVPN_Belgium.ovpn'
	option enabled '1'
	option dev_type 'tun'

config openvpn 'AirVPN_Germany'
	option config '/etc/openvpn/AirVPN_Germany.ovpn'
	option enabled '1'
	option dev_type 'tun'

config openvpn 'AirVPN_Netherlands'
	option config '/etc/openvpn/AirVPN_Netherlands.ovpn'
	option enabled '1'
	option dev_type 'tun'

config openvpn 'AirVPN_Norway'
	option config '/etc/openvpn/AirVPN_Norway.ovpn'
	option enabled '1'
	option dev_type 'tun'

config openvpn 'AirVPN_Sweden'
	option config '/etc/openvpn/AirVPN_Sweden.ovpn'
	option enabled '1'
	option dev_type 'tun'
root@OpenWrt:/#

(In the latter file, the line option dev_type 'tun' for each VPN client is probably superfluous).

A check of the file /var/run/pbr.nft reveals that I have now at least gotten rid of the No such file or directory error:

cat /var/run/pbr.nft
root@OpenWrt:/# cat /var/run/pbr.nft
#!/usr/sbin/nft -f

add chain inet fw4 pbr_mark_0x010000
add rule inet fw4 pbr_mark_0x010000  mark set mark and 0xff00ffff xor 0x010000
add rule inet fw4 pbr_mark_0x010000 return
add chain inet fw4 pbr_mark_0x020000
add rule inet fw4 pbr_mark_0x020000  mark set mark and 0xff00ffff xor 0x020000
add rule inet fw4 pbr_mark_0x020000 return
add chain inet fw4 pbr_mark_0x030000
add rule inet fw4 pbr_mark_0x030000  mark set mark and 0xff00ffff xor 0x030000
add rule inet fw4 pbr_mark_0x030000 return
add chain inet fw4 pbr_mark_0x040000
add rule inet fw4 pbr_mark_0x040000  mark set mark and 0xff00ffff xor 0x040000
add rule inet fw4 pbr_mark_0x040000 return
add chain inet fw4 pbr_mark_0x050000
add rule inet fw4 pbr_mark_0x050000  mark set mark and 0xff00ffff xor 0x050000
add rule inet fw4 pbr_mark_0x050000 return
add chain inet fw4 pbr_mark_0x060000
add rule inet fw4 pbr_mark_0x060000  mark set mark and 0xff00ffff xor 0x060000
add rule inet fw4 pbr_mark_0x060000 return
add rule inet fw4 pbr_prerouting ether saddr { redacted }  goto pbr_mark_0x060000 comment "MacBook Pro M3"
root@OpenWrt:/#

It took me a while to digest the following alinea, and I am still not sure to what you refer here:

In my current situation, besides lan, wan and wan6, my interfaces are now vpnclient0, vpnclient1 etc., and I refer to the latter as supported interfaces under the 'Advanced Configuration' tab of LuCi's PBR interface. Or is it exactly this what you liked to see?

and:

Anyways, despite these changes, my problem has still not disappeared, meaning that traffic generated by my laptop is still not funneled through one of the VPN servers in Sweden, as my routing policy dictates. Why this is the case is beyond me, so should you or @stangri have any further suggestions, I'd be much obliged to hear. When I compare my use case to those of others, I believe mine is far less complicated, and that's why I assume that a solution to my problem should be possible.

I am leaning here at the shoulders of others who are far more knowledgeable in matters like these than me. Although I immediately accept that WireGuard is the lighter and faster protocol, I also understand that it wasn't designed with privacy in mind. As per the WireGuard protocol, its configuration files require a fixed IP address, and besides, users' real IP addresses are indefinitely stored on the VPN server by default, and are kept there even after sessions have been closed. While I know VPN providers may take mitigating measures, this is why I for the time being prefer OpenVPN, especially for work related matters. However, I do have a Vilfo router laying around, which to me has become defunct by not having received any update since the latter half of 2022. I am planning to flash it as well with OpenWrt as a backup, and in this case I am planning to experiment with WireGuard for more trivial applications.

Your setup looks OK, I have the same setup with pbr 1.1.7-59, with two OpenVPN and two WireGuard tunnels which works as intended, so scratching my head at the moment why the routing of your tunnels is not processed.

Like you said a good VPN provider (I use Mullvad) keeps no logs and has taken measures to mitigate the fixed IP address, but if you are a high level government target I can understand your concern.

I don't think I can add anything to @egc's expertise, in my experience a lot of reported leaks are IPv6-related due to the nature of IPv6 routing, so while I understand it may sound like "reset everything and start from scratch", if you could completely disable IPv6 on your router, enable all counters for pbr and see if anything changes when monitoring output of status it may provide an insight.

Hmm, I guess if PBR is not working, and you have another device to play with, you could try a virtual router?

Something like this.

  1. Create stuff
###
# Create a VPN tunnel, defilter any IPv4 and IPv6 source-IP beyond tunnel, disable magic routes
##
root@OpenWrt:~# ip link add dev wg0 type wireguard
-> allowed-ip = 0.0.0.0/0, ::/0
-> route-allowed = no


(replace keys and ip with provider's settings.)

###
# Create a virtual gateway on LAN
##
root@OpenWrt:~# ip link add dev mv0 type macvlan mode bridge address 16:a5:60:bb:f3:f4 link br-lan 
root@OpenWrt:~# ip addr add 192.168.1.2/24 dev mv0

###
# Create a virtual router
##
root@OpenWrt:~# ip link add dev vpn-router type vrf table 123

###
# Add default IPv4 + IPv6 routes to virtual router
##
root@OpenWrt:~# ip -4 route add default dev wg0 table 123
root@OpenWrt:~# ip -6 route add default dev wg0 table 123

###
# Bind the above LAN gateway and VPN endpoint interfaces to the new virtual router
##
root@OpenWrt:~# ip link set dev mv0 master vpn-router
root@OpenWrt:~# ip link set dev wg0 master vpn-router

###
# Up it goes
##
root@OpenWrt:~# ip link set dev vpn-router up
root@OpenWrt:~# ip link set dev wg0 up
root@OpenWrt:~# ip link set dev mv0 up

Simplest solution I can think of.

  1. Optional: Test that the tunnel works by pinging the peer tunnel interface /30 ip address

  2. Optional: Run "tcpdump -nni mv0" and "tcpdump -nni wg0" in two side-by-side windows to see traffic

  3. Mandatory: Point the machine that needs VPN to gateway 192.168.1.2 instead of 192.168.1.1

  4. Mandatory: Ping something out in the world from the machine, eg. "ping 1.1.1.1"

Caveat: requires kmod-vrf, probably only available in 24.10-SNAPSHOT sysupgrades, might be excluded for small devices because it takes up 128 bytes extra space or whatever.

(You can do most or all of this in LUCI and UCI, I just went with CLI for fewer screenshots.)

EDIT: Probably a good idea to add masquerading via luci->firewall as well. Create a vpn-lan zone for the mv0 interface and a vpn-wan zone for the wg0 interface, set the masquerade flag on vpn-wan and allow forward vpn-lan -> vpn-wan.

although you wrote you had PBR enabled, your config shows otherwise:

The browser problems you described can be related and are sometimes seen when using add-ons for your browser.
To solve this clear browser cache and use incognito/in-private browsing.

After you have enabled PBR check that the option enabled indeed is '1' and reboot and then check again if it still is enabled.

Note that OpenVPN is slow to start and things might not work after a reboot (you might need to increase the pbr startup times).
From the command line do, after a reboot, to make sure everything will run:

service network restart && service openvpn restart && sleep 10 && service pbr stop && service pbr start

That is all I can think off

1 Like

@egc, @stangri and @appelsin: thank you very much for your replies. I am currently abroad for work and hence not near my router. When I am back next week I'll pick up the matter again and see how far I get.

1 Like

@egc, @stangri and @appelsin: having returned home again, and after another couple of hours fiddling with the settings of my router, I have decided to once again uninstall the PBR package and maybe get another router up and running to handle traffic generated by my laptop. Despite egc's and appelsins best efforts, I haven't got a clue as to why I can't get a routing policy working anymore, whereas this wasn't a problem with PBR version 1.1.1-7 and earlier. I am not suffering from a leak, as stangri seems to suggest, and it is not as if my routing policy works for IPv4 and not for IPv6 - it doesn't work at all, regardless of whether I base it on the MAC address of my laptop or its IP address. All the more since I have IPv6 support for PBR enabled, if my problem is indeed IPv6 related, there may well hide some built-in weakness in the PBR package that needs further scrutiny. I may try the package again some time in the future, but for the time being I am giving up on it. Anyways, thank you for your time to help me sorting this problem out.

1 Like

I think it's pretty well-tested, just based on feels - I see people reporting minor problems in the forums and pretty quickly fixes arrive in PBR. So my best guess is this is a configuration issue of sorts.

(caveat: i like doing everything manually, so i have no first-hand experience, take it with a grain of salt coming from me)

No problem, and thank you for reporting back with a status even though things are not working (yet)

2 Likes