Multiple IP uplinks with Gentoo
When your computer or server has access to multiple LAN segments with different address spaces and different gateways to the Internet, there’s a nice feature called policy routing that allows you to use all of them simultaneously without having to re-configure your network topology. This is especially useful when you want to increase the bandwidth and resilience of a single computer or server without the burden of being an Autonomous System (BGP peering, Internet Registry bureaucracy, etc.).
Here are the steps to setup multiple uplinks through policy routing on Gentoo:
- First of all, to access multiple networks, either you have multiple physical NICs or you need to configure your network uplink to let your network ports access multiple VLANs. For more information on VLANs configurations under Gentoo, you can check Gentoo Handbook section on VLANs.
- On Linux kernel, you need to enable CONFIG_IP_MULTIPLE_TABLES option (in Linux kernel menuconfig, you find it under Networking support => Networking options => IP: policy routing). Recompile and install kernel.
- Next, you need to install iproute2 package, which allows editing multiple routing tables:
# emerge -av sys-apps/iproute2
- Edit /etc/iproute2/rt_tables and add the following route table lines:
100 T0 101 T1
- Edit your /etc/conf.d/net file to enable network startup configuration. First add the following lines, modifying addresses and interface names to suit your needs:
config_eth0=( "192.168.0.100/24" ) routes_eth0=( "192.168.0.0/24 src 192.168.0.100 table T0" "default via 192.168.0.1 table T0" "default nexthop via 192.168.0.1 weight 1" ) rules_eth1=("from 192.168.1.1/32 table T0 priority 100" ) config_eth1=( "192.168.1.200/24" ) routes_eth0=( "192.168.1.0/24 src 192.168.1.200 table T1" "default via 192.168.1.1 table T1" "default nexthop via 192.168.0.1 weight 1" ) rules_eth1=("from 192.168.1.100/32 table T1 priority 101" )
Then uncomment the following functions (if you copied your /etc/conf.d/net from /etc/conf.d/net.example, they should be already there in comments):
postup() { local x="rules_${IFVAR}[@]" local -a rules=( "${!x}" ) if [[ -n ${rules} ]] ; then einfo "Adding IP policy routing rules" eindent # Ensure that the kernel supports policy routing if ! ip rule list | grep -q "^" ; then eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" eerror "in your kernel to use ip rules" else for x in "${rules[@]}" ; do ebegin "${x}" ip rule add ${x} dev "${IFACE}" eend $? done fi eoutdent # Flush the cache ip route flush cache dev "${IFACE}" fi } postdown() { # Automatically erase any ip rules created in the example postup above if interface_exists "${IFACE}" ; then # Remove any rules for this interface local rule ip rule list | grep " iif ${IFACE}[ ]*" | { while read rule ; do rule="${rule#*:}" ip rule del ${rule} done } # Flush the route cache ip route flush cache dev "${IFACE}" fi # Return 0 always return 0 }
- Finally, reboot with your new kernel. My advice is to proceed with this step while you can access your machine locally, just in case anything goes wrong.
Some in-depth on what I described above: with policy routing you can insert additional routing tables and configure your system to use a set of rules to decide which table to apply for each IP packet. So if you create T0 and T1 tables, you can set your host to respond to requests from each interface back to the same interface and load balance routes going to outer network by giving the same weight to both gateways in generic route table.
If you use this setup to publish your server on multiple public networks, you will probably need to configure multiple DNS A records in round-robin over your IPs.
If you’re interested in more Gentoo tips, just subscribe to my feed or follow me on Twitter.
Related posts:

