Configuration to use choose the hardware interface for the request?

Solution 1:

What curl --interface <iface> http://example.com does is to connect to example.com, using interface's <iface> IP address as source. Otherwise routing proceeds as usual.

If you wish to route based on the packets source address, you need to add two routing tables (one for packets with source 10.199.25.78 and one for packets with source 10.227.136.222). Let's give the routing tables names, by adding:

200 ppp0
201 ppp1

to /etc/iproute2/rt_tables and fill them with default routes for packets from those interfaces:

ip route add default dev ppp0 via 10.64.64.64 table ppp0
ip route add default dev ppp1 via 10.64.64.65 table ppp1

Now, all you need to do is to add two rules which will select table ppp0 or ppp1 according to the source address:

ip rule add from 10.199.25.78 table ppp0
ip rule add from 10.227.136.222 table ppp1

Edit: I dug deeper into curl's --interface ppp0 option. It can work in two ways (cf. connect.c):

  • if the process has the CAP_NET_RAW capability (like when you are root) it binds to the given interface (through SO_BINDTODEVICE) and all routes that don't use the ppp0 interface are ignored.
  • if the process is unprivileged, curl binds to the IP address of the ppp0 interface (10.199.25.78) and routing proceeds as usual.