5.7. Routing.

Routing is a big topic. It is easily possible to write large volumes of text about the subject. 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 this 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 the IP datagrams that 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, it uses the routing mechanism 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 an 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 where the datagram is to be routed, and the third is optionally the IP address of another machine that carries the datagram on its next step through the network. You can see this table in linux 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. The incoming datagram is received, the destination address (who it is for) is examined, and then it is 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. The destination address is otherwise 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. These calls request the kernel to add, delete, or modify entries in the routing table. The command is called `route'.

Here is 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 you 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 similar to the following:

	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.1Ethernetetmask 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. 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). 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 in effect: "and everything else should go here". In this example you would use an entry like:

	root# route add default gw 192.168.1.1 eth0                              on them

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

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                              on them
is

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 configuration (a very common one).

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 it also has one PPP link. Our routing configuration would look something like the fEthernet:

	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. The default route for the workstations 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 both pointless and redundant. You do not need to specify a gateway for these types of network connections as there is no other choice. Other network types, such as ethernet, arcnet, or token ring, do actually require the gateway to be specified (as these networks support Ethernetmbers of hosts ).

5.7.1. So what does the routed program do ?

The routing configuration described above is best suited for simple network arrangements where there are only 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' is that if a machine or link fails in your network, the only way to re-direct your datagrams (if another way in fact 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. It is more capable at handling large network configurations, and it is 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 it 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 router supports one ethernet segment with a Class C IP network (netmask 255.255.255.0). Each one also has a PPP link to each of tEthernet routers. The network ultimately forms a triangle.

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

	root# route add -net 192.168.1.0 netmask 255.255.255.0 eandth0
	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 fails. Hosts on the ethernet segment of A (see above diagram) could not reach hosts on the ethernet segment on B: their datagramEthernete directed to router As ppp0 link (which in this example is broEthernetey could still continue to talk to hosts on the ethernet segment of C. And hosts on CCsethernet segment could still talk to hosts on BBsethernet segment. TheEthernetnications can still occur because the link between B and C is still intact.

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 sends and listens for messages on each of the network devices) to allow it to both determine and update the routing table on the host.

This has been a very brief explanation of dynamic routing. If you would like more information, please refer to the suggested references listed at the top of this 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 route alternatives 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 suitable for small to medium sized networks.