Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pbr: invalid default route if gateway is not configured for interface #26083

Open
sumpfralle opened this issue Mar 2, 2025 · 4 comments
Open

Comments

@sumpfralle
Copy link
Contributor

I am using pbr for routing outgoing SMTP traffic via a wireguard connection instead of the WAN interface.

My Setup

  • interface wan is the local uplink
  • interface smtp_vpn is the wireguard interface
    • my local IP on this interface is 10.90.12.1
    • a single peer is configured (and connected) with a few allowed_ips is configured (including 0.0.0.0/0)
    • resulting default route for the wireguard interface:
      root@router:~# ip r | grep -w default | grep smtp_vpn
      default dev smtp_vpn proto static scope link metric 20
      

Problem

The default route configured in the dynamically generated routing table pbr_smtp_vpn is wrong:

root@router:~# ip r show table pbr_smtp_vpn | grep -w default
default via 10.90.12.1 dev smtp_vpn

Here the local IP address (10.90.12.1) is used as a default gateway.
This obviously does not work.
Instead the original link-level route should have been applied (see "My Setup" above).

Workaround

In order to let the configured packets flow via the smtp_vpn interface, I configured a static route via OpenWrt for the table dynamically maintained by pbr:

network.cfg21c8b4=route
network.cfg21c8b4.interface='smtp_vpn'
network.cfg21c8b4.target='0.0.0.0/0'
network.cfg21c8b4.metric='15'
network.cfg21c8b4.table='pbr_smtp_vpn'

Probably the above is not robust enough, but it works as for now.

And now there are two default routes in this dynamic pbr table:

root@router:~# ip r show table pbr_smtp_vpn | grep -w default
default via 10.90.12.1 dev smtp_vpn
default dev smtp_vpn proto static scope link metric 15

For unknown reasons, the (unwanted) host-based route (via 10.90.12.1) is ignored by the kernel. This lets the static route handle the traffic.

Possible cause

/etc/init.d/pbr currently contains the following function:

pbr_get_gateway4() {
        local iface="$2" dev="$3" gw
        network_get_gateway gw "$iface" true
        if [ -z "$gw" ] || [ "$gw" = '0.0.0.0' ]; then
#               gw="$(ubus call "network.interface.${iface}" status | jsonfilter -e "@.route[0].nexthop")"
                gw="$(ip -4 a list dev "$dev" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')"
        fi
        eval "$1"='$gw'
}

The currently active gw= assignment picks the local IP as the gateway IP.
I cannot imagine a situation, where the local IP could be the proper choice for a default route.
Thus, the above fallback is probably of no use at all?

I would recommend one of the following changes:

  • A) do not set a route, if no default gateway is found
    • no surprises, no problems
    • a static route should be a reasonable workaround for most affected users
  • B) set a link-scope route, if no default gateway is found
    • this works for wireguard interfaces (just by accident)

Thanks for maintaining the great pbr package!

@stangri
Copy link
Member

stangri commented Mar 6, 2025

Please add information from README->Getting Help.

@sumpfralle
Copy link
Contributor Author

Thanks for the reminder!

Here is my setup:

pbr_status_output.log

@stangri
Copy link
Member

stangri commented Mar 10, 2025

There have been many updates and fixes since 1.1.6, please try the most recent version on your device: https://docs.openwrt.melmac.net/#OnyourOpenWrtdevicewithopkg

@egc112
Copy link
Contributor

egc112 commented Mar 11, 2025

To add, these WireGuard interfaces are point to point so actually do not need a gateway but for IPv4 it is just ignored so should work anyway, this is my WireGuard routing table:

root@DL-WRX36:~# ip route show table pbr_wg_mullv_se
default via 10.69.78.222 dev wg_mullv_se

10.69.78.222 is the list address of the WireGuard interface and is just ignored but it is working anyway

IPv6 does not like to have a gateway on point to point links so it was removed for IPv6 (I did test work for Stan that is why I know)

root@DL-WRX36:~# ip -6 route show table pbr_wg_mullv_se
fc00:bbbb:bbbb:bb01::/64 dev wg_mullv_se proto kernel metric 256 pref medium
default dev wg_mullv_se metric 128 pref medium

code implemented for IPv6:

	if ip -6 address show dev "$dev6" | grep -q "BROADCAST"; then
		try ip -6 route add default via "$gw6" dev "$dev6" table "$tid" metric "$procd_wan6_metric" || ipv6_error=1
	elif ip -6 address show dev "$dev6" | grep -q "POINTOPOINT"; then
		try ip -6 route add default dev "$dev6" table "$tid" metric "$procd_wan6_metric" || ipv6_error=1
	else
		state add 'errorSummary' 'errorInterfaceRoutingUnknownDevType' "$dev6"
	fi

Bottom line having a gateway on IPv4 on point to point links is not necessary but should work anyway at least on 1.1.8-r10 (and perhaps for everybody but you? )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants