Source Policy Routing on Linux
2008-07-2 – 3:32 amDefault, out of the box, behavior of a router is to look at the destination IP address and forward accordingly.
Policy routing gives you more control over your routers decision making process. With Policy Routing you can define a specific attribute of a packet, and configure your router to forward the packet in a different way.
Source policy routing is routing based on source IP address.
Real World Example
The company I work for offers a VOIP service. We use a sister company as our VOIP provider in another state. Recently we have been experiencing packet loss where our two upstream providers peer. Needless to say this is not good for VOIP and our customers have experienced issues.
Jokingly at a meeting today I suggested that we route all of the VOIP traffic through a VPN to another upstream of ours, thus bypassing the lossy peering point.
This sparked my interest for two reasons. The first, proof of concept that it could be done (otherwise known as curiosity). The second, if we couldn’t convince our upstream of the issue, it could be a last ditch solution.
A word of caution before continuing. It’s not a good idea to policy route priority traffic through a midstream VPN.
More common situations for policy routing, would be to send priority traffic over a dedicated link. On a Linux host if you have multiple IPs on different subnets, you could configure each IP to use it’s proper gateway.
Configuring Source Policy Routing on Linux
The bulk of this section was inspired/plagarized from TLDP.
Configuring Source Policy Routing in Linux is fairly simple.
- Create a new routing table
- Define a policy rule to lookup the new table
- Populate new tables routing information
Create a new routing table
# echo “252 VOIP” >> /etc/iproute2/rt_tables
This creates a new routing table which can be referred to as 252 or VOIP.
You can substitute 252 with any number ranging from 1 - 252.
Table 255/local - a special table for local broadcasts.
Table 254/main - the standard table you should be familiary with.
Table 253/default - last resort table, not typically used.
Table 0/unspec - truthfully I’m unsure, but looks like it holds the routes of all tables?
You can view a particular routing table with:
# ip route show table <table_number or table_name>
Define a policy rule to lookup the new table
To create a rule based on source address we will use the policy “from”
# ip rule add from 192.168.254.20 table VOIP
Rules are looked up much in the same way as iptables. First match wins.
We could define an entire subnet in the form of xxx.xxx.xxx.xxx/xx.
You can view your routing rules with:
# ip rule show
0: from all lookup 255
32765: from 192.168.254.20 lookup VOIP
32766: from all lookup main
32767: from all lookup default
Populate new tables routing information
Your traffic will currently be dropped as there is not any routing information in the table VOIP.
# ip route add default via 172.16.32.1 dev eth0 table VOIP
Last we need to clear the routing cache
# ip route flush cache
That’s it! We have succesfully altered the default routing decision to send any packet coming in with the source IP of 192.168.254.20 to the gateway 172.16.32.1.
Be sure to check the ip man page for more rule matches as well as rule destinations (it doesn’t have to be a routing table).