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.
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:
Change to the GNS3 QEMU images directory:
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:
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:
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.
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:
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.
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
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
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
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.
Upgrade
Upgrade all system packages to the edge version:
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:
... 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:
Change the ownership to frr:frr
Start the FRR daemon:
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:
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.
This interfaces configuration uses the updated ifupdown-ng syntax
Edit the file /etc/network/interfaces file to look like in the example below:
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:
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:
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.
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
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:
Changing password for zebra New password: Retype password: passwd: password for zebra changed by root
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
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:
Add the zebra user to the frrvty and frr system wheel group:
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:
Verify the assigned system group membership:
Exit the userprompt
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
The resulting prompt will look in the FRRouting appliance like in the examples shown below:
The router FRR vtysh shell will use no colors:
Adjust /etc/issue
Append the setup credentials to the /etc/issue file:
user/pass root/root
Adjust /etc/motd
Create a new MOTD to be informative and appealing:
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:
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.
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.
[...]
# 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:
[...]
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:
... 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:
...
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:
Once again. Be cautious editing the inittab file. Failure doing so will result in unusable linux guest.
...
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:
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:
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:
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:
... * 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.