Policy based routing

What for?
Sometimes one routing table is simply not enough. For example you two gateways to your provider, and want to do an loadbalancing by sending all ssh traffic over one and all http over the other uplink. With just one gateway everything goes over one uplink and the other is unused.

With policy based routing you can choose by various parameters which package should use which routing table and therefor perhaps take another route.

Kernel

 * CONFIG_IP_ADVANCED_ROUTER
 * IP_MULTIPLE_TABLES
 * CONFIG_NETFILTER_XT_MARK (only if you intend to use fwmarks as indicators for ip rule)
 * IP_NF_MANGLE (only if you intend to use fwmarks as indicators for ip rule)

Packages

 * sys-apps/iproute2
 * net-firewall/iptables (only if you intend to use fwmarks as indicators)

Create new Routing Table

 * 1) edit /etc/iproute2/rt_tables
 * 2) append [ID of your Table] [Name of your table]
 * 3) Add rules with ip rule but with table [Table Name or Table ID]
 * 4) check with ip route show table [Table Name or Table ID]

Decide which packages takes what routing table
By default every packages takes the routing table main (ID 254). You can now specify rules for packages to take different routing tables (which you have to create first), every package which is not matching any rule still takes the default routing table (main).

ip rule
A full list of the possible parameters you can get here If this is not sufficient for you (i.e. an source port), you can use fwmark. These fwmark you can set with iptables, so can create an ip rule with every match iptables is capable of.

iptables mark
Simply use -j MARK --set-mark . The target MARK only works in mangle.For incoming packages I use -t mangle -A PREROUTING, for outgoing packages -t mangle -A OUTPUT. Please be aware that the mark gets lost when the packet is processed by a process (i.e. apache), so if your packet arrives your network card and the way home doesn't work properly it's of no use if you mark the incoming packet, you have to mark the new generated outgoing packet.

Packet seems to disappear
Most likely the packet gets dropped because of it was considered "martian". In the actual kernel these packages get dropped silently. You can enable logging by:

net.ipv4.conf.default.log_martians = 1 net.ipv4.conf.all.log_martians = 1
 * 1) Enable log of martian packages

If you now see messages with indicated your package gets considered martian, you can disable dropping them by:

net.ipv4.conf.default.rp_filter=0 net.ipv4.conf.all.rp_filter=0
 * 1) Enables source route verification
 * 1) Enable reverse path