Some weeks ago I have been using a self-baked FRR routing appliance for the GNS3 network emulator in the blog article FRR basic IS-IS router configuration. Recently after reading the FRR release notes, I have noticed that alpine linux offers recent FRR binaries in its testing repository.

Building a tiny FRR appliance from scratch is a complex task. The available virtual appliances in the GNS Marketplace are either to old or need much more resources.

Download an x86 ISO file from the official alpine linux website, or use the direct link to the x86 ISO file.

wget http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86/alpine-virt-3.11.0-x86.iso

Create an empty disk image file for the virtual guest installation. Here qcow2 is used. The qcow file is only 1GB large, and the resulting installation will be not more than 175MB:

 qemu-img create -f qcow2 alpine-frr7.qcow2 1G

After the diskfile has been created, use QEMU to boot the downloaded iso file. Enable serial port redirection to a localhost TCP port 4321:

qemu-system-i386 -boot d -cdrom ~/Downloads/alpine-virt-3.10.3-x86.iso -hda ~/GNS3/images/qemu/alpine-frr7.qcow2 -enable-kvm -m 1G -serial telnet:localhost:4321,server,nowait

Connect to serial port redirected to port 4321 on localhost, for username use root, password is hitting the enter ke and enable serial port redirection to a localhost port 4321.

telnet localhost 4321
Trying ::1...      
Connected to localhost.
Escape character is '^]'.

Welcome to Alpine Linux 3.11
Kernel 5.4.5-0-virt on an i686 (/dev/ttyS0)

localhost login: root
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org/>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

localhost:~# 

This is the initial installation sequence as it displayed in the command line interface. Your personal setup will be a little longer, some self explaining steps are skipped for brevity.

setup-alpine

Select keyboard layout [de]

Select keyboard variant [de]

Select hostname [frr]

Which one do you want to initialize? (or '?' or 'done') [eth0]

IP address for eth0? (or 'dhcp', 'none', '?') [dhcp]

Do you want to do any manual network configuration? [no] no

Changing password for root

Which timezone are you in? ('?' for list) [Europe/Berlin]

HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]

Enter mirror number (1-46) or URL to add (or r/f/e/done) [r]

Available disks are:
  sda   (1.1 GB ATA      QEMU HARDDISK   )
Which disk(s) would you like to use? (or '?' for help or 'none') [none] sda

The following disk is selected:
  sda   (1.1 GB ATA      QEMU HARDDISK   )

How would you like to use it? ('sys', 'data', 'lvm' or '?' for help) [?] sys

WARNING: Erase the above disk(s) and continue? [y/N]: y

Installation is complete. Please reboot.

Use the halt command to stop the virtual guest. Now the virtual guest needs to be booted from the just installed virtual disk. Below the command to run the raw linux alpine installation for further mastering:

qemu-system-i386 -boot c -hda ~/GNS3/images/qemu/frr.qcow2 -enable-kvm -m 1G -serial telnet:localhost:4321,server,nowait -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 &

After successful first boot update the repository using the apk tool:

apk update

The latest FRR packages are available in the alpine testing repositories. Edit the repositories file:

vi /etc/apk/repositories

Replace last entry and remove the '#' hash in the last line. This is how the file is supposed to be looking after the change:

#/media/cdrom/apks
http://dl-cdn.alpinelinux.org/alpine/v3.11/main
#http://dl-cdn.alpinelinux.org/alpine/v3.11/community
#http://dl-cdn.alpinelinux.org/alpine/edge/main
#http://dl-cdn.alpinelinux.org/alpine/edge/community
http://dl-cdn.alpinelinux.org/alpine/edge/testing

Update the repository once again to get the FRR binaries:

apk update

Now install the latest FRR packages:

apk add frr sudo mtr

Now configure the FRR package. Edit the /etc/frr/daemons file and replace following entries. This is optional over here, f.e. I do not want to have VRRP, BFD, PBR, SHARP, and NHRPD, started by default. The default entries have =no

bgpd=yes
ospfd=yes
ospf6d=yes
ripd=yes
ripngd=yes
isisd=yes
pimd=yes
ldpd=yes
nhrpd=no
eigrpd=yes
babeld=yes
sharpd=no
pbrd=no
bfdd=no
fabricd=yes
vrrpd=no

Start the FRR daemon:

/etc/init.d/frr start

Verify the routing daemon applications are running by using either ss or netstat:

frr:~# ss -tulpen
Netid   State    Recv-Q   Send-Q     Local Address:Port     Peer Address:Port   Process                                                                         
tcp     LISTEN   0        3              127.0.0.1:2608          0.0.0.0:*       users:(("isisd",pid=2370,fd=11)) uid:100 ino:6219 sk:1 <->
tcp     LISTEN   0        3              127.0.0.1:2609          0.0.0.0:*       users:(("babeld",pid=2373,fd=10)) uid:100 ino:6235 sk:2 <->
tcp     LISTEN   0        3              127.0.0.1:2611          0.0.0.0:*       users:(("pimd",pid=2376,fd=12)) uid:100 ino:6254 sk:3 <->
tcp     LISTEN   0        3              127.0.0.1:2612          0.0.0.0:*       users:(("ldpd",pid=2382,fd=17)) uid:100 ino:6290 sk:4 <->
tcp     LISTEN   0        3              127.0.0.1:2613          0.0.0.0:*       users:(("eigrpd",pid=2386,fd=11)) uid:100 ino:6322 sk:5 <->
tcp     LISTEN   0        128              0.0.0.0:22            0.0.0.0:*       users:(("sshd",pid=2073,fd=3)) ino:5916 sk:6 <->                   
tcp     LISTEN   0        3              127.0.0.1:2616          0.0.0.0:*       users:(("staticd",pid=2389,fd=11)) uid:100 ino:6340 sk:7 <->
tcp     LISTEN   0        3              127.0.0.1:2618          0.0.0.0:*       users:(("fabricd",pid=2392,fd=11)) uid:100 ino:6358 sk:8 <->
tcp     LISTEN   0        3              127.0.0.1:2601          0.0.0.0:*       users:(("zebra",pid=2347,fd=19)) uid:100 ino:6101 sk:9 <->
tcp     LISTEN   0        3              127.0.0.1:2602          0.0.0.0:*       users:(("ripd",pid=2358,fd=11)) uid:100 ino:6145 sk:a <->
tcp     LISTEN   0        3              127.0.0.1:2604          0.0.0.0:*       users:(("ospfd",pid=2364,fd=12)) uid:100 ino:6182 sk:b <->
tcp     LISTEN   0        3              127.0.0.1:2605          0.0.0.0:*       users:(("bgpd",pid=2351,fd=17)) uid:100 ino:6123 sk:c <->           
tcp     LISTEN   0        3                  [::1]:2606             [::]:*       users:(("ospf6d",pid=2367,fd=12)) uid:100 ino:6201 sk:d v6only:1 <->           
tcp     LISTEN   0        128                 [::]:22               [::]:*       users:(("sshd",pid=2073,fd=4)) ino:5918 sk:e v6only:1 <->                      
tcp     LISTEN   0        3                  [::1]:2603             [::]:*       users:(("ripngd",pid=2361,fd=11)) uid:100 ino:6163 sk:f v6only:1 <->

Daemon verification using netstat:

root # netstat -tulpen

Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2608 0.0.0.0:* LISTEN 2370/isisd tcp 0 0 127.0.0.1:2609 0.0.0.0:* LISTEN 2373/babeld tcp 0 0 127.0.0.1:2611 0.0.0.0:* LISTEN 2376/pimd tcp 0 0 127.0.0.1:2612 0.0.0.0:* LISTEN 2382/ldpd tcp 0 0 127.0.0.1:2613 0.0.0.0:* LISTEN 2386/eigrpd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2073/sshd tcp 0 0 127.0.0.1:2616 0.0.0.0:* LISTEN 2389/staticd tcp 0 0 127.0.0.1:2618 0.0.0.0:* LISTEN 2392/fabricd tcp 0 0 127.0.0.1:2601 0.0.0.0:* LISTEN 2347/zebra tcp 0 0 127.0.0.1:2602 0.0.0.0:* LISTEN 2358/ripd tcp 0 0 127.0.0.1:2604 0.0.0.0:* LISTEN 2364/ospfd tcp 0 0 127.0.0.1:2605 0.0.0.0:* LISTEN 2351/bgpd tcp 0 0 ::1:2606 :::* LISTEN 2367/ospf6d tcp 0 0 :::22 :::* LISTEN 2073/sshd tcp 0 0 ::1:2603 :::* LISTEN 2361/ripngd

nano /boot/extlinux.conf

Add following lines to the APPEND section, this will display the boot messages to the VGA and the serial console:

...
APPEND quiet console=ttyS0,115200
...

Enabling a login console is done in the /etc/inittab file.

vi /etc/inittab

The last entry for ttyS0 is found in the last line of that file. Just add the 115200 to it, and save the file:

# Put a getty on the serial port
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100

Explanation. The 115200 is the serial console bandwidth in baud. It is set here in this installation to its maximum.

Since this is a full router, activating of IPv4 and IPv6 forwarding is mandatory. This is what happens if IP forwarding has not been activated, notice the both no entries:

FRR# show run

Building configuration... Current configuration: ! frr version 7.2 frr defaults traditional hostname frr no ip forwarding no ipv6 forwarding ! line vty ! end

This could be configured to ip forwarding in the vtysh shell but this setting will not persist across reboots. To make the appliance a real router out of the box and keep the change permanent, add following lines the alpine wiki (reference), create the /etc/sysctl.d/90-routing-sysctl.conf file with following entries:

cat > /etc/sysctl.d/90-routing-sysctl.conf

# IPv4 and IPv6 forwarding
net.ipv4.conf.all.forwarding=1
net.ipv6.conf.all.forwarding=1

Create a system user zebra for the frr appliance:

adduser zebra

Set the password to zebra:

Changing password for zebra
New password: 
Retype password: 
passwd: password for quagga changed by root

Check system groups for frr:

grep frr /etc/group

Add the zebra user to the frrvty and frr system group:

adduser zebra frr
adduser zebra frrvty

This can be verified after a reboot, or new login using the id command. The output after running the id command should look like below:

id
uid=1000(zebra) gid=1000(zebra) groups=101(frr),102(frrvty),1000(zebra)

Write the used credentials to the /etc/issue file:

cat >> /etc/issue
user/pass       zebra/zebra
                root/root
user %
root #

The router FRR vtysh shell will use no colors:

FRR#

Finally pre-configure and enable at least 4 network interface cards in the linux system to be started right at the boot time. Interfaces have no IP addressing at start time. Edit the file /etc/network/interfaces file to look like in the example below, adjust the amount of NIC's to you own needs:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual
        pre-up ip link set dev $IFACE up
        pre-down ip link set dev $IFACE down

auto eth1
iface eth1 inet manual
        pre-up ip link set dev $IFACE up
        pre-down ip link set dev $IFACE down

auto eth2
iface eth2 inet manual
        pre-up ip link set dev $IFACE up
        pre-down ip link set dev $IFACE down

auto eth3
iface eth3 inet manual
        pre-up ip link set dev $IFACE up
        pre-down ip link set dev $IFACE down

The last configuration setting is to add the frr daemon to the default boot routine:

rc-update add frr default

At this point the appliance is ready to be used in GNS3. Here it used as a ethernet router with 4 ports. It's good enough for most networking scenarios. FRR is capable of running following routing protocols for free:

  • bgpd - BGP Border Gateway Protocol daemon
  • ospfd - OSPF Open Shortest Path First daemon
  • ospf6d - OSPF6 - IPv6 OSPF daemon
  • ripd - RIP Router Information Protocol daemon
  • ripngd - RIPng Next Generation RIP
  • isisd - IS-IS Intermediate System to Intermediate System daemon
  • pimd - PIM Protocol Independent Multicast daemon
  • ldpd - LDP Label Distribution Protocol daemon
  • nhrpd - NHRP Next Hop Resolution Protocol daemon
  • eigrpd - Enhanced Interior Gateway Routing Protocol (EIGRP) daemon
  • babeld - Babel, is a distance-vector routing protocol daemon
  • sharpd - SHARP daemon
  • pbrd - Policy Based Routing (PBR) daemon
  • bfdd - Bidirectional Forwarding Detection (BFD) daemon
  • fabricd - A routing protocol derived from IS-IS

Possible issues:

While booting the FRR router appliance there might be a possible timeout during the boot. The error message might appear like the boot is halted at 'random: crng init done'". The reason for this behaviour is explained at the linux kernel mailing list. To workaround this boot the GNS3 appliance using following KVM options. Append following options in the appliance in the advanced settings tab:

-object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0

This options can be also used for booting the guest directly using QEMU.

A second minor issue is a missing file in the standard installation. An error will display after the appliance has started up. To fix this touch following file in the FRR appliance.

touch /etc/frr/vtysh.conf

And now enjoy using this alpine linux FRR 7.2 appliance in your networking labs!