This is a 64bit version of the how to article Building an tiny GNS3 FRR linux appliance article. Many features in the linux IP stack and in the FRRouting implementation rely running on 64 bit architecture. Using the x86 architecture not all available protocols will work as they should, trouble is ahead. Recommendation using only the real 64 bit for the superior routing network appliance netlab experience. Really.

This FRRouting installation needs only 100 MB of disk space.

📘 Note
x86 architecture is deprecated from the linux IP networking perspective. Use a most current x86_64 iso file from the official alpine linux website.

Get installation medium

This is for lazy folks, might use a old version, adjust to most recent release. The output file is stored to the /tmp directory in the host system:

user % wget https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/alpine-virt-3.15.4-x86_64.iso -P /tmp/

Change to the GNS3 QEMU images directory:

user % cd ~/GNS3/images/QEMU/

Create FRR guest image

Create an empty disk image file for the virtual guest installation. Here qcow2 is used. The qcow file is only 1 GB large, and the installation will result in taking 100 MB of disk space:

user % qemu-img create -f qcow2 frr822.qcow2 1G

Boot installation medium

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

user % qemu-system-x86_64 -boot d -cdrom /tmp/alpine-virt-3.15.4-x86_64.iso -hda ~/GNS3/images/QEMU/frr822.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 key and enable serial port redirection to a localhost port 4321.

user % telnet localhost 4321

Trying ::1...
Connected to localhost. Escape character is '^]'.   Welcome to Alpine Linux 3.15 Kernel 5.15.32-0-virt on an x86_64 (/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:~#

Initial guest setup

This is the initial installation sequence as it displayed in the command line interface. The setup routine is started running the setup-alpine command. The individual setup will different compared to the displayed below. Some self explaining steps are skipped for brevity in the shown output below. Begin the node setup installation routine as written int the MOTD file.

Shortened example of the setup-alpine command:

user % setup-alpine

Select keyboard variant [de] Select hostname [frr822] 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.

user % halt

Boot FRR guest

Configure guest node frr822 needs to boot from the installed storage now. Start the installation using following command:

qemu-system-x86_64 -boot c -hda ~/GNS3/images/QEMU/frr822.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 &

Once again connect to the running guest node using the loopback interface:

Connect to FRR guest

user % telnet localhost 4321

Use the in previous step configured root password to login to the node. After successful first boot, before updating packages, edit the repositories file:

Edit repositories

root # vi /etc/apk/repositories

Add the community repository to the list, to get recent FRR package, move all entries to the edge called package tree, remove any version specific entries containing version strings: v5.12:

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

After adjusting the repositories file, update the package repository using the apk update command:

Update

root # apk update

Install packages

Install following needed packages:

  • frr
  • mtr
  • ifupdown-ng
  • sudo
  • agetty
  • alpine-baselayout

The ifupdown-ng package handles link or carrier detection in GNS3 if connecting ethernet interfaces. The alpine-baselayout provides a default usable prompt. The agetty package provides a simple and suckless autologin mechanism for the appliance.

root # apk add frr sudo mtr agetty ifupdown-ng alpine-baselayout

Upgrade

Upgrade all system packages to the edge version:

root # apk upgrade

Configure frr daemon

Now configure the FRR package. Edit the /etc/frr/daemons file and replace following entries. This is optional over here, the target GNS3 appliance will run following routing protocols:

  • BGP - Border Gateway Protocol
  • OSPF - OSPFv2 specifically running using IPv4
  • OSPF6 - OSPF6 for IPv6
  • RIP - the Routing Information Protocol (RIP) RFC2453
  • RIPng - RIP for IPv6
  • IS-IS - Intermediate System-to-Intermediate System routing protocol, not build on top of IP.
  • LDP - Label Distribution Protocol
  • EIGRP - Diffusing Update Algorithm - DUAL - RFC7896 implementation
  • BABEL - Routing protocol designed for wireless networks needs
  • BFD - Pickup helper protocol, to shorten the routing protocol convergence time
  • openFABRIC - Enhanced IS-IS for DC specific or fabric centric designs

The default configuration file entries has =no. Add =yes on desired routing protocols. Adjust this file to own needs. This is a routing protocol centric configuration:

root # vi /etc/frr/daemons
📄 File /etc/frr/daemons

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

Before starting the FRR daemon create following empty file, if not exists by default:

root # touch /etc/frr/vtysh.conf

Change the ownership to frr:frr

root # chown frr:frr /etc/frr/vtysh.conf

Start the FRR daemon:

root # /etc/init.d/frr start

Verfiy frr daemon

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

frr822:~# ss -tulp
Netid State  Recv-Q Send-Q Local Address:Port   Peer Address:PortProcess                            
udp   UNCONN 0      0            0.0.0.0:4784        0.0.0.0:*    users:(("bfdd",pid=2215,fd=12))   
udp   UNCONN 0      0            0.0.0.0:3784        0.0.0.0:*    users:(("bfdd",pid=2215,fd=11))   
udp   UNCONN 0      0            0.0.0.0:3785        0.0.0.0:*    users:(("bfdd",pid=2215,fd=15))   
udp   UNCONN 0      0               [::]:4784           [::]:*    users:(("bfdd",pid=2215,fd=14))   
udp   UNCONN 0      0               [::]:3784           [::]:*    users:(("bfdd",pid=2215,fd=13))   
udp   UNCONN 0      0               [::]:3785           [::]:*    users:(("bfdd",pid=2215,fd=16))   
tcp   LISTEN 0      3          127.0.0.1:2613        0.0.0.0:*    users:(("eigrpd",pid=2209,fd=12)) 
tcp   LISTEN 0      128          0.0.0.0:ssh         0.0.0.0:*    users:(("sshd",pid=1892,fd=3))    
tcp   LISTEN 0      3          127.0.0.1:2616        0.0.0.0:*    users:(("staticd",pid=2212,fd=12))
tcp   LISTEN 0      3          127.0.0.1:2617        0.0.0.0:*    users:(("bfdd",pid=2215,fd=19))   
tcp   LISTEN 0      3          127.0.0.1:2618        0.0.0.0:*    users:(("fabricd",pid=2218,fd=12))
tcp   LISTEN 0      3          127.0.0.1:zebra       0.0.0.0:*    users:(("zebra",pid=2173,fd=23))  
tcp   LISTEN 0      3          127.0.0.1:ripd        0.0.0.0:*    users:(("ripd",pid=2185,fd=12))   
tcp   LISTEN 0      3          127.0.0.1:ospfd       0.0.0.0:*    users:(("ospfd",pid=2191,fd=12))  
tcp   LISTEN 0      3          127.0.0.1:bgpd        0.0.0.0:*    users:(("bgpd",pid=2178,fd=18))   
tcp   LISTEN 0      3          127.0.0.1:isisd       0.0.0.0:*    users:(("isisd",pid=2197,fd=12))  
tcp   LISTEN 0      3          127.0.0.1:2609        0.0.0.0:*    users:(("babeld",pid=2200,fd=11)) 
tcp   LISTEN 0      3          127.0.0.1:2612        0.0.0.0:*    users:(("ldpd",pid=2205,fd=18))   
tcp   LISTEN 0      128             [::]:ssh            [::]:*    users:(("sshd",pid=1892,fd=4))    
tcp   LISTEN 0      3              [::1]:ripngd         [::]:*    users:(("ripngd",pid=2188,fd=12)) 
tcp   LISTEN 0      3              [::1]:ospf6d         [::]:*    users:(("ospf6d",pid=2194,fd=12)) 

Add frr to default startup

Add the frr daemon to the default boot routine, so it starts by default:

root # rc-update add frr default

Configure interfaces

  • Configure the guest's amount of interface cards, in example 4 NIC's
  • Enable IP and IPv6 forwarding
  • Add protocol support (MPLS)

Add physical interfaces

Adjust the amount of NIC's to reflect your own needs here. Once could add even 20

Provision the guest node to use 4 NIC's here: eth0, eth1, eth2, and eth3 in the linux system to be started right at the boot time. Interfaces using no IP addressing and not requesting IP addressing via dhcp.

📘 Note
This interfaces configuration uses the updated ifupdown-ng syntax

Edit the file /etc/network/interfaces file to look like in the example below:

root # vi /etc/network/interfaces
📄 File /etc/network/interfaces

auto lo auto eth0 auto eth1 auto eth2 auto eth3

Enable IP forwarding

Since this is a full blown router setup, activating of IPv4 and IPv6 forwarding in kernel is mandatory, and configuring that it persists across reboots. Enable ip forwarding for both IP address families, IPv4 and IPvv6. To make the change permanent, add following lines the alpine wiki (reference), create the /etc/sysctl.d/90-ip-forwarding.conf file with following entries:

root # cat > /etc/sysctl.d/90-ip-forwarding.conf

net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1

Enable MPLS

Advanced IP networking relies on the linux MPLS dataplane. Enable needed modules to use MPLS kernel modules:

Load the necessary linux kernel MPLS modules:

modprobe mpls_router
modprobe mpls_gso
modprobe mpls_iptunnel

Verify kernel modules are loaded using the lsmod | grep mpls command:

root # lsmod | grep mpls

mpls_iptunnel 16384 0 mpls_router 45056 1 mpls_iptunnel ip_tunnel 36864 1 mpls_router mpls_gso 16384 0

Append these 3 kernel modules to the /etc/modules-load.d/modules.conf configuration file. This ensures modules are loaded on each system start.

root # cat > /etc/modules-load.d/modules.conf

mpls_router mpls_gso mpls_iptunnel

Activate MPLS for all 5 interfaces in the FRR appliance, and set the maximal available platform MPLS label stack to 1048575. Label with the label ID=1048575 will be the last possible label for this platform:

sysctl -w net.mpls.conf.eth0.input=1
sysctl -w net.mpls.conf.eth1.input=1
sysctl -w net.mpls.conf.eth2.input=1
sysctl -w net.mpls.conf.eth3.input=1
sysctl -w net.mpls.conf.lo.input=1
sysctl -w net.mpls.platform_labels=1048575

For permanent setting across reboots, create following file /etc/sysctl.d/91-mpls.conf

root # cat > /etc/sysctl.d/91-mpls.conf

net.mpls.conf.lo.input=1 net.mpls.conf.eth0.input=1 net.mpls.conf.eth1.input=1 net.mpls.conf.eth2.input=1 net.mpls.conf.eth3.input=1 net.mpls.platform_labels=1048575

The FRR router appliance is now prepared to be used as a advanced networking router.

Add zebra user

Create a user called zebra and set the password to zebra:

root # adduser zebra

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

📙 Important
The zebra user password will need to be removed further in the setup, to add a auto login routine, directly into the FRRouting's vtysh shell.

Configure system groups

Users of group wheel do not need password to authenticate to run system commands. Using visudo

root # visudo

edit following line, and remove the comment (#):

...
## Same thing without a password                                            
%wheel ALL=(ALL) NOPASSWD: ALL
...

Quitting and writing with visudo; Escape edit mode, hit ESC button, write and quit :wq.

Check system groups for frr:

root # grep frr /etc/group

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

root # adduser zebra frr
root # adduser zebra frrvty
root # adduser zebra wheel

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:

Verify zebra user

Authenticate as user zebra user:

root # su - zebra

Verify the assigned system group membership:

user % id zebra uid=1000(zebra) gid=1000(zebra) groups=1000(zebra),10(wheel),101(frr),102(frrvty)

Exit the userprompt

user % exit

System

Following system adjustments are optional but useful for a out of the box better experience and handling of the guest. Adjustments for better usability.

Adjust system prompt

Configure using colored prompt per default. This option will enable colored prompt according to the given shell

root # cp /etc/profile.d/color_prompt.sh.disabled /etc/profile.d/color_prompt.sh
root # chmod +x /etc/profile.d/color_prompt.sh

The resulting prompt will look in the FRRouting appliance like in the examples shown below:

user % This is the zebra user prompt
root # This is the root user prompt

The router FRR vtysh shell will use no colors:

frr822#This is the FRRouting vtysh command line

Adjust /etc/issue

Append the setup credentials to the /etc/issue file:

root # cat >> /etc/issue

user/pass root/root

Adjust /etc/motd

Create a new MOTD to be informative and appealing:

root # cat > /etc/motd

Welcome to FRRouting Alpine!

Adjust /dev/ttyS0

To be able to watch the appliance boot process in the console using GNS3, add following optional configure steps:

root # vi /boot/extlinux.conf

Add following lines to the APPEND section of the bootloader, this will display the boot messages to serial console ttyS0:

console=ttyS0,115200

The resulting entry after editing might be looking like this one:

...
APPEND root=UUID=efae36-55d4-4533-8379-c1e86e3d modules=sd-mod,usb-storage,ext4 quiet console=ttyS0,115200 rootfstype=ext4
...

Enable subsecond booting, set the TIMEOUT entry to 1, which is 1/10-th of a second (100 milliseconds), this is the shortest time waiting for linux kernel. Setting this to 0 will end up waiting for user entry at next boot.

    ...
TIMEOUT 1
...

Enabling a login console is done in the /etc/inittab file, and be sure to disable the 2-nd line calling ttyS0, like it is shown in example.

📕 Warning
Assigning 2 distinct ttyS0 entries to getty WILL end in uncontrolable login shell behaviour on next authentication, Be cautious editing the inittab file, Failure will result in unusable linux guest.
root # vi /etc/inittab
[...]
# Put a getty on the serial port
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100

# enable login on alternative console
# ttyS0::respawn:/sbin/getty -L 0 ttyS0 vt100

The 115200 is the serial console bandwidth in Baud. It is set to its maximum available bandwidth.

Adjust /var/tmp

Prevent not empty temporary directory and sometime resulting in crashes, because of double assigned process ID. This is a workaround for myself, takes 24MB only:

This creates a tmpfs for the /var/tmp directory, 24 MB size. Add following line to the /etc/fstab file:

root # vi /etc/fstab
[...]
tmpfs           /var/tmp        tmpfs   size=24M,mode=0777     0 0

At next boot this is active. Verify using the df -h command, after next boot of the guest.

Autologin

Create a suckless autologin solution, straight into the vtysh. Much like the IOS prompt, or any other network centric device would act. This is the reason for agetty getting installed, using agetty's --autologin -a option. Autologin requires removing the appliance user password.

Edit /etc/passwd

Edit the passwd file, edit only the following zebra user entry:

root # vi /etc/passwd
📄 File /etc/passwd

... zebra:x:1000:1000:Linux User,,,:/home/zebra:/bin/ash ...

Make the user zebra not requiring a password, simply by removing the x from the line, it will be looking afterwards like in below example:

📄 File /etc/passwd

... zebra::1000:1000:Linux User,,,:/home/zebra:/bin/ash
...

Now the password for the user zebra has been removed.

Edit /etc/inittab

Now adjust the autologin entry to the /etc/inittab file. Replace the active ttyS0 entry in the configuration to this one using the agetty -a zebra auto login option, like in example below. Using the --noissue option the login does not display the content of the /etc/issue file:

📕 Warning
Once again. Be cautious editing the inittab file. Failure doing so will result in unusable linux guest.
root # vi /etc/inittab
...
ttyS0::respawn:/sbin/agetty -a zebra --noissue -L ttyS0 115200 vt100
...

Edit ~/.profile

Booting the FRR appliance and opening the console session in GNS3 should display a working vtysh session. Without the need of executing any additional commands. Authenticate as the zebra user:

root # su - zebra

Add following entry to the ~/.profile to start vtysh per default after login. If the file does not exist, create it, and add the vtysh entry:

user % vi ~/.profile
vtysh

vtysh is the needed content of the .profile. Now the autologin method is set up. The autologin for the zebra user on /dev/ttyS0 will end in the vtysh of FRRouting. Once logged in, use the exit command to exit to the system shell.

Stop FRR guest

At this point the FRRouting appliance is finished. Use the halt command to stop the guest:

root # halt

Summary

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. FRRouting 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 daemon
  • 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 specifically for fabric centric designs, like known from DC using the spine-leaf topology.
  • pathd - PATH is a daemon that handles the installation and deletion of Segment Routing (SR) Policies. Path Computation Element PCEP implementation.

This is the boot sequence and the final prompt how the appliance will great you after a start in GNS3 topology, it has 4 NIC's per default, everything is set up to ready:

Show up boot up routine.#To demonstrate how the FRRouting appliance will end the boot sequence in the vtysh shell.

... * Setting keymap ... [ ok ] * Starting networking ... * lo ... [ ok ] * eth0 ... [ ok ] * eth1 ... [ ok ] * eth2 ... [ ok ] * eth3 ... [ ok ] * Starting busybox syslog ... [ ok ] * Seeding 4096 bits and crediting * Saving 4096 bits of creditable seed for next boot * Starting busybox acpid ... [ ok ] * Starting busybox crond ... [ ok ] Started watchfrr * Starting sshd ... [ ok ]   Welcome to Alpine Linux 3.16.0_alpha20220328 (edge) Kernel 5.15.34-0-virt on an x86_64 (ttyS0)   frr822 login: zebra (automatic login)   Welcome to FRRouting Alpine!   Hello, this is FRRouting (version 8.2.2). Copyright 1996-2005 Kunihiro Ishiguro, et al.   frr822#

Now this guest node is ready to be added named as frr822 QEMU appliance to GNS3, using 4 NIC's and consuming 324 MB of RAM, and using 100 MB of disk installation. Don't forget to update.

References