Understanding routing

posted May 5, 2013, 5:27 PM by Sachchida Ojha
On Linux and UNIX systems, information on how packets are to be forwarded is stored in a kernel structure called a routing table. You need to manipulate this table when configuring your computer to talk to other computers across a network. The routing table can be used for both static and dynamic routing. Dynamic routing consists of the kernel making decisions as to which route, out of multiple present routes, a packet should take. Since dedicated routers and ISPs generally deal more with dynamic routing, I won’t go into detail, as it is beyond the scope of this Daily Drill Down. In this Daily Drill Down, however, I will focus on static routing because it is the most common.

You can examine the routing table by using the netstat program like this:
netstat -r

This will print out a routing table that may look something like the one in Table A.

Table A
Kernel IP routing table

The Destination column identifies the destination network. The Gateway column identifies the defined gateway for the specified network. An asterisk (*) appears in this column if no forwarding gateway is needed for the network. The Genmask column shows the netmask for the network; in this case, it is The Iface column shows the network interface. If you had more than one interface, you would see lo (for loopback), eth0 (first Ethernet device), and eth1 (for the second Ethernet device), and so on for the number of interfaces you have installed. Under the Flags section, the U flag means the route is up, and the G flag means that specified gateway should be used for this route. There are other flags that you may see, which include: D for dynamically installed, M for modified, and R for reinstated. These three flags indicate that the route was created or modified by a routing daemon after encountering an ICMP Redirect message. (Usually, you won’t see these flags unless you use dynamic routing.) Finally, you may see a ! flag, which indicates a rejecting route.

The MSS column indicates the default Maximum Segment Size for TCP connections over this route. The Window column indicates the default window size for TCP connections over this route, and the Irtt column indicates the Initial Round Trip Time for this route. The kernel uses this to select values for certain TCP parameters without having to wait for potentially slow answers from remote hosts. These three columns you will normally not need to worry about unless performance is suffering and you're trying to find a way to tweak it. Under most circumstances, you will not redefine the defaults here.

As you can see, I have defined a route for, which is the loopback network. The loopback network is handled locally, so no forwarding gateway is required. I also have a defined route for, which is the network that the eth0 interface is attached to. It also does not require a forwarding gateway because this is the local network. The last line contains a Destination of default, sometimes shown as, which means everything else not already classified. In this case, everything not destined for the loopback network or the network will be sent to the address—which is the forwarding gateway—and the route to the Internet.

Changing static routes
Now that I’ve shown you how to display currently defined routes, you’ll need to know how to change them. This can be done easiest using the Linuxconf program under Red Hat or Linux-Mandrake and similar administration programs under other Linux variants. Some variants, however, do not have tools like Linuxconf to handle defining routes, so let’s take a look at the "old school" method, instead. To do this configuration by hand, you'll have to learn how to use theroute command.

The first argument passed to route will be either add or del, which will tell route if it is adding or deleting a route from the routing table. The rest of the arguments that route uses are dependant upon which action you have chosen.

Let's take a look at creating the routing table so that we have defined the same routes, as shown in the previous example. The first thing you need to do is add the network to which you belong by using:
route add -net netmask dev eth0

This will add the network to the Ethernet device eth0. This corresponds with the first line shown in the netstat output.

To add the loopback network, you would use:
route add -net netmask lo

This adds the network to the Ethernet device lo, which represents the loopback (or local) network. It is not necessary to do this if you’re using Linux kernels 2.2 or higher, as those kernels will handle this automatically.

Finally, you need to add the default gateway using:
route add default gw

This creates the final entry shown by netstat and tells Linux to route all packets not destined for the network or the loopback network to the defined gateway, in this case

In the same way, you can delete networks using the del command with route like this:
route del -net

This will delete the routing table entry for the network.

Multinetwork routing
So what happens if you have a more complicated network? Let's assume for a moment that you have two LANs, the first with the network and a second with the network. There is a firewall between the two networks, with two network cards: eth0 is attached to the network, while eth1 is attached to the network. This firewall needs to route packets from the network through the network, which will in turn forward packets to the Internet.

In this scenario, you’d set up the firewall system with two IP addresses: on eth1 and on eth0. The gateway to the Internet on the network is still On the firewall system, you would run route with the following commands:
route add -net netmask dev eth1
route add default gw
route add -net netmask dev eth0

On the router, this defines both networks: on eth1 and on eth0. It also assigns as the default gateway.

On the computers in the network, you would use route like this:
route add -net netmask dev eth0
route add default gw

This tells each computer that the default gateway is, which is your firewall/router.

With both the firewall and the network set up, you should be able to route all packets from the network to the Internet and to the network. So what happens if you have a system in the network you want to be able to talk to systems in the network?

On each system in the network, you will have to configure your routing table a little differently. Here, you would traditionally use:
route add -net netmask dev eth0
route add default gw

This configures the network and the default gateway. However, in this case, knows nothing about the network, so your packets would get lost because has no idea where to send the packets and will attempt to send them through the default gateway. You need to add another routing statement to each system in the network like this:
route add -net netmask gw

This command tells the kernel to route all packets destined for the network to, which it defines as a gateway. So now, by using the three route commands, your kernel will know where to send packets. In this situation, a few things happen:

Packets to are handled without a gateway.
Packets to are sent to the defined gateway,
Packets traveling anywhere else are sent to the default gateway,

Using Linuxconf
Routing can be configured in a more intuitive way if you have the Linuxconf program, or something similar, available to you.

With Linuxconf, you can easily set up routing. To do so, fire up Linuxconf and select the Networking section. Click on Routing And Gateways. Here, you have a few options from which you can choose.

You’ll first need to set the defaults. Click the Defaults button, and define your default gateway by entering If this were a router you were configuring, you would click Enable Routing to tell the kernel to allow packets from other systems to be routed through your system to the defined gateway.

Here, you can also define routes to other networks, routes to other hosts, and routes to alternate local networks. To define routes to other networks, you would use the route command. Click Route To Other Networks, and you will be given a list of the currently defined routes. Click Add to add a new route.

In the Add New Route window, you define the gateway to the other network, the destination network, and the netmask, which is an optional setting. In this case, you might set as the gateway with as the destination. You could optionally select as thenetmask. Click Accept to save the routing definition.

You can similarly define the route to another host. For instance, if you only wanted to be able to reach the computer at IP address, you might select the Route To Other Hosts option and add a new route with the gateway of and the destination of In this way, you don't have to do blanket routing, because you would only be dealing with the one host. If you want to deal with more than one host in the network, you probably want to define a route to the entire network. This is handy if you have multiple gateways routing to different parts of the same network. For instance, if was located behind a gateway at, while the rest of the network you need was located behind, you might define the gateway here of for the destination and have the blanket route to defined in the Route To Other Networks section. Since the packet will always be routed with the best match (or shortest path), it is safe to define routing in this fashion.

Finally, you can define other local networks in the Route To Alternate Local Networks section. Unlike the previous definitions, this does not work by going through a defined network but by broadcasting through the defined Ethernet interface. For instance, if you were configuring your router, the defined local network may be for eth0 and for eth1. You could define the interface as eth1, the destination as, and the netmask as This would tell the kernel to route all traffic to the network directly over the eth1 interface instead of through a gateway.

Another likely interface would be running a multilayered network where your primary address is in the network with a secondary address as an alias in the network. For instance, your primary eth0 address might be and your alias—which would be listed as eth0:0—might be You would define the interface as eth0, the destination as, and the netmask as Your system would then handle traffic for both the and networks transparently.

More often than not, however, you won't need to make use of this unless you are configuring a router or you have a rather large and complex LAN.

After you've made your changes in Linuxconf, simply exit and save your changes. Then, restart your network using:
/etc/rc.d/init.d/network restart