License:
----------
RatRoute  - a routing table manipulator
Copyright (C) 2005  Roelf Diedericks

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USAt


Overview:
----------

RatRoute is a perl script to simplify the maintenance of gateways
and routing tables in situations where multiple paths to the internet
are available. It does this by manipulating the Linux kernel routing
tables using the iproute2 utility and information from a configuration
file.

iproute2 has an advantage over the normal linux 'route' utility in that
it's syntax allows one to more accurately control the kernel routing 
table, setup multiple default gateways and lists of routing table rules
to order kernel routing decisions.

Unfortunately, iproute's syntax and ideology makes it a tool that isn't
easily understood by end-users. Linux Kernel routing rules makes 


Pre-Requisites:
---------------
- RatRoute requires the CPAN Module LockFile::Simple

wget http://search.cpan.org/CPAN/authors/id/R/RA/RAM/LockFile-Simple-0.2.5.tar.gz
tar xvfz LockFile-Simple-0.2.5.tar.gz
cd LockFile-Simple-0.2.5
perl Makefile.PL
make install

- You must have a reasonably modern (preferably 2.6.8+) series kernel
- You must have patched said kernel with an appropriate patch for the
  kernel revision with a the routes- patch by Julian Anastov.
  http://www.ssi.bg/~ja/#routes-2.6

- You must have iproute2 version ss041019 or higher
- Your kernel must be configured as an advanced router (CONFIG_IP_ADVANCED_ROUTER)
- Appropriate masquarading rules if you intend to masquerade an internal network
  via the loadbalanced gateways. E.g.: 
  	iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
  The "ppp+" bit indicates to the kernel that all traffic outbound via any PPP interface
  is to be masqueraded.


Installation:
--------------
- Must be done as root
- Unpack the tarball
box:~ tar xvfz ratroute-0.2.tar.gz


- Copy the binary and config file

Example:

box:~/ratroute-0.1# cp ratroute /usr/bin
box:~/ratroute-0.1# cp ratroute.conf /etc

- Create symlinks to ratroute
 so that it can trap PPP up/down events

box:~# ln -s /usr/bin/ratroute /etc/ppp/ip-up.d/ratroute
box:~# ln -s /usr/bin/ratroute /etc/ppp/ip-down.d/ratroute

The scripts in /etc/ppp/ip-*.d/ is run by run-parts everytime
a ppp connection is established or torn down on debian systems.

Configuration:
---------------

The sample /etc/ratroute.conf file includes an example to configure
two DSL connections for loadbalanced traffic.

The most crucial part of the configuration for each interface is the
"linkname/ipparam" parameter. This has to exactly match the ipparam
and linkname options in your /etc/ppp/peers/dsl1 configuration file.
Each interface must have unique ipparam/linkname parameters so that
ratroute can figure out on which interface a routing event has been
generated.

Detail of operation:
--------------------

The following example explains the event flow for a debian-like 
system with two interfaces: 'dsl1' and 'dsl2'.

/etc/ppp/ppp_on_boot is run automatically at bootup by
the /etc/init.d/ppp script.

ppp_on_boot in turns activates each of the dsl connections
dsl1, and dsl2 by running 'pon dsl1' or 'pon dsl2'. This starts
the ppp daemon with the appropriate configuration file from 
/etc/ppp/peers which contains the ISP/PPPoE link specific information.
Examples of these can be found in the ppp-peer-samples/ directory
within the tarball.

Important parameters in the peers/* files are the "ipparam" and 
"linkname" parameters. These parameters get passed to ratroute
and is ratroute's only means of identifying the interface on
which the event ocurred. 

Additional boot-up adsl connections can be configured here by
simply adding them to ppp_on_boot.

Apparently the /etc/ppp/ppp_on_boot and /etc/init.d/ppp method
is now deprecated in Debian 3.1 so it would probably be a good
idea to move the startup of these interfaces to /etc/network/interfaces
at some point in the future as described in 
/usr/share/doc/ppp/README.Debian.gz and interfaces(5) man page.

After a PPP connection has been establish, ratroute is triggered
by the symlinks in /etc/ppp/ip-up.d

Various environment variables that have been set by pppd is then
used to determine how to configure the kernel routing table.

In our example, after both PPPoE connections have been established
the kernel routing table will look like this.

The kernel routing table is made up out of 'rules' and 'tables'
Rules, are configured in order of preference.

box:~# ip rule list
0:      from all lookup local 
30:     from 165.146.35.96 lookup dsl1_reverse 
30:     from all lookup dsl1 
31:     from 165.146.46.74 lookup dsl2_reverse 
31:     from all lookup dsl2 
51:     from all lookup main 
52:     from all lookup balancedpool 
32766:  from all lookup main 
32767:  from all lookup default 

The kernel will start looking for routes in the 
various rules by starting at 0.

The 'local' table contains routes to directly attached network interfaces
such as the ethernet network, and the routes to the actual ppp devices 
themselves.

The "dsl1" and "dsl2" rules and their counterpart *_reverse rules
contain routes that are to be direclty handled by each respective
PPP interface. The "_reverse" routes is where the secret of multipath
balanced gateways lie. The reverse rules explain to the kernel that
incoming traffic from an interface needs to be sent back out on the 
same interface, instead of going via the loadbalanced routes.

The 'balancedpool' table contains a multipath loadbalanced route for
the two dsl interfaces. 

These are essentially the default gateways for the system.

box:~# ip route show table balancedpool
default 
        nexthop dev ppp1 weight 1
        nexthop dev ppp0 weight 1

Whenever ratroute detects that an interface has gone down, it will
readjust this balancedpool table to ensure that the dead interface
is removed from the pool. This negates most of the need for kernel
patches for dead-gateway-detection.

When an interface goes down, the ip-down.d symlink to ratroute takes
care of deleting any routes that were added and also removes the dead
gateway from the balancedpool table.

To test whether loadbalancing is actually ocurring:

box:~# ip route get 66.249.85.99
66.249.85.99 dev ppp0  src 165.146.35.96 
    cache  mtu 1492 advmss 1452 hoplimit 64

box:~# ip route get 66.249.85.100
66.249.85.100 dev ppp1  src 165.146.35.96 
    cache  mtu 1492 advmss 1452 hoplimit 64

If loadbalancing is ocurring correctly, then each request for a new
route will cause the kernel to choose a different interface. Note that
once a route has been established, the same route will be preferred
until the route drops out of the route cache, or the route cache is
flushed

To flush the route cache, issue the 'ip route flush cache' command.
Ratroute automatically flushes all routes whenever an interface
event is detected.

Weighting can be assigned to the various interfaces by changing the
values in /etc/ratroute.conf as described in said file.

Files accessed:
-----------
/etc/ratroute.conf
/var/lock/ratroute.lock
/var/state/ratroute.weights
/proc/net/dev

Contact:
----------

email: <rodent at rodent dot za do net>
post:
	Roelf Diedericks
	6 Hagen Road
	Greenside
	2193
	Johannesburg, Gauteng
	Republic of South Africa

