EIGRP Routing on Linux via Free Range Routing

Background

If you are familiar with networking on Linux, you may know of the Quagga project, which is an old open source project that implemented some routing protocols. You may also have heard that a cool company called Cumulus Linux forked Quagga into an open source project they call “Free Range Routing” (Their github page has the most recent code, the project page has more info, and their documentation is extensive) . They have taken the development of the project into high gear and implemented many new features, new protocols, and generally gone above and beyond the original Quagga project which had seen little to no development activity for years.

While you may be able to find some binary packages out there, building from source is the best way to get the most recent code and the most recent features. However building from source can be time consuming if your not familiar with the project and/or the process of building from source. If you just want to poke around a little bit or do some testing, there is a nice alternative using Ubuntu’s “snap” technology. Snaps are kind of like containers, although they’re different from Docker or LXC. The idea is to package up all the libraries the application needs so it can run on any Linux distribution that can run the snap daemon. Stability, portability, and ease of installation are the goal. You can check out more about snap at the Snapcraft page.

Free Range Routing offers snaps through the snap store and installation is downright easy.

If you’re familiar with Cisco technologies, you may know that their proprietary (and yes, it’s still proprietary) routing protocol EIGRP is only available on Cisco devices. In 2013 Cisco published a draft RFC detailing how to implement EIGRP, opening the gate for anyone interested to implement it. There were a few attempts to add it on to Quagga, however none of them really got past alpha stage. Free Range Routing is the first major attempt to implement it, although it’s still in experimental stage. Installing the Free Range Routing snap will get you the latest EIGRP code, and you can run it on your Linux box.

Installation

There is a readme specific to installing the snap package that comes when you install the snap itself, but it’s at the Github page as well of course.

Ubuntu 18.04

Make sure to update, and install snapd:

sudo apt update
sudo apt install snapd

Then install the frr snap:

sudo snap install frr

Then you’ll need to give it permission to control the network:

snap connect frr:network-control core:network-control

Restart your box to finish.

Topology

Pretty simple idea here. We want PC1 to be able to reach PC2. There are no routes in place, so that’s where EIGRP comes in. The Ubuntu box doesn’t know about 172.16.0.0/24 and the Cisco IOSv Router doesn’t know about 192.168.0.0/24, and we’ll use EIGRP to tell each router about those networks. This blog assumes IPv4 routing has been enabled on the Ubuntu box and IP addresses have been configured on the interfaces shown.

Configuration

Ubuntu 18.04

You’ll find the snap files under “/snap”, so cd to “/snap/bin” where you’ll find all the frr stuff. Most importantly you’ll find frr.vtysh which is the command line interface for frr. Running that will take you into the frr CLI, or you can use an absolute path to it:

sudo /snap/bin/frr.vtysh

You’ll be greeted with the frr CLI which is very Cisco-like and based on the original Quagga CLI. You can configure EIGRP using Cisco-like commands:

#conf t
(config)#
(config-router)#network 192.168.0.0/24
(config-router)#network 172.16.0.0/24
(config-router)#end
#

CiscoIOSv15.6(2)T-1

I’ve abbreviated the output of my show run a bit to make things more readable:

interface GigabitEthernet0/0
 ip address 10.0.0.2 255.255.255.252
!
interface GigabitEthernet0/1
 ip address 172.16.0.1 255.255.255.0
!        
router eigrp 10
 network 10.0.0.0 0.0.0.3
 network 172.16.0.0 0.0.0.255

Verification

Ubuntu 18.04

You can use the same show commands within the frr CLI to see if you’re getting routes:

# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

E   10.0.0.0/30 [90/28160] is directly connected, eth0, 00:43:35
C>* 10.0.0.0/30 is directly connected, eth0, 00:46:38
E>* 172.16.0.0/24 [90/5376] via 10.0.0.2, eth0, 00:42:36
E   192.168.0.0/24 [90/28160] is directly connected, eth1, 00:42:47
C>* 192.168.0.0/24 is directly connected, eth1, 00:45:56
# 

Of course you can always drop out with “exit” to the Bash shell and do “ip route”:

$ip route
10.0.0.0/30 dev eth0 proto kernel scope link src 10.0.0.1 
172.16.0.0/24 via 10.0.0.2 dev eth0 proto 192 metric 20 
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.1 
$ 

CiscoIOSv15.6(2)T-1

It’s nice when the commands are the same (similar) everywhere.

Router#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override, p - overrides from PfR

Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        10.0.0.0/30 is directly connected, GigabitEthernet0/0
L        10.0.0.2/32 is directly connected, GigabitEthernet0/0
      172.16.0.0/16 is variably subnetted, 2 subnets, 2 masks
C        172.16.0.0/24 is directly connected, GigabitEthernet0/1
L        172.16.0.1/32 is directly connected, GigabitEthernet0/1
D     192.168.0.0/24 [90/28416] via 10.0.0.1, 00:44:51, GigabitEthernet0/0
Router#

Finally, make sure PC1 can ping PC2:

PC1> ping 172.16.0.2
84 bytes from 172.16.0.2 icmp_seq=1 ttl=62 time=1.843 ms
84 bytes from 172.16.0.2 icmp_seq=2 ttl=62 time=1.879 ms
84 bytes from 172.16.0.2 icmp_seq=3 ttl=62 time=1.904 ms
84 bytes from 172.16.0.2 icmp_seq=4 ttl=62 time=1.906 ms

EIGRP on Linux!