OpenWrt: route different computers via different upstreams based on their IP
Let's say you have two IPv4 upstreams: 10.1.0.1 and 10.2.0.1.
10.1.0.1 is used as the default route, but you want some computers to be routed via 10.2.0.1, based on their LAN IP address.
Let's imagine for an example that you have two DHCP clients connected:
# cat /tmp/dhcp.leases
1629000000 01:02:03:aa:bb:cc 192.168.1.200 MacBook-Pro 01:01:02:03:aa:bb:cc
1629000000 01:02:03:dd:ee:ff 192.168.1.210 MacBook-Air 01:01:02:03:dd:ee:ff
and you want to route MacBook-Air (192.168.1.210) via the second upstream 10.2.0.1.
Your main routing table looks like this:
# ip r
default via 10.1.0.1 dev eth2 src 10.1.0.100
192.168.1.0/24 dev br-lan scope link src 192.168.1.1
10.1.0.0/24 dev eth2 scope link src 10.1.0.100
10.2.0.0/24 dev eth3 scope link src 10.2.0.100
Add new routing table:
# echo "100 mytable" >> /etc/iproute2/rt_tables
Define new IP set:
# ipset create myset hash:net
Fill it with LAN IPs of computers you want to route via the second upstream:
# ipset add myset 192.168.1.210
Add iptables rules to mark packets coming from those IPs. Add it to /etc/firewall.user, then restart firewall.
iptables -t mangle -A PREROUTING -m set --match-set myset src -j MARK --set-mark 0x64
Add routing rule matching the fwmark:
# ip rule add fwmark 0x64 table mytable
Set default route in table mytable:
# ip route add default via 10.2.0.1 table mytable
You may also want to add route for LAN:
# ip route add 192.168.1.0/24 via 192.168.1.1 table mytable
Basically that's it, now packets coming from 192.168.1.210 will be routed through 10.2.0.1.
To make these changes persistent, use /etc/rc.local script (executed at boot) and /etc/hotplug.d hooks.