Linux Core as Router and L3 Switch Appliance

The tutorial introduces  a virtual router and layer3 switch appliance based on Linux Core.  The appliance is basically Linux Core installed on Vmware virtual machine loaded with Open vSwitch extension and two routing daemon extensions - Quagga and Bird. The disk also contains several  extensions useful for testing network such as d-itg, hping3 and others. The list of available extension is here.

As the Open vSwitch installation is introduced in this tutorial I will focus more on Quagga and Bird installation and initial configuration. Installation of router redundancy protocol VRRP represented by Keepalived extension is also covered in the tutorial and the Keepalived extension is included in the vmdk image.

The VMware disk image is available in Download section.

1. Quagga Routing Daemon Installation and Configuration

Quagga is IPv4 and IPv6 routing software suite, GPL licensed.  I submitted Quagga extension to Core Linux repository so it should be easy to download and install it with a single command:

tce-load -wi quagga

In case you built Quagga extension yourself some extra steps are needed  to achieve extension persistency after installation. First add quagga extension to the list of extensions loaded after Core boot.

$ echo "quagga.tcz" >>/mnt/sda1/tce/onboot.lst

Then copy these three files.

$ cp quagga.tcz  quagga.tcz.dep   quagga.tcz.md5.txt /mnt/sda1/tce/optional/

1.1 Create Configuration Files for Zebra and Routing Daemons

Each routing daemon needs to have its own configuration file. At least password must be set for telnet connection to daemon.

$ sudo su
# echo "password quagga" > /usr/local/etc/quagga/zebra.conf
# echo "password quagga" > /usr/local/etc/quagga/vtysh.conf
# echo "password quagga" > /usr/local/etc/quagga/ripd.conf
# echo "password quagga" > /usr/local/etc/quagga/ripngd.conf
# echo "password quagga" > /usr/local/etc/quagga/ospfd.conf
# echo "password quagga" > /usr/local/etc/quagga/ospf6d.conf
# echo "password quagga" > /usr/local/etc/quagga/bgpd.conf
# echo "password quagga" > /usr/local/etc/quagga/isisd.conf
# echo "password quagga" > /usr/local/etc/quagga/babeld.conf

1.2 Create Directory for PID Files

Create a directory /usr/local/var/quagga that stores PID of the Quagga routing daemons. Change the ownership of the directory for a user tc and a group staff in case Quagga is compiled with the user tc option.

If a user and a group is not specified during configuration of Quagga the default user quagga and the group quagga is used. In this case the ownership for the user quagga and the group quagga must be also set for the directory.

$ sudo mkdir /usr/local/var/quagga
$ sudo chown tc:staff /usr/local/var/quagga

Make directory persistent after boot of Core.

$ echo "/usr/local/var/quagga" >> /opt/.filetool.lst

1.3 Start Routing Daemons Running After Boot of Core

$ sudo su
# echo "/usr/local/sbin/zebra -u root -d -f /usr/local/etc/quagga/zebra.conf" >> /opt/
# echo "/usr/local/sbin/ripd -u root -d -f /usr/local/etc/quagga/ripd.conf" >> /opt/
# echo "/usr/local/sbin/ripngd -u root -d -f /usr/local/etc/quagga/ripngd.conf" >> /opt/
# echo "/usr/local/sbin/ospfd -u root -d -f /usr/local/etc/quagga/ospfd.conf" >> /opt/
# echo "/usr/local/sbin/ospf6d -u root -d -f /usr/local/etc/quagga/ospf6d.conf" >> /opt/
# echo "/usr/local/sbin/bgpd -u root -d -f /usr/local/etc/quagga/bgpd.conf" >> /opt/
# echo "/usr/local/sbin/isisd -u root -d -f /usr/local/etc/quagga/isisd.conf" >> /opt/
# echo "/usr/local/sbin/babeld -u root -d -f /usr/local/etc/quagga/babeld.conf" >> /opt/

All the routing daemons will be started after boot of Linux Core. If you are not going to use all routing protocol add only a particular daemon to the file /opt/ It helps to save memory and CPU (about 2 MB for each daemon).

Add Quagga configuration files to the list of persistent  files.

$ echo "/usr/local/etc/quagga" >> /opt/.filetool.lst

Finally, save the configuration

/usr/bin/ -b

1.4 Quagga Operation

Each routing daemon listens  on dedicated port and has its dedicated configuration file:

zebra 2601/tcp # Zebra vty
ripd 2602/tcp # RIPd vty
ripngd 2603/tcp # RIPngd vty
ospfd 2604/tcp # OSPFd vty
bgpd 2605/tcp # BGPd vty
ospf6d 2606/tcp # OSPF6d vty
ospfapi 2607/tcp # ospfapi
isisd 2608/tcp # ISISd vty
babeld 2609/tcp # Babeld vty

Enter a telnet command and the port on which is daemon listening.  For example to configure hostname, static route, IP addresses,  use the telnet to connect to zebra daemon.

$ telnet localhost 2601

If Quagga is compiled with parameter --enable-vtysh we can use integrated user interface shell called vtysh. Vtysh connects to each daemon with UNIX domain socket and then works as a proxy for user input.

Note: It is strongly advised to call command /usr/bin/ -b once you finished your configuration in order to instruct Core to keep changes in deamon configuration otherwise your configuration will be lost after reboot of Core Linux.

1.5  Enable IPv4 and IPv6 Packets Forwarding Between Interfaces

Forwarding is disabled by default between network interfaces. To activate ipv4 and ipv6 forwarding we have to configure following:

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1

$ echo "sysctl -w net.ipv4.ip_forward=1" >> /opt/
$ echo "sysctl -w net.ipv6.conf.all.forwarding=1" >> /opt/

$ /usr/bin/ -b

After reboot you can check if ipv4 and ipv6 forwarding is enabled (value 1).

systcl -a | grep forward

1.6 Quagga Troubleshooting

If  you invoke zebra command and you get the message below Quagga was compiled without specifying user and group and it uses the default username quagga and the group quagga.

privs_init: could not lookup user quagga

We can solve it either by creating a required user and group or specifying appropriate user with parameter --user and group with parameter --group during start of a daemon.

2. Bird Routing Daemon Installation and Configuration

Bird is another popular IPv4 and IPv6 routing daemon so I decided to load Core Linux virtual machine with the bird extension. Extension can be downloaded and installed with a single command:

$ tce-load -wi bird.tcz

The Bird extension contains both IPv4 and IPv6 bird routing daemons and remote controls. First, create configuration files for bird and bird6.

$ sudo su

# mkdir /usr/local/etc/bird/

# cp /usr/local/etc/bird.conf  /usr/local/etc/bird/bird.conf.
# cp /usr/local/etc/bird6.conf  /usr/local/etc/bird6.conf

# rm /usr/local/etc/bird.conf
# rm /usr/local/etc/bird6.conf

Set router ID for IPv6 manually otherwise bird6 daemon refuses to start.

# echo "router id;" >> /usr/local/etc/bird/bird6.conf 

Then configure Core to start IPv4 and IPv6 bird routing daemons after boot.

$ echo "/usr/local/sbin/bird -c /usr/local/etc/bird/bird.conf -u root" >> /opt/
$ echo "/usr/local/sbin/bird6 -c /usr/local/etc/bird/bird6.conf -u root" >> /opt/

Finally,  add configuration directory to the list of persistent Core files and save configuration.

$ echo "/usr/local/etc/bird/" >> /opt/.filetool.lst
$ /usr/bin/ -b

3. VRRP Stack Installation and Configuration

VRR /Virtual Router Redundancy Protocol/ is implemented as a part of keepalived project which brings keepalive facility to the Linux  Virtual Server project.

3.1 Keepalived installation

tce-load -wi keepalived

Create keepalived directory, configuration file and script for restarting VRRP daemon - child of keepalived daemon.

$ sudo su
# mkdir /usr/local/etc/keepalived/
# touch /usr/local/etc/keepalived/keepalived.conf

# vi /usr/local/sbin/


pid=$(cat /var/run/
sudo kill $pid

# chmod +x /usr/local/sbin/

Save configuration directory and make keepalived started during Micocore boot.  Parameter -p means only VRRP subsystem is started.

$ echo "/usr/local/etc/keepalived/" >> /opt/.filetool.lst
$ echo "/usr/local/sbin/" >> /opt/.filetool.lst
$ echo "/usr/local/sbin/keepalived -P -l -f /usr/local/etc/keepalived/keepalived.conf" >> /opt/
$ /usr/bin/ -b



11 thoughts on “Linux Core as Router and L3 Switch Appliance

    • It is a good idea to have LiSA, Quagga and other networking staff merged in to Microcore Router. To be honest I wasn't successful with LiSA installation from sources last summer - I was able to build patched CentOS kernel from git repository but userspace didn't work. Since then I have been too busy to try it again.
      I was talking with LiSA developer in January this year and he said that would like to move from patched kernel to normal Linux kernel. If they do it I'll install LiSA to Microcore.

  1. Thanks Brezular for the good documentation as usual. Keep up the good job. :)
    I'm having a problem to install it on Core. Does the extension still available?

    tc@box:/opt$ tce-load -iw quagga
    Downloading: quagga.tcz
    Connecting to (
    wget: server returned error: HTTP/1.1 404 Not Found
    md5sum: quagga.tcz.md5.txt: No such file or directory
    Error on quagga.tcz

    • Hi,
      unfortunately the Quagga extension is not available in 7.x repository. If you want to compile Quagga by your own, I can send installation steps to your email. You can also download my vmdk image containing Quagga 0.99.24-rc1 extension with EIGRP support, compiled for x64 CoreLinux 7.2 here

  2. Yeah, that would be great.. Thanks Radovan Brezula I really appreciate it.
    And thanks for all contents in this site ... it is very helpful and easy to understand

Leave a comment

Your email address will not be published. Required fields are marked *