Here's how we did it. Our linux router is running a stock RH kernel, version 2.4.18-3, from RH Linux 7.3
I assume you already have all relevant interfaces up and running, firewall configured and (if needed) NAT working. Now let's add source routing.
First, add a new routing table which we called 'naboer' by adding an entry to /etc/iproute2/rt_tables
"# echo 10 naboer >> /etc/iproute2/rt_tables"
Populate this new routing table with sufficient information
"# ip route add default dev ppp0 table naboer"
"# ip route add 10.0.0.0/8 dev eth2 table naboer"
"# ip route add 192.168.0.0/16 dev eth2 table naboer"
"# ip route add 195.159.120.0/25 dev eth2 table naboer"
Now comes the funny part. Add this routing table to the list of routing tables:
"# ip rule add from 10.0.0.0/8 table naboer"
"#ip rule add from 192.168.0.0/16 table naboer"
Type the following command to examine your current list of routing tables:
"# ip rule list"
0: from all lookup local
32764: from 192.168.0.0/16 lookup naboer
32765: from 10.0.0.0/8 lookup naboer
32766: from all lookup main
32767: from all lookup 253
The "from x.x.x.x/x" parts mean that only traffic originating from the specified networks should use the specified routing table. And that's all there's to it! This is source routing!
To examine each routing table, use the following command:
"# ip route list table main"
80.212.192.0 dev ppp0 proto kernel scope link src 80.212.203.202
195.159.85.228/30 dev eth0 scope link
195.159.120.192/26 dev eth4 scope link
195.159.120.128/26 dev eth3 scope link
195.159.120.0/25 dev eth2 scope link
192.168.0.0/16 dev eth2 proto kernel scope link src 192.168.0.1
10.0.0.0/8 dev eth2 proto kernel scope link src 10.0.0.1
127.0.0.0/8 dev lo scope link
default via 195.159.85.229 dev eth0
"# ip route list table naboer"
195.159.120.0/25 dev eth2 scope link
192.168.0.0/16 dev eth2 scope link
10.0.0.0/8 dev eth2 scope link
default dev ppp0 scope link
See? "main" is the good old fashioned standard routing table, "naboer" is our new one, only used by selected traffic.
All that's left for you is to incorporate this into your init scripts. I put my stuff in "/etc/rc.d/rc.local" but feel free to find a more elegant solution :-)