Step 1 Download and install quagga

Download quagga package
sudo apt-get -d install quagga
extract quagga
mkdir ~/quagga
dpkg -x quagga ~/quagga/
copy the executable and libs
#get dependency for ripd
vic@vicubuntu:~/uml/usr/lib/quagga$ ldd ripd
        linux-gate.so.1 =>  (0x0095d000)
        libzebra.so.0 => not found
        libcap.so.2 => /lib/libcap.so.2 (0x00394000)
        libcrypt.so.1 => /lib/tls/i686/cmov/libcrypt.so.1 (0x0025b000)
        libpcreposix.so.3 => /usr/lib/libpcreposix.so.3 (0x003b5000)
        librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x00745000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00ad3000)
        libattr.so.1 => /lib/libattr.so.1 (0x00547000)
        libpcre.so.3 => /lib/libpcre.so.3 (0x00182000)
        libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x008f2000)
        /lib/ld-linux.so.2 (0x0044d000)
 
#now cp them to the corresponding folder of UML instance
cp /home/vic/quagga/usr/lib/libzebra.so.0 ~/uml/lib/
cp /lib/libcap.so.2 ~/uml/lib/
cp /lib/tls/i686/cmov/libcrypt.so.1 ~/uml/lib/
cp /usr/lib/libpcreposix.so.3 ~/uml/lib/
cp /lib/tls/i686/cmov/librt.so.1 ~/uml/lib/
cp /lib/tls/i686/cmov/libc.so.6 ~/uml/lib/
cp /lib/libattr.so.1 ~/uml/lib/
cp /lib/libpcre.so.3 ~/uml/lib/
cp /lib/tls/i686/cmov/libpthread.so.0 ~/uml/lib/
cp /lib/ld-linux.so.2 ~/uml/lib/
 
#get dependency for zibra
vic@vicubuntu:~/uml/usr/lib/quagga$ ldd zebra
        linux-gate.so.1 =>  (0x0086b000)
        libcap.so.2 => /lib/libcap.so.2 (0x00903000)
        libzebra.so.0 => not found
        libcrypt.so.1 => /lib/tls/i686/cmov/libcrypt.so.1 (0x00673000)
        libpcreposix.so.3 => /usr/lib/libpcreposix.so.3 (0x00159000)
        librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x00242000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x0024b000)
        libattr.so.1 => /lib/libattr.so.1 (0x0087e000)
        libpcre.so.3 => /lib/libpcre.so.3 (0x00110000)
        libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x003c8000)
        /lib/ld-linux.so.2 (0x004ee000)
 
#cp the libs, though some are overlapping
cp /home/vic/quagga/usr/lib/libzebra.so.0 ~/uml/lib/
cp /lib/libcap.so.2 ~/uml/lib/
cp /lib/tls/i686/cmov/libcrypt.so.1 ~/uml/lib/
cp /usr/lib/libpcreposix.so.3 ~/uml/lib/
cp /lib/tls/i686/cmov/librt.so.1 ~/uml/lib/
cp /lib/tls/i686/cmov/libc.so.6 ~/uml/lib/
cp /lib/libattr.so.1 ~/uml/lib/
cp /lib/libpcre.so.3 ~/uml/lib/
cp /lib/tls/i686/cmov/libpthread.so.0 ~/uml/lib/
cp /lib/ld-linux.so.2 ~/uml/lib/
 
#cp the libness files to provide account management
cp /lib/tls/i686/cmov/libnss_files-2.11.1.so ~/uml/lib/
cp /lib/tls/i686/cmov/libnss_files.so.2 ~/uml/lib/

I add user quagga in /etc/passwd and group quaggavty and quagga in /etc/group, and make zebra.conf under /etc/quagga/ then try to start zebra again (See int the error section below)

Now it looks fine, but the process does not show up, after digging it is the double mounted /var that is bothering me. I changed the code as following and run quagga successfully.

.
mount -a
mkdir -p /var/run /var/lock /var/log /var/tmp /var/run/quagga
chmod 777 /var/* /var/run/quagga
mount none /logfile -t hostfs -o /home/vic/umlvar
.

The /var is now mounted in rcS following the instruction in fstab (ramfs) . Hence, all the folders under it have to be recreated everything. I created another folder specifically for the dump files in UML instance folder /logfile and mount hostfs /home/vic/umlvar to it. And now everything works well.

/ # telnet 0 2602
 
Entering character mode
Escape character is '^]'.
 
 
Hello, this is Quagga (version 0.99.15).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
 
 
User Access Verification
 
Password: 
ripd> en
Password: 
ripd# show ru
 
Current configuration:
!
hostname ripd
password zebra
enable password zebra
log file /var/log/ripd1.log
log stdout
!
router rip
 version 1
 redistribute connected
 network eth0
 network eth1
 network eth2
!
line vty
!
end

As shown above, the RIP v1 is working on my routers

Errors

Error 1
cannot start quagga after all the lib are copied.

/usr/lib/quagga # ./zebra
privs_init: could not lookup user quagga

To solve this problem, I have to make a passwd file with user quagga and root in it. /etc/passwd as shown below was made in UML instance

quagga:x:115:123:Quagga routing suite,,,:/var/run/quagga/:/bin/false
root:x:0:0:root:/root:/bin/bash

Then another similar problem occurs, and solved similarly with a file named group as shown also below

#This is the error message for vty group
/etc/init.d # /usr/lib/quagga/zebra 
privs_init: could not lookup vty group quaggavty
 
#This is the group file for solving the vty group problem
quaggavty:x:122:
quagga:x:123:
root:x:0:

Error 2
The libs files should always be copied to /lib instead of /usr/lib. The folder quagga installation would like to us it indeed /usr/lib, but in our simple setup of UML, we alway use /lib unless specifically defined.

Step 2 Adapt the host script and rcS for the test

host script

After revise the host script now looks like

.
      router)
        sw1=$4
        ip1=$5
        mask1=$6
        br1=$7
        pro=$8
        ver=$9
 
        if [ -z "$10" ]; then 
echo "screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname eth0=daemon,,unix,$switchhome/$sw1.ctl ip_eth0=$ip1 mask_eth0=$mask1 bc_eth0=$br1 pro=$pro ver=$ver role=$role"
        screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname eth0=daemon,,unix,$switchhome/$sw1.ctl ip_eth0=$ip1 mask_eth0=$mask1 bc_eth0=$br1 pro=$pro ver=$ver role=$role
        else
          sw2=$8
          ip2=$9
          mask2=$10
          br2=$11
          pro=$12
          ver=$13
          if [ -z "$14" ]; then
            screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ rw umlid=$hostname hostname=$hostname eth0=daemon,,unix,$switchhome/$sw1.ctl ip_eth0=$ip1 mask_eth0=$mask1 bc_eth0=$br1 eth1=daemon,,unix,$switchhome/$sw2.ctl ip_eth1=$ip2 mask_eth1=$mask2 bc_eth1=$br2 pro=$pro ver=$ver role=$role
          else
            sw3=$12
            ip3=$13
            mask3=$14
            br3=$15
            pro=$16
            ver=$17
            if [ -z "$18" ]; then
              screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname eth0=daemon,,unix,$switchhome/$sw1.ctl ip_eth0=$ip1 mask_eth0=$mask1 bc_eth0=$br1 eth1=daemon,,unix,$switchhome/$sw2.ctl ip_eth1=$ip2 mask_eth1=$mask2 bc_eth1=$br2 eth2=daemon,,unix,$switchhome/$sw3.ctl ip_eth2=$ip3 mask_eth2=$mask3 bc_eth2=$br3 pro=$pro ver=$ver role=$role
            else
              sw4=$16
              ip4=$17
              mask4=$18
              br4=$19
              pro=$20
              ver=$21
              screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname eth0=daemon,,unix,$switchhome/$sw1.ctl ip_eth0=$ip1 mask_eth0=$mask1 bc_eth0=$br1 eth1=daemon,,unix,$switchhome/$sw2.ctl ip_eth1=$ip2 mask_eth1=$mask2 bc_eth1=$br2 eth2=daemon,,unix,$switchhome/$sw3.ctl ip_eth2=$ip3 mask_eth2=$mask3 bc_eth2=$br3 eth3=daemon,,unix,$switchhome/$sw4.ctl ip_eth3=$ip4 mask_eth3=$mask4 bc_eth3=$br4 pro=$pro ver=$ver role=$role
            fi
          fi
        fi
        if [ $pro = "rip" ] && [ $ver = "1" ]; then
          cp -P ~/uml/etc/quagga/ripd1.conf ~/uml/etc/quagga/ripd.conf
        fi
        if [ $pro = "rip" ] && [ $ver = "2" ]; then
          cp -P ~/uml/etc/quagga/ripd2.conf ~/uml/etc/quagga/ripd.conf
        fi
 
        echo "router $hostname started"
      ;;
.
.

The major addition is the last part of the above (earlier part is copied from section of host). The code now will ask for protocol going to be used (rip, ospf and so on), and last part of it will cp the corresponding configuration files according different version number of RIP. I use option -P here to reserve the permission.

I also changed the host part, to let it accept one more parameter which is the default gateway.

configuration file

configuration I use to start the router is shown below, complete configuration will be attached in later sections when the specific network is concerned.

./netstart start router routera swa 20.0.0.1 255.0.0.0 20.255.255.255 coreab 10.0.0.1 255.0.0.0 10.255.255.255 coreac 192.168.1.17 255.255.255.240 192.168.1.31 rip 1

It mostly resembles the syntax for starting up a host, only two more options for routing protocol and version number are added at the end.

rcS (UML instance)

The router is implemented in rcS as following

router)
        echo "router $hostname"
        if [ ! -z $ip_eth0 ] && [ ! -z $mask_eth0 ] && [ ! -z $bc_eth0 ];
        then
          ifconfig eth0 $ip_eth0 netmask $mask_eth0 broadcast $bc_eth0 up
        fi
        if [ ! -z $ip_eth1 ] && [ ! -z $mask_eth1 ] && [ ! -z $bc_eth1 ];
        then
          ifconfig eth1 $ip_eth1 netmask $mask_eth1 broadcast $bc_eth1 up
        fi
        if [ ! -z $ip_eth2 ] && [ ! -z $mask_eth2 ] && [ ! -z $bc_eth2 ];
        then
          ifconfig eth2 $ip_eth2 netmask $mask_eth2 broadcast $bc_eth2 up
        fi
        if [ ! -z $ip_eth3 ] && [ ! -z $mask_eth3 ] && [ ! -z $bc_eth3 ];
        then
          ifconfig eth3 $ip_eth3 netmask $mask_eth3 broadcast $bc_eth3 up
        fi
        echo "1" > /proc/sys/net/ipv4/ip_forward
        /etc/init.d/quagga start  
        echo "INFO: $pro $ver started"

Same as in the host script, the earlier part is shared. And the later part enable ip_forwarding as needed by routing and start the quagga. I only have to call the quagga start-stop function and RIP will be started by quagga as configured in ~uml/etc/quagga/daemon.

Step 3 Network 1 RIP v1

configuration for network 1
#!/bin/sh
 
#start switches in hub mode first
./netstart start hub swa
./netstart start hub swb
./netstart start hub swc
./netstart start hub coreab
./netstart start hub coreac
./netstart start hub corebc
 
#start sniffers
./netstart start sniffer sniffera swa
./netstart start sniffer snifferb swb
./netstart start sniffer snifferc swc
./netstart start sniffer snifferab coreab
./netstart start sniffer snifferac coreac
./netstart start sniffer snifferbc corebc
 
#start hosts
./netstart start host hosta swa 20.0.0.2 255.0.0.0 20.255.255.255 20.0.0.1
./netstart start host hostb swb 30.0.0.2 255.0.0.0 30.255.255.255 30.0.0.1
./netstart start host hostc swc 40.0.0.2 255.0.0.0 40.255.255.255 40.0.0.1
 
 
#start routers
 
./netstart start router routera swa 20.0.0.1 255.0.0.0 20.255.255.255 coreab 10.0.0.1 255.0.0.0 10.255.255.255 coreac 192.168.1.17 255.255.255.240 192.168.1.31 rip 1
./netstart start router routerb swb 30.0.0.1 255.0.0.0 30.255.255.255 coreab 10.0.0.2 255.0.0.0 10.255.255.255 corebc 192.168.1.33 255.255.255.240 192.168.1.47 rip 1
./netstart start router routerc swc 40.0.0.1 255.0.0.0 40.255.255.255 coreac 192.168.1.18 255.255.255.240 192.168.1.31 corebc 192.168.1.34 255.255.255.240 192.168.1.47 rip 1

Step 3 Network 1 RIP v2

configuration
./netstart start router routera swa 20.0.0.1 255.0.0.0 20.255.255.255 coreab 10.0.0.1 255.0.0.0 10.255.255.255 coreac 192.168.1.17 255.255.255.240 192.168.1.31 rip 2
./netstart start router routerb swb 30.0.0.1 255.0.0.0 30.255.255.255 coreab 10.0.0.2 255.0.0.0 10.255.255.255 corebc 192.168.1.33 255.255.255.240 192.168.1.47 rip 2
./netstart start router routerc swc 40.0.0.1 255.0.0.0 40.255.255.255 coreac 192.168.1.18 255.255.255.240 192.168.1.31 corebc 192.168.1.34 255.255.255.240 192.168.1.47 rip 2

Only have to change the version number to 2.

RIP running configuration
Current configuration:
!
hostname ripd
password zebra
enable password zebra
log file /var/log/ripd1.log
log stdout
!
router rip
 version 2
 redistribute connected
 network eth0
 network eth1
 network eth2
!
line vty
!
end