OpenBSD route via different gateways which have same IP but on different interfaces

gatewayopenbsdrouterouting

I have multiple VPN connections which use the same gateway IP (I do not have the ability to change this as it is out of my control). These VPNs all provide access to different networks, and the networks are at least one or two hops upstream, so a gateway IP is required in all cases. With Linux, to route to the networks, I can simply do:

ip route add $destination_1 via $gateway_ip dev $interface_1
ip route add $destination_2 via $gateway_ip dev $interface_2
ip route add $destination_3 via $gateway_ip dev $interface_3

etc.

Linux will then place the traffic for each destination network onto the correct interfaces, headed for the correct gateway, so it doesn't matter that the gateway IP is the same for each interface.

My question is, how can I achieve this in OpenBSD? I have tried and failed. My findings are that for a particular destination, I can either:

  • specify an interface (if the destination is directly reachable on that link – which it isn't in my case)
  • specify a gateway IP because the destination is not directly on link

But I can't figure out how to specify both.

Best Answer

Use the -ifp modifier to route. From the man page:

In a change or add command where the destination and gateway are not
sufficient to specify the route, the -ifp or -ifa modifiers may be 
used to determine the interface name or interface address.

So something like this works:

# for  arg in tun0 tun1 tun2; do ifconfig $arg  192.168.11.1/24; done
# route add 10/8 -iface 192.168.11.1 -ifp tun0
add net 10/8: gateway 192.168.11.1
# route add 172.16/12 -iface 192.168.11.1 -ifp tun1
add net 172.16/12: gateway 192.168.11.1
# route add 192.168.254/24 -iface 192.168.11.1 -ifp tun2
add net 192.168.254/24: gateway 192.168.11.1
# route show -inet
Routing tables

Internet:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio 
Iface
10/8               192.168.11.1       GS         0        0     -     8 tun0
localhost          localhost          UHl        0       22 32768     1 lo0
172.16/12          192.168.11.1       S          0        0     -     8 tun1
192.168.11.1       192.168.11.1       UHhl       1        4     -     1 tun0
[...my real routes omitted...]
192.168.254/24     192.168.11.1       S          0        0     -     8 tun2

If your destination routes are overlapping then you can use pf and route labels to match, or routing domains.