5.7. Routing.

Routing is a big topic. It is easily possible to write large volumes of text about it. Most of you will have fairly simple routing requirements, some of you will not. I will cover some basic fundamentals of routing only. If you are interested in more detailed information then I suggest you refer to the references provided at the start of the document.

Let's start with a definition. What is IP routing ? Here is one that I'm using:

"IP Routing is the process by which a host with multiple network connections decides where to deliver IP datagrams it has received."

It might be useful to illustrate this with an example. Imagine a typical office router, it might have a PPP link off the Internet, a number of ethernet segments feeding the workstations and another PPP link off to another office. When the router receives a datagram on any of its network connections, routing is the mechanism that it uses to determine which interface it should send the datagram to next. Simple hosts also need to route, all Internet hosts have two network devices, one is the loopback interface described above and the other is the one it uses to talk to the rest of the network, perhaps an ethernet, perhaps a PPP or SLIP serial interface.

Ok, so how does routing work ? Each host keeps a special list of routing rules, called a routing table. This table contains rows which typically contain at least three fields, the first is a destination address, the second is the name of the interface to which the datagram is to be routed and the third is optionally the IP address of another machine which will carry the datagram on its next step through the network. In linux you can see this table by using the following command:

	user% cat /proc/net/route
	

or by using either of the following commands:

	user% /sbin/route -n
	user% netstat -r
	

The routing process is fairly simple: an incoming datagram is received, the destination address (who it is for) is examined and compared with each entry in the table. The entry that best matches that address is selected and the datagram is forwarded to the specified interface. If the gateway field is filled then the datagram is forwarded to that host via the specified interface, otherwise the destination address is assumed to be on the network supported by the interface.

To manipulate this table a special command is used. This command takes command line arguments and converts them into kernel system calls that request the kernel to add, delete or modify entries in the routing table. The command is called `route'.

A simple example. Imagine you have an ethernet network. You've been told it is a class-C network with an address of 192.168.1.0. You've been supplied with an IP address of 192.168.1.10 for your use and have been told that 192.168.1.1 is a router connected to the Internet.

The first step is to configure the interface as described earlier. You would use a command like:

	root# ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
	

You now need to add an entry into the routing table to tell the kernel that datagrams for all hosts with addresses that match 192.168.1.* should be sent to the ethernet device. You would use a command similar to:

	root# route add -net 192.168.1.0 netmask 255.255.255.0 eth0
	

Note the use of the `-net' argument to tell the route program that this entry is a network route. Your other choice here is a `-host' route which is a route that is specific to one IP address.

This route will enable you to establish IP connections with all of the hosts on your ethernet segment. But what about all of the IP hosts that aren't on your ethernet segment ?

It would be a very difficult job to have to add routes to every possible destination network, so there is a special trick that is used to simplify this task. The trick is called the `default' route. The default route matches every possible destination, but poorly, so that if any other entry exists that matches the required address it will be used instead of the default route. The idea of the default route is simply to enable you to say "and everything else should go here". In the example I've contrived you would use an entry like:

	root# route add default gw 192.168.1.1 eth0
	

The `gw' argument tells the route command that the next argument is the IP address, or name, of a gateway or router machine which all datagrams matching this entry should be directed to for further routing.

So, your complete configuration would look like:

	root# ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
	root# route add -net 192.168.1.0 netmask 255.255.255.0 eth0
	root# route add default gw 192.168.1.1 eth0
	

If you take a close look at your network `rc' files you will find that at least one of them looks very similar to this. This is a very common configuration.

Let's now look at a slightly more complicated routing configuration. Let's imagine we are configuring the router we looked at earlier, the one supporting the PPP link to the Internet and the lan segments feeding the workstations in the office. Lets imagine the router has three ethernet segments and one PPP link. Our routing configuration would look something like:

	root# route add -net 192.168.1.0 netmask 255.255.255.0 eth0
	root# route add -net 192.168.2.0 netmask 255.255.255.0 eth1
	root# route add -net 192.168.3.0 netmask 255.255.255.0 eth2
	root# route add default ppp0
	

Each of the workstations would use the simpler form presented above, only the router needs to specify each of the network routes separately because for the workstations the default route mechanism will capture all of them letting the router worry about splitting them up appropriately. You may be wondering why the default route presented doesn't specify a `gw'. The reason for this is simple, serial link protocols such as PPP and SLIP only have two hosts on their network; (one at each end). To specify the host at the other end of the link as the gateway is pointless and redundant, as there is no other choice, so you do not need to specify a gateway for these types of network connections. Other network types such as ethernet, arcnet or token ring do require the gateway to be specified as these networks support large numbers of hosts on them.

5.7.1. So what does the routed program do ?

The routing configuration described above is best suited to simple network arrangements where there are only ever single possible paths to destinations. When you have a more complex network arrangement things get a little more complicated. Fortunately for most of you this won't be an issue.

The big problem with `manual routing' or `static routing' as described, is that if a machine or link fails in your network then the only way you can direct your datagrams another way, if another way exists, is by manually intervening and executing the appropriate commands. Naturally this is clumsy, slow, impractical and hazard prone. Various techniques have been developed to automatically adjust routing tables in the event of network failures where there are alternate routes, all of these techniques are loosely grouped by the term `dynamic routing protocols'.

You may have heard of some of the more common dynamic routing protocols. The most common are probably RIP (Routing Information Protocol) and OSPF (Open Shortest Path First Protocol). The Routing Information Protocol is very common on small networks such as small-medium sized corporate networks or building networks. OSPF is more modern and more capable at handling large network configurations and better suited to environments where there is a large number of possible paths through the network. Common implementations of these protocols are: `routed' - RIP and `gated' - RIP, OSPF and others. The `routed' program is normally supplied with your Linux distribution or is included in the `NetKit' package detailed above.

An example of where and how you might use a dynamic routing protocol might look something like the following:


    192.168.1.0 /                         192.168.2.0 /
       255.255.255.0                         255.255.255.0
     -                                     -
     |                                     |
     |   /-----\                 /-----\   |
     |   |     |ppp0   //    ppp0|     |   |
eth0 |---|  A  |------//---------|  B  |---| eth0
     |   |     |     //          |     |   |
     |   \-----/                 \-----/   |
     |      \ ppp1             ppp1 /      |
     -       \                     /       -
              \                   /
               \                 /
                \               /
                 \             /
                  \           /
                   \         /
                    \       /
                     \     /
                  ppp0\   /ppp1
                     /-----\
                     |     |
                     |  C  |
                     |     |
                     \-----/
                        |eth0
                        |
                   |---------|
                   192.168.3.0 /
                      255.255.255.0

We have three routers A, B and C. Each supports one ethernet segment with a Class C IP network (netmask 255.255.255.0). Each router also has a PPP link to each of the other routers. The network forms a triangle.

It should be clear that the routing table at router A could look like:

	root# route add -net 192.168.1.0 netmask 255.255.255.0 eth0
	root# route add -net 192.168.2.0 netmask 255.255.255.0 ppp0
	root# route add -net 192.168.3.0 netmask 255.255.255.0 ppp1
	

This would work just fine until the link between router A and B should fail. If that link failed then with the routing entry shown above hosts on the ethernet segment of A could not reach hosts on the ethernet segment on B because their datagram would be directed to router A's ppp0 link which is broken. They could still continue to talk to hosts on the ethernet segment of C and hosts on the C's ethernet segment could still talk to hosts on B's ethernet segment because the link between B and C is still intact.

But wait, if A can talk to C and C can still talk to B, why shouldn't A route its datagrams for B via C and let C send them to B ? This is exactly the sort of problem that dynamic routing protocols like RIP were designed to solve. If each of the routers A, B and C were running a routing daemon then their routing tables would be automatically adjusted to reflect the new state of the network should any one of the links in the network fail. To configure such a network is simple, at each router you need only do two things. In this case for Router A:

	root# route add -net 192.168.1.0 netmask 255.255.255.0 eth0
	root# /usr/sbin/routed
	

The `routed' routing daemon automatically finds all active network ports when it starts and sends and listens for messages on each of the network devices to allow it to determine and update the routing table on the host.

This has been a very brief explanation of dynamic routing and where you would use it. If you want more information then you should refer to the suggested references listed at the top of the document.

The important points relating to dynamic routing are:

  1. You only need to run a dynamic routing protocol daemon when your Linux machine has the possibility of selecting multiple possible routes to a destination. An example of this would be if you plan to use IP Masquerading.

  2. The dynamic routing daemon will automatically modify your routing table to adjust to changes in your network.

  3. RIP is suited to small to medium sized networks.