Linux Routing


For the typical linux computer with an internet connection there are two interfaces, eth0 and lo. For this post lets go over how a packet is routed in a linux system.*

The iproute2 commands that I use the most often are ip address and ip route. ip address without any additional arguments will show all the ip addresses configured for the network devices present on the system (e.g. eth0 and lo). Similarly ip route will show all the system routes that are configured on the system which essentially map a subnet to a particular network interface.

In the routes you’d typically see a default route defined as default via 10.0.0.1 dev eth0 and a route for eth0 explicitly defined as 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.2. When an application needs to send a packet to a destination ip, it will hand the packet to the kernel’s network stack to send off all while oblivious to whichever route or network device that the kernel ends up using.

Let’s go through different examples that will use each of the routes.

If an application wants to send a packet to another system that has an ip of 10.0.0.3 the kernel will look at the routes that isn’t the default route which in this case will match with the route 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.2. This means that the packet will be sent to 10.0.0.3 using eth0 with a source ip of 10.0.0.2. This particular case is a bit special because the destination ip, 10.0.0.3, is within the local subnet so the system’s arp table will contain an entry mapping 10.0.0.3 to the mac address of the system on the subnet responding to arp requests for the ip 10.0.0.3. The packet will then be sent out of eth0, go through a L2 switch which will direct the packet based on the destination mac address and finally send it to the computer which responded to the arp request for 10.0.0.3.

If an application wants to send a packet to another system that has an ip of 12.0.0.2 the kernel in this case will look at all the routes and because no routes match, it will use the default route. What this means is that it will send the packet with a destination address of 12.0.0.2 and use the mac address associated with 10.0.0.1 in the arp table. From here the packet is sent to the router which has NAT’ing functionality and will essentially proxy the connection to 12.0.0.2 for 10.0.0.2.

This post is an ongoing effort and will be continuously updated and corrected for errors as I’m sure the way I’ve tried to explain it is a bit flawed.