Linux - routing policy database
Welcome to the tutorial guide. The guide will provide a user with guidance about routing policy database. If a user has a large router then he/she will be able to cater for the needs of different people, who should be served differently. The routing policy database allows a user to do this by having multiple sets of routing tables.
If a user is interested in using this feature then he/she needs to ensure that his/her kernel is compiled with the “IP: advanced router” and “IP: policy routing” features.
When the kernel needs to make a routing decision, it finds out which table needs to be consulted. By default, there are three tables. The old ‘route’ tool modifies the main and local tables, as does the ip tool (by default).
The default rules:
[ahu@home ahu]$ ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
This lists the priority of all rules. A user can see that all rules apply to all packets (’from all’) and also the ‘main’ table before, it is output by ip route ls, but the ‘local’ and ‘default’ table are new.
A user can generate rules which point to different tables which allow a user to override system wide routing rules.
An example will help a user to understand more about this. If a user has 3 cable modems, connected to a Linux NAT (’masquerading’) router and people living in the accommodation want to pay less to use certain services on the internet such as yahoo mail they will be then using the low-end cable modem.
Please note that the fast cable modem is known as 212.64.94.251 and is a PPP link to 212.64.94.1. The slow cable modem is known by various IP addresses, 212.64.78.148 in this example and is a link to 195.96.98.253.
The local table:
[ahu@home ahu]$ ip route list table local
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 10.0.0.1 dev eth0 proto kernel scope host src 10.0.0.1
broadcast 10.0.0.0 dev eth0 proto kernel scope link src 10.0.0.1
local 212.64.94.251 dev ppp0 proto kernel scope host src 212.64.94.251
broadcast 10.255.255.255 dev eth0 proto kernel scope link src 10.0.0.1
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 212.64.78.148 dev ppp2 proto kernel scope host src 212.64.78.148
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
The main table can be viewed as:
[ahu@home ahu]$ ip route list table main
195.96.98.253 dev ppp2 proto kernel scope link src 212.64.78.148
212.64.94.1 dev ppp0 proto kernel scope link src 212.64.94.251
10.0.0.0/8 dev eth0 proto kernel scope link src 10.0.0.1
127.0.0.0/8 dev lo scope link
default via 212.64.94.1 dev ppp0
A user can generate a rule, let’s call it ‘Shafkat’ for the house mate. Although a user can work with pure numbers, it’s simple and easy if a user adds the tables to /etc/iproute2/rt_tables.
# echo 200 Shafkat >> /etc/iproute2/rt_tables
# ip rule add from 10.0.0.10 table Shafkat
# ip rule ls
0: from all lookup local
32765: from 10.0.0.10 lookup Shafkat
32766: from all lookup main
32767: from all lookup default
A user can now generate Shafkat’s table, and flush the route cache:
# ip route add default via 195.96.98.253 dev ppp2 table Shafkat
# ip route flush cache
Split access
Please note that a user can set some symbolic names such as $IF1, $IF2, $IP1, etc. If we say that $IF1 is the name of the first interface and $IF2 the name of the second. A user can then use $IP1 as an IP address associated with $IF1 and $IP2 the IP address associated with $IF2. Now a user can then let $P1 be the IP address of the gateway at Provider 1, and $P2 the IP address of the gateway at provider 2. Finally, let $P1_NET be the IP network $P1 is in, and $P2_NET the IP network $P2 is in.
This will result in two additional routing tables, say T1 and T2. These are added in /etc/iproute2/rt_tables. Now a user can set up routing in these tables as follows:
ip route add $P1_NET dev $IF1 src $IP1 table T1
ip route add default via $P1 table T1
ip route add $P2_NET dev $IF2 src $IP2 table T2
ip route add default via $P2 table T2
A user can just build a route to the gateway and build a default route via that gateway, as a user would do in the case of a single upstream provider, but put the routes in a separate table per provider.
Now a user can set up the main routing table. It is good to know that that the src arguments ensure the right outgoing IP address is chosen.
ip route add $P1_NET dev $IF1 src $IP1
ip route add $P2_NET dev $IF2 src $IP2
A users preference for default route is:
ip route add default via $P1
After this, a user can set up the routing rules. These actually choose what routing table to route with. Here a user has to ensure that in order to make sure that he or she routes out a given interface if a user already has the corresponding source address:
ip rule add from $IP1 table T1
ip rule add from $IP2 table T2
Load balancing
If a user has already setup split access then instead of choosing one of the two providers as a users’ default route. Please set up the default route to be a multipath route. In the default kernel this will balance routes over the two providers. It is done as follows.
ip route add default scope global nexthop via $P1 dev $IF1 weight 1 \
nexthop via $P2 dev $IF2 weight 1
This will balance the routes over both providers. Please note that balancing will not be perfect, as it is route based, and routes are cached. This means that routes to often-used sites will always be over the same provider.
If you followed advise and guidance as provided in this tutorial guide then you would have learnt about routing policy database.













