As I told in the [*comment*][1] linked from OP, starting with Linux kernel 4.17, using *iptables* (or anything *netfilter* related) is not needed anymore to solve this problem. The newer feature available to handle this with a recent kernel is described in [kernelnewbies.org][2]: > Extends fib rule match support to include sport, dport and ip proto match (to complete the 5-tuple match support). Common use-cases of Policy based routing in the data center require 5-tuple match [commit][3], [commit][4], [commit][5], [commit][6], [commit][7] So rather than searching what detail didn't work the same way as in my previous answer, I'll implement the newer method in this answer. I'll assume only *one* VPN is running: the one described by OP. I lack informations about the other VPN to know if there are interactions with it. Please scratch any *ip rule* rules or *iptables* rules previously added to try and solve this problem. Keep the table 80 as in OP: ip route add table 80 192.168.50.0/24 dev bond0 src 192.168.50.34 ip route add table 80 default via 192.168.50.1 Add with [`ip rule`][8] the rules selecting the alternate routes when using specific destination ports. Without knowing the use case or remaining topology (other VPN, server *also* receiving incoming traffic from the VPN...), to stay on the safe side I limit this to the server itself, not anything it might be routing. That's the goal of `iif lo` below. It's a special way to mean *from local*, ie locally initiated outgoing (non-routed) traffic: ip rule add iif lo ipproto tcp dport 80 lookup 80 ip rule add iif lo ipproto tcp dport 443 lookup 80 ip rule add iif lo ipproto tcp dport 1195 lookup 80 ip rule add iif lo ipproto tcp dport 32400 lookup 80 Then the remaining part is to relax [Strict Reverse Path Forwarding][9] to [Loose RPF][10] (which isn't much different from not activating it at all) in case it's [active][11] by default in the given Linux distribution, to prevent return traffic from being dropped: sysctl -w net.ipv4.conf.bond0.rp_filter=2 And that's it: # ip route get 192.0.2.2 192.0.2.10 dev tun1 src 10.44.10.6 uid 0 cache # ip route get 192.0.2.2 ipproto tcp dport 80 192.0.2.10 via 192.168.50.1 dev bond0 table 80 src 192.168.50.34 uid 0 cache [1]: https://unix.stackexchange.com/questions/453509/route-traffic-on-certain-port-through-certain-interface#comment1060751_456898 [2]: https://kernelnewbies.org/Linux_4.17#Networking "Linux_4.17 - 10. Networking" [3]: https://git.kernel.org/linus/bfff4862653bb96001ab57c1edd6d03f48e5f035 [4]: https://git.kernel.org/linus/4a2d73a4fb36ed4d73967bd3892cfab014a52ab2 [5]: https://git.kernel.org/linus/bb0ad1987e963e47a02cc53b8275ffe2b38d4b70 [6]: https://git.kernel.org/linus/e37b1e978bec5334dc379d8c2423d063af207430 [7]: https://git.kernel.org/linus/5e5d6fed374155ba1a7a5ca5f12fbec2285d06a2 [8]: https://manpages.debian.org/iproute2/ip-rule.8 [9]: https://tools.ietf.org/html/rfc3704#section-2.2 "2.2. Strict Reverse Path Forwarding" [10]: https://tools.ietf.org/html/rfc3704#section-2.4 "2.4. Loose Reverse Path Forwarding" [11]: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/networking/ip-sysctl.txt?h=v5.4#n1225 "rp_filter"