Networking - OSPF Routing with Quagga

Quagga is a very popular open source routing software. It supports all main IGP protocols like RIP, OSFP, IS-IS, also EGP protocol like BGP. Open source Routing I thought it is interesting to try it out…

Quagga software architecture

Quagga Software architecture

The Quagga architecture consists of a core daemon (zebra) which is an abstraction layer to the underlying Unix kernel and presents the Zserv API over a Unix-domain socket or TCP socket to Quagga clients. The Zserv clients typically implement a routing protocol and communicate routing updates to the zebra daemon. Existing Zserv clients are:

  • ospfd, implementing Open Shortest Path First (OSPFv2)
  • bgpd, implementing Border Gateway Protocol (BGPv4+), including address family support for IP multicast and IPv6
  • ripd, implementing Routing Information Protocol (RIP) version 1 and 2;
  • isisd, implementing Intermediate System to Intermediate System (IS-IS)
  • ospf6d, implementing Open Shortest Path First (OSPFv3) for IPv6
  • ripngd, implementing Routing Information Protocol (RIPng) for IPv6
  • pimd, implementing Protocol Independent Multicast (PIM-SSM) for Source-specific multicast

Install Quagga in ubuntu

Qugga source code can be downloaded from http://download.savannah.gnu.org/releases/quagga/. It can be built from source easily. However for popular linux distribution like ubuntu, it already has binary in the main repo. So the life is easier.

Steps to install in ubuntu:

  • sudo apt install quagga quagga-doc
  • Enable linux IPv4 packet forwarding in /etc/sysctl.conf : net.ipv4.ip_forward=1
  • Setup config for quagga:
  1. cp /usr/share/doc/quagga-core/examples/vtysh.conf.sample /etc/quagga/vtysh.conf
  2. cp /usr/share/doc/quagga-core/examples/zebra.conf.sample /etc/quagga/zebra.conf
  3. cp /usr/share/doc/quagga-core/examples/bgpd.conf.sample /etc/quagga/bgpd.conf
  4. cp /usr/share/doc/quagga-core/examples/ospfd.conf.sample /etc/quagga/ospf.conf
  • sudo chown quagga:quagga /etc/quagga/*.conf
  • sudo chown quagga:quaggavty /etc/quagga/vtysh.conf
  • sudo chmod 640 /etc/quagga/*.conf
  • Run zebra and needed routing daemon
    1. sudo service zebra start
    2. sudo service zebra status
    3. sudo service bgpd start
    4. sudo service ospfd start
    5. sudo service bgpd status

“Console” access:

  • zebra: telnet localhost 2601
  • ripd: telnet localhost 2602
  • ripngd: telnet localhost 2603
  • ospfd: telnet localhost 2604
  • bgpd: telnet localhost 2605
  • vtysh: sudo vtysh

the default password is zebra.

Quagga network topology

I created four virtualBox VMs and have internal networks connect them as below:

Quagga test network

Run OSPF using Quagga

Quagga-Master:

xterm# sudo vtysh

Quagga-Master# show running-config 
Building configuration...

Current configuration:
!
hostname Router
hostname ospfd
log stdout
hostname bgpd
hostname Quagga-Master
!
password zebra
enable password zebra
!
interface enp0s3
!
interface enp0s8
 ip address 11.1.1.1/24
!
interface enp0s9
 ip address 22.1.1.1/24
!
interface enp0s10
 ip address 33.1.1.1/24
!
interface lo
!
router bgp 7675
 bgp router-id 33.1.1.1
!
 address-family ipv6
 exit-address-family
 exit
!
router ospf
!
ip forwarding
!
line vty
!
end
Quagga-Master#
Quagga-Master# conf t
Quagga-Master(config)# router ospf
Quagga-Master(config-router)# network 11.1.1.0 
% There is no matched command.
Quagga-Master(config-router)# network 11.1.1.0/24 
  area  Set the OSPF area ID
Quagga-Master(config-router)# network 11.1.1.0/24 area 0
Quagga-Master(config-router)# network 22.1.1.0/24 area 0
Quagga-Master(config-router)# network 33.1.1.0/24 area 0
Quagga-Master(config-router)# end
Quagga-Master# 

Quagga-1:

Quagga-1# show running-config 
Building configuration...

Current configuration:
!
hostname Router
hostname ospfd
log stdout
hostname bgpd
hostname Quagga-1
!
password zebra
enable password zebra
!
interface enp0s3
!
interface enp0s8
 ip address 11.1.1.2/24
!
interface enp0s9
 ip address 111.1.1.1/24
!
interface lo
!
ip forwarding
!
line vty
!
end
Quagga-1# 
Quagga-1# conf t
Quagga-1(config)# router ospf
Quagga-1(config-router)# network 11.1.1.0/24 area 0
Quagga-1(config-router)# network 111.1.1.0/24 area 0
Quagga-1(config-router)# end
Quagga-1# 

Quagga-2:

Quagga-2# show running-config 
Building configuration...

Current configuration:
!
hostname Router
hostname ospfd
log stdout
hostname bgpd
hostname Quagga-2
!
password zebra
enable password zebra
!
interface enp0s3
!
interface enp0s8
 ip address 22.1.1.2/24
!
interface enp0s9
 ip address 122.1.1.1/24
!
interface lo
!
ip forwarding
!
line vty
!
end
Quagga-2# 
Quagga-2# conf t
Quagga-2(config)# router ospf 
Quagga-2(config-router)# network 22.1.1.0/24 area 0
Quagga-2(config-router)# network 122.1.1.0/24 area 0
Quagga-2(config-router)# end
Quagga-2#

Quagga-3:

Quagga-3# show run
Building configuration...

Current configuration:
!
hostname Router
hostname ospfd
log stdout
hostname bgpd
hostname Quagga-3
!
password zebra
enable password zebra
!
interface enp0s3
!
interface enp0s8
 ip address 33.1.1.2/24
!
interface enp0s9
 ip address 133.1.1.1/24
!
interface lo
!
ip forwarding
!
line vty
!
end
Quagga-3# 
Quagga-3# conf t
Quagga-3(config)# router ospf
Quagga-3(config-router)# network 33.1.1.0/24 area 0
Quagga-3(config-router)# network 133.1.1.0/24 area 0
Quagga-3(config-router)# end
Quagga-3# 

Check the routing table and try to ping

Quagga-Master# show ip ospf neighbor 

Neighbor ID     Pri State           Dead Time Address         Interface         
   RXmtL RqstL DBsmL
111.1.1.1         1 Full/Backup       38.280s 11.1.1.2        enp0s8:11.1.1.1   
       0     0     0
22.1.1.2          1 Full/Backup       38.846s 22.1.1.2        enp0s9:22.1.1.1   
       0     0     0
133.1.1.1         1 Full/Backup       38.905s 33.1.1.2        enp0s10:33.1.1.1  
       0     0     0
Quagga-Master# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, N - NHRP,
       > - selected route, * - FIB route

C>* 10.0.2.0/24 is directly connected, enp0s3
O   11.1.1.0/24 [110/10] is directly connected, enp0s8, 00:16:16
C>* 11.1.1.0/24 is directly connected, enp0s8
O   22.1.1.0/24 [110/10] is directly connected, enp0s9, 00:16:10
C>* 22.1.1.0/24 is directly connected, enp0s9
O   33.1.1.0/24 [110/10] is directly connected, enp0s10, 00:16:05
C>* 33.1.1.0/24 is directly connected, enp0s10
O>* 111.1.1.0/24 [110/20] via 11.1.1.2, enp0s8, 00:00:09
C>* 127.0.0.0/8 is directly connected, lo
O>* 133.1.1.0/24 [110/20] via 33.1.1.2, enp0s10, 00:00:02
K>* 169.254.0.0/16 is directly connected, enp0s10
Quagga-Master# 
Quagga-Master# ping 133.1.1.1
PING 133.1.1.1 (133.1.1.1) 56(84) bytes of data.
64 bytes from 133.1.1.1: icmp_seq=1 ttl=64 time=0.379 ms
64 bytes from 133.1.1.1: icmp_seq=2 ttl=64 time=0.330 ms
64 bytes from 133.1.1.1: icmp_seq=3 ttl=64 time=0.345 ms
^C
--- 133.1.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2044ms
rtt min/avg/max/mdev = 0.330/0.351/0.379/0.025 ms
Quagga-Master# ping 22.1.1.1
PING 22.1.1.1 (22.1.1.1) 56(84) bytes of data.
64 bytes from 22.1.1.1: icmp_seq=1 ttl=64 time=0.017 ms
64 bytes from 22.1.1.1: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 22.1.1.1: icmp_seq=3 ttl=64 time=0.030 ms
^C
--- 22.1.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2037ms
rtt min/avg/max/mdev = 0.017/0.025/0.030/0.005 ms
Quagga-Master# 

Quagga-1# show ip ospf neighbor 

Neighbor ID     Pri State           Dead Time Address         Interface         
   RXmtL RqstL DBsmL
33.1.1.1          1 Full/DR           39.851s 11.1.1.1        enp0s8:11.1.1.2   
       0     0     0
Quagga-1# show ip route 
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, N - NHRP,
       > - selected route, * - FIB route

C>* 10.0.2.0/24 is directly connected, enp0s3
O   11.1.1.0/24 [110/10] is directly connected, enp0s8, 00:07:52
C>* 11.1.1.0/24 is directly connected, enp0s8
O>* 22.1.1.0/24 [110/20] via 11.1.1.1, enp0s8, 00:07:42
O>* 33.1.1.0/24 [110/20] via 11.1.1.1, enp0s8, 00:07:42
O   111.1.1.0/24 [110/10] is directly connected, enp0s9, 00:00:10
C>* 111.1.1.0/24 is directly connected, enp0s9
C>* 127.0.0.0/8 is directly connected, lo
O>* 133.1.1.0/24 [110/30] via 11.1.1.1, enp0s8, 00:00:07
K>* 169.254.0.0/16 is directly connected, enp0s8
Quagga-1# ping 133.1.1.1
PING 133.1.1.1 (133.1.1.1) 56(84) bytes of data.
64 bytes from 133.1.1.1: icmp_seq=1 ttl=63 time=0.563 ms
64 bytes from 133.1.1.1: icmp_seq=2 ttl=63 time=0.527 ms
^C
--- 133.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1017ms
rtt min/avg/max/mdev = 0.527/0.545/0.563/0.018 ms
Quagga-1# 

Check the routing table in linux kernel:

Quagga-master VM: we can see it matches with what we see from “show ip route” below:

ubuntu1804-1@ubuntu18041-VirtualBox:~$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    103    0        0 enp0s3
10.0.2.0        0.0.0.0         255.255.255.0   U     103    0        0 enp0s3
11.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 enp0s8
22.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 enp0s9
33.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 enp0s10
111.1.1.0       11.1.1.2        255.255.255.0   UG    20     0        0 enp0s8
133.1.1.0       33.1.1.2        255.255.255.0   UG    20     0        0 enp0s10
link-local      0.0.0.0         255.255.0.0     U     1000   0        0 enp0s10
ubuntu1804-1@ubuntu18041-VirtualBox:~$ 

As we can see, it is pretty easy to set up a linux box as router!