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:

  1. 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.
  2. 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.
  3. Next, you need to install iproute2 package, which allows editing multiple routing tables:
    # emerge -av sys-apps/iproute2
  4. Edit /etc/iproute2/rt_tables and add the following route table lines:
    100        T0
    101        T1
  5. 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
    }
  6. 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.

This entry was posted in How-tos, Sysadmin and tagged , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment