Damion Brown's Blog

D97A 07F3 DCB1 302D

Multihoming with source based routing.


  • Wed 22 November 2017
  • Tech

In a situation with two seperate LANs each with thier own WAN connections, a host wanting to provide services to both networks will need to impliment sourced based routing policies.

By default, a unix system A) will not forward a packet from one interface to any other B) can have only one default gateway.

A standard networked system may have a LAN of 192.168.1.0/24 and a gateway of 192.168.1.1. Any traffic destined for an address outside the 192.168.1.0/24 range will be sent to the default gateway (192.168.1.1) for futher processing as the destination is outside the broadcast domain.

Attaching this system to a secondary LAN (172.16.0.0/24 with a gateway of 172.16.0.1) is a fundamental task, but can produce unexpected results to the unpractised.

A LAN host accessing the system on the 172.16.0.0/24 network will recieve a response as it's within the broadcast domain. Conversely a host accessing the system through the 172.16.0.1 gateway (IE: A host on the WAN) will not recieve a response. The packet will reach the system correctly; however as the default gateway is on a different interface there is no return path back to the requsting host.

A really bad meme.

The solution to this problem is to create seperate routing tables with broadcast domains and gateways respective to each interface, then create rules to handle packets based on their source and destination.

Personally I think ifconfig's output is more easily digested than ip's, here's the would-be-system's output:

[dbrown@multihoming]{~}$ ifconfig
enp5s3    Link encap:Ethernet  HWaddr 00:1b:2f:35:59:51
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21b:2fff:fe35:5951/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:804755 errors:0 dropped:0 overruns:0 frame:0
          TX packets:174977 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:252127993 (252.1 MB)  TX bytes:14421582 (14.4 MB)

enp5s4    Link encap:Ethernet  HWaddr 00:15:17:0e:82:b1
          inet addr:172.16.0.100  Bcast:172.16.0.255  Mask:255.255.255.0
          inet6 addr: fe80::215:17ff:fe0e:82b1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1749583 errors:0 dropped:0 overruns:0 frame:0
          TX packets:379375 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:298537779 (298.5 MB)  TX bytes:260908705 (260.9 MB)

Two interfaces and two different LANs.

First create two routing tables for the two interfaces:

echo "1 old" >> /etc/iproute2/rt_tables
echo "2 new" >> /etc/iproute2/rt_tables

Here's the whole file:

[dbrown@multihoming]{~}$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
1 old
2 new

Now to add a default gateway and broadcast domain for each interface:

ip route add 192.168.1.0/24 src 192.168.1.100 dev enp5s3 table new
ip route add default via 192.168.1.1 dev enp5s3 table new
ip route add 172.16.0.0/24 src 172.16.0.100 dev enp5s4 table old
ip route add default via 172.16.0.1 dev enp5s4 table old

Our tables should look like this now:

[dbrown@multihoming]{~}$ ip route show table new
default via 192.168.1.1 dev enp5s3
192.168.1.0/24 dev enp5s3  scope link  src 192.168.1.100
[dbrown@multihoming]{~}$ ip route show table old
default via 172.16.0.1 dev enp5s4
172.16.0.0/24 dev enp5s4  scope link  src 172.16.0.100

Now to create our rules to handle traffic for each interface:

ip rule add from 192.168.1.0/24 table new
ip rule add to 192.168.1.0/24 table new
ip rule add from 172.16.0.0/24 table old
ip rule add to 172.16.0.0/24 table old

Viewing our ip rules gives the following:

[dbrown@multihoming]{~}$ ip rule
0:      from all lookup local
32762:  from all to 172.16.0.100 lookup old
32763:  from 172.16.0.100 lookup old
32764:  from all to 192.168.1.100 lookup new
32765:  from 192.168.1.100 lookup new
32766:  from all lookup main
32767:  from all lookup default

Now the system will serve clients outside the broadcast domain on both LANs.

If you had two WAN IP addresses from two seperate ISPs, this system could now response to requests on both addresses.

Persistence across reboots

This part is fairly trivial, the routing tables are persistant but the routes and rules are not.

To make them persistent across reboots, you'll need to re-create them as the interfaces come up.

[dbrown@multihoming]{~}$ cat /etc/network/interfaces
auto enp5s4
iface enp5s4 inet dhcp
post-up ip rule add from 172.16.0.0/24 table old
post-up ip rule add to 172.16.0.0/24 table old
post-up ip route add default via 172.16.0.1 dev enp5s4 table old
post-up ip route add 172.16.0.0/24 src 172.16.0.100 dev enp5s4 table old

auto enp5s3
iface enp5s3 inet dhcp
post-up ip rule add from 192.168.1.0/24 table new
post-up ip rule add to 192.168.1.0/24 table new
post-up ip route add default via 192.168.1.1 dev enp5s3 table new
post-up ip route add 192.168.1.0/24 src 192.168.1.100 dev enp5s3 table new

which can easily be done by modifying the interfaces file.