Pbr does not create IP sets

Hi all!

I have configured PBR with domain policy. But it works until the device is rebooted.
After reboot, ip-sets are not created.
If I reload the pbr service, everything starts working. Sing-box is used as a vpn gateway (with zerotier it also does not work).
dnsmasq configured to work with dnscrypt-proxy2.
What could be the problem?

Testing on RockChip 3A and on openWRT x86

Version: OpenWrt 24.10.0, r28427-6df0e3d02a

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 '0'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option localservice '1'
        option ednspacket_max '1232'
        option noresolv '1'
        list server '127.0.0.53'

config dhcp 'lan'
        option interface 'lan'
        option start '50'
        option limit '204'
        option leasetime '12h'
        option dhcpv4 'server'
        option dhcpv6 'server'
        option ra 'server'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option force '1'

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'
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 'fd4a:a971:6036::/48'
        option packet_steering '1'

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

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

config interface 'wwan'
        option proto 'dhcp'
        option hostname '*'

config device
        option name 'phy0-sta0'
        option ipv6 '0'

config interface 'tun0'
        option proto 'none'
        option device 'tun0'
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'
        list network 'wan'
        list network 'wan6'
        list network 'wwan'

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 include 'pbr'
        option fw4_compatible '1'
        option type 'script'
        option path '/usr/share/pbr/firewall.include'

config zone
        option name 'zerotier'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        option masq '1'

config forwarding
        option src 'zerotier'
        option dest 'lan'

config forwarding
        option src 'lan'
        option dest 'zerotier'

config zone
        option name 'wireguard'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'

config forwarding
        option src 'wireguard'
        option dest 'lan'

config forwarding
        option src 'lan'
        option dest 'wireguard'

config zone
        option name 'tun'
        option forward 'ACCEPT'
        option output 'ACCEPT'
        option input 'ACCEPT'
        option masq '1'
        option mtu_fix '1'
        option family 'ipv4'
        list device 'tun0'
        list network 'tun0'

config forwarding
        option name 'lan-tun'
        option dest 'tun'
        option src 'lan'
        option family 'ipv4'

config forwarding
        option src 'tun'
        option dest 'lan'
pbr
config pbr 'config'
        option enabled '1'
        option verbosity '2'
        option strict_enforcement '1'
        option resolver_set 'dnsmasq.nftset'
        list resolver_instance '*'
        option ipv6_enabled '0'
        option boot_timeout '30'
        option rule_create_option 'add'
        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'
        option procd_wan_interface 'wwan'

config policy
        option name 'intel'
        option dest_addr 'intel.com'
        option interface 'tun0'
pbr status before reload

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 rule inet fw4 pbr_prerouting ip daddr { 13.91.95.74 } goto pbr_mark_0x020000 comment "intel"
pbr chains - policies
chain pbr_forward { # handle 48
}
chain pbr_input { # handle 49
}
chain pbr_output { # handle 50
}
chain pbr_postrouting { # handle 52
}
chain pbr_prerouting { # handle 51
}
chain pbr_dstnat { # handle 47
}
pbr chains - marking
pbr nft sets
pbr tables & routing
IPv4 table 256 pbr_wwan route:
default via 192.168.162.210 dev phy0-sta0
IPv4 table 256 pbr_wwan rule(s):
30000: from all fwmark 0x10000/0xff0000 lookup pbr_wwan
IPv4 table 257 pbr_tun0 route:
default via 172.16.250.1 dev tun0
IPv4 table 257 pbr_tun0 rule(s):
29998: from all fwmark 0x20000/0xff0000 lookup pbr_tun0

pbr status after reload
pbr - environment
pbr 1.1.8-r10 running on OpenWrt 24.10.0.

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 set inet fw4 pbr_tun0_4_dst_ip_cfg026ff5 { type ipv4_addr;                   auto-merge;                             flags interval;
policy performance;                              comment "intel";}
add rule inet fw4 pbr_prerouting ip daddr @pbr_tun0_4_dst_ip_cfg026ff5  goto pbr_mark_0x020000 comment "intel"

pbr chains - policies
        chain pbr_forward { # handle 48
        }
        chain pbr_input { # handle 49
        }
        chain pbr_output { # handle 50
        }
        chain pbr_postrouting { # handle 52
        }
        chain pbr_prerouting { # handle 51
                ip daddr @pbr_tun0_4_dst_ip_cfg026ff5 goto pbr_mark_0x020000 comment "intel" # handle 499
        }
        chain pbr_dstnat { # handle 47
        }

pbr chains - marking
        chain pbr_mark_0x010000 { # handle 492
                meta mark set meta mark & 0xff01ffff | 0x00010000 # handle 493
                return # handle 494
        }
        chain pbr_mark_0x020000 { # handle 495
                meta mark set meta mark & 0xff02ffff | 0x00020000 # handle 496
                return # handle 497
        }

pbr nft sets
        set pbr_tun0_4_dst_ip_cfg026ff5 { # handle 498
                type ipv4_addr
                flags interval
                auto-merge
                comment "intel"
        }

dnsmasq sets
nftset=/intel.com/4#inet#fw4#pbr_tun0_4_dst_ip_cfg026ff5 # intel

pbr tables & routing
IPv4 table 256 pbr_wwan route:
default via 192.168.162.210 dev phy0-sta0
IPv4 table 256 pbr_wwan rule(s):
30000:  from all fwmark 0x10000/0xff0000 lookup pbr_wwan

IPv4 table 257 pbr_tun0 route:
default via 172.16.250.1 dev tun0
IPv4 table 257 pbr_tun0 rule(s):
29998:  from all fwmark 0x20000/0xff0000 lookup pbr_tun0

Race condition?

(Re)start manually in rc.local ?

1 Like

What does "Race condition" mean?

Manually reload with 'service pbr reload' or '/etc/init.d/pbr restart'

PBR probably loads before all interfaces are up...

In this case PBR won a race, where the interfaces should have finished 1st.

Hence race condition.

Thanks for the clarification.

I tried changing pbr config

option boot_timeout

from default 30 to 160, but it didn't help.
And also add option

procd_reload_delay

and it didn't help.

Is there any way to fix it?