Linux provides a number of tools for flexible routing selection.
Single routing table
In the simplest case, there is just one kernel routing table and no routes with the SRC attribute. This table contains a number of routes, which were placed there manually (
ip route add), by the DHCP daemon, or by routing daemons. In this case, the kernel chooses:
- the most specific route;
- if there are multiple equally specific routes, the one with the smallest kernel metric.
Note that the kernel metric (displayed by
ip route show) is chosen by the routing daemon, and is not necessarily related to the metric of any particular routing protocol. For example, Quagga uses the same metric for all the routes it installs in the kernel, independently of the protocol's metric.
Linux also supports routes with a SRC attribute which only match packets with a given source address. SRC only works for IPv6, and was buggy until very recently (3.11, if memory serves); I don't recommend using it unless you know what you are doing.
Multiple routing tables
If you need more flexibility than the above provides, you will need to play with multiple routing tables, and write rules to choose one particular routing table for each packet. A common technique is to dispatch on source-address in order to simulate source-specific routes. Another technique is to run each routing daemon in its own routing table, and simulate Cisco's "administrative distance". All of this is described in detail in Chapter 4 of the LARTC.