Using policy based routing with netifd to separate VPN and non-VPN traffic

Hi there,

How can I set up policy based routing using netifd to send packets from one particular network (named 'novpn') out the 'wan' interface and everything else through the default routing table?

I've looked at all the policy based routing examples in the wiki and none of them do this and none of them make it clear how one might be able to do this. There's no other documentation. I've searched the web, searched these forums and asked on IRC and I've come up with nothing.

Help would be appreciated.



Have you tried using the VPN and WAN Policy-Based Routing Luci interface to add the subnet and how it should be routed?

I'm not sure what you're referring to here. I was using the vpn-policy-routing and luci-app-vpn-policy-routing packages but I had problems with masquerading between networks and vpn-policy-routing was identified as the likely culprit after an extensive debugging session on IRC. So, having now upgraded to 21.02, I've decided to discard vpn-policy-routing and use netifd to manage policy based routing. (That's why the title of the post says "with netifd" :slight_smile:

Yes, this is what I was referring to. Sorry to hear you had trouble with those. I currently use both to be able to choose how devices on my LAN connect to the Internet (ISP A or ISP B) and also to make a few use a WireGuard connection for streaming purposes. I find it much easier than having to deal with network and firewall settings. Hope you find the reason why vpn-policy-routing is not working on your side, so maybe you can try my suggestion above.

I'm using policy based routing in a bit different way, but it probably can be remodeled for your needs.

No fancy GUI, just a few lines in /etc/config/network

  1. Separate routing table for VPN, with a killswitch to block traffic in case VPN is down
config route
	option interface 'loopback'
	option target ''
	option type 'blackhole'
	option table '22'

config route
	option interface 'vpn'
	option target ''
	option table '22'

config route
	option interface 'vpn'
	option target ''
	option table '22'
  1. Rule(-s) to redirect particular device or network to this custom VPN routing table.
config rule
	option src ''
	option lookup '22'

In case VPN protected devices need direct access to other local networks, add as a first rule

config rule
        option dest ''
        option lookup 'main'

Thanks for the snippets, that's the most useful information I've seen so far. However, I'm still not clear on how to do what I want.

What does this option do? The documentation says:

Static IPv4 routes can be defined on specific interfaces using route sections

but what does it mean for a route to be defined "on" a specific interface? The second example from the documentation lists the equivalent ip command for a section that includes an interface option but the ip command doesn't make use of the information in the interface option. This section:

config route 'route_example_2'
        option interface 'vpn'
        option target ''
        option table '100'
        option gateway ''

is apparently equivalent to:

ip route add default via table 100

It's obvious how the target, table and gateway options are being used but the interface option seems to be superfluous.

The documentation for the option only says:

Specifies the logical interface name of the parent (or master) interface this route belongs to; must refer to one of the defined interface sections

Again, what does it mean for a route to "belong to" an interface?

  • The logical interfaces l3 device is passed as dev argument to the generated route
  • The route is deleted when the logical interface is brought down
  • The route is created when the logical interface goes up

That contradicts the example in the documentation; I presume the documentation is wrong?

You mean the manual iproute2 command?

Yes, I was referring to this example:

The ip command includes no dev argument.

Yes, but the documentation states equivalent, not identical. If you want to make it even more obvious, maybe change equivalent to similar.

In my case 'vpn' is a Wireguard interface.
And this particular option means "shoot 'em all packets towards this interface and let Wireguard sort 'em out"
No need to specify gateway, since Wireguard sends packets to the relevant peer according to allowed_ips setting. And the next hop routes packets further, according to its own routing table(-s).

But again, thats how I see it working, in laymans terms. @jow described it more correctly.

I'm astonished by how simple this was. (And yet how difficult it was to get any kind of assistance.) I've added it as an example to the wiki, hopefully people who follow won't have to suffer as I have.

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

WireGuard (SSWG) default route in my case, and needed only one device separated as non-VPN traffic. Needed a Metric on the WAN IF.

I had kind assistance.


config interface 'wan'
	option ifname 'eth0'
	option proto 'dhcp'
	option peerdns '0'
	list dns ''
	option metric '10'				    # Added Metric option 

config rule                        
	option in 'lan'
	option src 'SINGULAR-DEVICE/32'		# confg rule where option src 'SINGULAR-DEVICE/32'
	option lookup '100'

config route                            # option gateway 'ISP-GATEWAY'
	option target ''
	option interface 'wan'
	option table '100
	option gateway 'ISP-GATEWAY'

Cmd to confirm.

/etc/config$ ip route show default
default dev SSWG proto static scope link 
default via ISP-GATEWAY dev eth0 proto static src ISP-IPADDRESS metric 10

/etc/config$ ip rule
0:	from all lookup local 
1:	from SINGULAR-DEVICE/32 iif br-lan lookup 100 
32766:	from all lookup main 
32767:	from all lookup default

/etc/config$ ip route show table 100
default via ISP-GATEWAY dev eth0 proto static metric 10

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.