Policy-Based-Routing (pbr) package discussion

Could you please try pbr 1.1.4-6?

If your default wan interface is not wan, you'd need to explicitly set it in procd_wan_interface option.

Hi, my default wan interface is not wan but tun0 as soon as is active vpn, but why when I change the name all works good?
From wwan to wifi_tethering

edit tested 1.1.4-6

The way that vpn-policy-routing was originally written, it waited for wan to come up before doing anything. Sadly, OpenWrt doesn't provide an API for packages to find out the name of wan interface, it only provides the name of the interface with the default gateway (which, depending on your configuration can be a VPN tunnel). So I've implemented my own way of trying to figure out what the wan interface is, which I've been tweaking since, but apparently it backfired in your use case.

Having reflected on this question tho, I feel that while it might be nice to be able to have wan as the target in policies and custom user files, whatever the actual wan interface name is (be it wwan or WAN or wan-ppoe), which is what current code does, there's no need to actually figure it out on start, I might as well check if the default interface is up/has gateway before starting to create tables/rules. There might be other considerations tho (like strict enforcement delay), so I'll have to ponder on that before making any drastic changes.

Service Status
Version 1.1.4-6 - Running (nft mode).
Service Gateways
wan/eth1/192.168.1xx.1
VPN_TUN/tun0/10.xx.xx.x ✓
wwan/phy2-sta0/0.0.0.0

I've touched the load network function, in this way all is ok...

load_network() {
	_find_firewall_wan_zone() { [ "$(uci_get 'firewall' "$1" 'name')" = "wan" ] && firewallWanZone="$1"; }
	local i
	local param="$1"
	config_load 'network'
	[ -z "$ifacesAll" ] && config_foreach _build_ifaces_all 'interface'
	if [ -z "$ifacesSupported" ]; then
		config_load 'firewall'
		config_foreach _find_firewall_wan_zone 'zone'
		for i in $(uci_get 'firewall' "$firewallWanZone" 'network'); do
			is_supported_interface "$i" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${i} "
		done
		config_load 'network'
		config_foreach _build_ifaces_supported 'interface'
	fi
	[ -z "$wanIface4" ] && pbr_find_iface wanIface4 'wan'
	[ -n "$wanIface4" ] && [ -z "$wanGW4" ] && network_get_gateway wanGW4 "$wanIface4"
	if [ -n "$ipv6_enabled" ]; then
		[ -z "$wanIface6" ] && pbr_find_iface wanIface6 'wan6'
		[ -n "$wanIface6" ] && [ -z "$wanGW6" ] && network_get_gateway6 wanGW6 "$wanIface6"
	fi
	case "$param" in
		on_boot|on_start)
			[ -n "$wanIface4" ] && output 2 "Found wan interface (${param}): $wanIface4 \\n"
			[ -n "$wanGW4" ] && output 2 "Found wan gateway (${param}): $wanGW4 \\n"
			[ -n "$wanIface6" ] && output 2 "Found wan6 interface (${param}): $wanIface6 \\n"
			[ -n "$wanGW6" ] && output 2 "Found wan6 gateway (${param}): $wanGW6 \\n"
		;;
	esac
	wanGW="${wanGW4:-$wanGW6}"
}

Thanks a lot

it's not obvious for me what have you changed.

Sorry.

--- a/originale/pbr
+++ b/mod/pbr
@@ -15,7 +15,7 @@ USE_PROCD=1
 # shellcheck disable=SC2018,SC2019,SC2034,SC3043,SC3057,SC3060
 
 readonly packageName='pbr'
-readonly PKG_VERSION='dev-test'
+readonly PKG_VERSION='1.1.4-6test'
 readonly serviceName="$packageName $PKG_VERSION"
 readonly serviceTrapSignals='exit SIGHUP SIGQUIT SIGKILL'
 readonly packageConfigFile="/etc/config/${packageName}"
@@ -604,19 +604,17 @@ load_environment() {
 
 load_network() {
        _find_firewall_wan_zone() { [ "$(uci_get 'firewall' "$1" 'name')" = "wan" ] && firewallWanZone="$1"; }
-       local i param="$1"
+       local i
+       local param="$1"
+       config_load 'network'
+       [ -z "$ifacesAll" ] && config_foreach _build_ifaces_all 'interface'
        if [ -z "$ifacesSupported" ]; then
                config_load 'firewall'
                config_foreach _find_firewall_wan_zone 'zone'
                for i in $(uci_get 'firewall' "$firewallWanZone" 'network'); do
                        is_supported_interface "$i" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${i} "
-                       if ! is_tunnel "$i"; then
-                               is_wan  "$i" && wanIface4="$i"
-                               [ -n "$ipv6_enabled" ] && is_wan6 "$i" && wanIface6="$i"
-                       fi
                done
                config_load 'network'
-               [ -z "$ifacesAll" ] && config_foreach _build_ifaces_all 'interface'
                config_foreach _build_ifaces_supported 'interface'
        fi
        [ -z "$wanIface4" ] && pbr_find_iface wanIface4 'wan'

Thanks again, please let me know if it is ok or wrong what I've done.

It is the file pbr in /etc/init.d/

1 Like

Oh, good catch, I've implemented your fixes and simplified code a bit more in pbr 1.1.4-7. Please also update the luci app to luci-app-pbr 1.1.4-7.

1 Like

Yes it is working...

I have this message on log, but also previosly...

Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory
Wed Mar 20 19:50:17 2024 daemon.err dnsmasq[1]: nftset inet fw4 pbr_wan_4_dst_ip_cfg0e6ff5 Error: No such file or directory

These log messages are mitigated or not present if I setup the procd_boot_delay '60' and adblock delay to 30.

Thanks again, can you also please push this version on openwrt/packages?

1 Like

Thank you for your help with 1.1.4-5, I'm trying to make sure it passes CI checks before I merge it, once it's merged it should be a trivial update to 1.1.4-7.

2 Likes

Out of curiosity, I am on OpenWrt 23.05.2 r23630-842932a63d and pbr is at 1.1.1-7. Where are these 1.1.4-X ?

Hi,
as is write on documentation, please follow:

Add Repository (GitHub)

opkg update
opkg install wget-ssl
echo -e -n 'untrusted comment: OpenWrt usign key of Stan Grishin\nRWR//HUXxMwMVnx7fESOKO7x8XoW4/dRidJPjt91hAAU2L59mYvHy0Fa\n' > /etc/opkg/keys/7ffc7517c4cc0c56
sed -i '/stangri_repo/d' /etc/opkg/customfeeds.conf
echo 'src/gz stangri_repo https://repo.openwrt.melmac.net' >> /etc/opkg/customfeeds.conf
opkg update
opkg install pbr luci-app-pbr

Please have a look also here

Or wait some days that newer version is pushed on openwrt repo if you are on snapshot.

1 Like

Thank you.
I am not on snapshot.

All good. The 5-10 second ipleak is still there, unfortunately. Would it be possible to have an iptable rule to block the entire internet until pbr or the interface is restarted? If not, do you know of another way to have policy-based routing with openwrt and a kill switch? Thanks in advance!

I can give you an idea: create a rule on firewall to block lan to wan, then, with a script you can deactivate that rule on your desired condition

There's already a killswitch implemented while pbr is being restarted in non-nft-file mode (so regular nft or iptables modes).

I don't know if a very high metrics on default routing table would help the strict enforcement or not, either way I don't have time to experiment with that at the moment.

@stangri
Quick question, does pbr interfere with SQM in any form?

Very good work here, much appreciate the time and effort you have put into this!

One thing that bothers me is the lack of error reporting, If possible, I think it would be good to better display why routing fails sometimes.

Nonetheless, long live OpenWrt!

Thank you for your work. I use your program. But there is one question that I could not solve. How to make a delay in starting the program so that it starts after all interfaces are raised. Otherwise, the router boot log shows records that the program restarts each time one of the interfaces is raised.

@kimboslice great point, this will be at the top of backlog.

@kot-nikot all the options/settings are described in the README.

Started seeing this error with the latest update of pbr on 23.05. Not sure if there are any adverse effects. Everything seems to work as before.

ERROR: 
/sbin/ip -6 route add default via 2001:558:6045:3b:a5c7:c7b4:3be6:849f/128 dev eth1 table 256 
ERROR: 
/sbin/ip -6 route add default from 2001:558:6045:3b:a5c7:c7b4:3be6:849f via fe80::dead:beef:1:1 dev eth1 proto static metric 512 pref medium table 256 
ERROR: 
/sbin/ip -6 route add default from 2601:645:8001:c4a0::/60 via fe80::dead:beef:1:1 dev eth1 proto static metric 512 pref medium table 256 
ERROR: 
/sbin/ip -6 route add fe80::/64 dev eth1 proto kernel metric 256 pref medium table 256 
ERROR: 
/sbin/ip -6 rule add fwmark 0x010000/0xff0000 table 256 priority 30000 
ERROR: 
/sbin/ip -6 route add unreachable default table 257 
ERROR: 
/sbin/ip -6 rule add fwmark 0x020000/0xff0000 table 257 priority 30001 
ERROR: 
/sbin/ip -6 route add unreachable default table 258 
ERROR: 
/sbin/ip -6 rule add fwmark 0x030000/0xff0000 table 258 priority 30002