Module 30: Networking – minirouter

Introduction

This article may need to be fixed ever since minirouter got renamed to uminirouter

The network speed of a VyOS router is bound by the speed of which the driver can be emulated in the virtual machine, typically 1gbps. minirouter was designed to handle this case and has been tested against faster 40/100 gbit networks.

Version requirements

  • bird 1.5.0
  • dnsmasq 2.73
  • ovs-vsctl 1.11

Bare Metal

minirouter could run on bare metal, but there is no way to currently configure it using miniccc since minimega issues configuration commands referencing the VM name.

Container

There is a prebuilt minirouter busybox container you can use to get running with minirouter.

The container can be rebuilt by running: github.com/sandia-minimega/minimega/blob/master/misc/uminirouter/build.bash

Cleanup

$ nuke # /home/ubuntu/launchme.sh new

Boot

tar xf minimega-2.3-minirouter.tar.bz2 vm config filesystem /home/ubuntu/minirouterfs/ vm config fifo 1 vm config net 0 vm config init /init vm config preinit /home/ubuntu/minirouterfs/preinit vm launch container r1 vm start r1

KVM

Prebuild

apt-get install squashfs-tools syslinux debootstrap genisoimage extlinux cd /home/ubuntu/minimega cp bin/miniccc misc/vmbetter_configs/minirouter_overlay/ cp bin/minirouter misc/vmbetter_configs/minirouter_overlay/

Qcow

minirouter when built as a qcow with vmbetter ignores the custom init script.

Using vmbetter build a qcow2; this will take a while.

./bin/vmbetter -branch unstable -qcow -level debug -mbr /usr/lib/syslinux/mbr/mbr.bin misc/vmbetter_configs/minirouter.conf

Mount the built qcow

qemu-nbd --connect /dev/nbd0 minirouter.qcow2
mkdir -p /mnt/kvm
mount /dev/nbd0p1 /mnt/kvm

Create a new init script

cat > /mnt/kvm/init << EOF #!/bin/sh  export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/  mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs udev /dev mkdir /dev/pts mount -n -t devpts -o newinstance,ptmxmode=666,gid=5,mode=620 none /dev/pts rm /dev/ptmx ln -s /dev/pts/ptmx /dev/ptmx mount -t cgroup cgroup /sys/fs/cgroup chmod a+rx /  modprobe loop modprobe tun modprobe virtio_console modprobe virtio_pci modprobe e1000 modprobe e1000e modprobe virtio_net modprobe vmxnet3  echo 32768 > /proc/sys/net/ipv4/neigh/default/gc_thresh1 echo 32768 > /proc/sys/net/ipv4/neigh/default/gc_thresh2 echo 65536 > /proc/sys/net/ipv4/neigh/default/gc_thresh3 echo 32768 > /proc/sys/net/ipv6/neigh/default/gc_thresh1 echo 32768 > /proc/sys/net/ipv6/neigh/default/gc_thresh2 echo 65536 > /proc/sys/net/ipv6/neigh/default/gc_thresh3  sysctl -w net.ipv6.conf.all.forwarding=1 sysctl -w net.ipv4.ip_forward=1 service dnsmasq stop sleep 10 /miniccc -v=false -serial /dev/virtio-ports/cc -logfile /miniccc.log & /minirouter -v=false -logfile /minirouter.log & sysctl -w net.ipv6.conf.all.forwarding=1 sysctl -w net.ipv4.ip_forward=1 EOF

Launch init after boot

sed -i '$i/init &' /mnt/kvm/etc/rc.local

Unmount the qcow2

umount /mnt/kvm qemu-nbd --disconnect /dev/nbd0

Launch the qcow2

clear vm config vm config memory 2048 vm config net 0 vm config disk /home/ubuntu/minimega/minirouter.qcow2 vm launch kvm r2 vm start r2

Initrd and Kernel

vmbetter can build minirouter to an initrd and kernel pairing while keeping the custom init.

The build process does take a while.

apt-get install squashfs-tools syslinux debootstrap genisoimage extlinux cd /home/ubuntu/minimega cp bin/miniccc misc/vmbetter_configs/minirouter_overlay/ cp bin/minirouter misc/vmbetter_configs/minirouter_overlay/

Unlike building a qcow, the init does not need to be customized beyond enabling forwarding.

Add these two lines if you haven’t already

echo "sysctl -w net.ipv6.conf.all.forwarding=1" >> misc/vmbetter_configs/minirouter_overlay/init echo "sysctl -w net.ipv4.ip_forward=1" >> misc/vmbetter_configs/minirouter_overlay/init

And build

./bin/vmbetter -branch unstable -level debug misc/vmbetter_configs/minirouter.conf

In your local directory you will find a minirouter.kernel and a minirouter.initrd, which you can then use to boot the router as a KVM image.

Be sure to give the image 2048MB of RAM or more

clear vm config vm config memory 2048 vm config net 0 vm config kernel minirouter.kernel vm config initrd minirouter.initrd vm launch kvm r3 vm start r3

Network Example

Image of diagram.png

Cleanup

$ nuke # /home/ubuntu/launchme.sh new

Boot with Static Routes

# cd /home/ubuntu/ # tar xf minimega-2.3-minirouter.tar.bz2
vm config filesystem /home/ubuntu/minirouterfs/ vm config fifo 1 vm config net 1 2 vm config init /init vm config preinit /home/ubuntu/minirouterfs/preinit vm launch container r0 vm start r0 vm config net 1 3 vm launch container r1 vm start r1
clear vm config vm config disk /home/ubuntu/tinycore.qcow vm config net 2 vm config memory 128 vm launch kvm linux-100-[1-5] vm config net 3 vm launch kvm linux-200-[1-5] vm start all
router r0 interface 0 1.0.0.1/24 router r0 interface 1 192.168.1.1/24 router r0 dhcp 192.168.1.1 range 192.168.1.2 192.168.1.254 router r1 interface 0 1.0.0.2/24 router r1 interface 1 192.168.2.1/24 router r1 dhcp 192.168.2.1 range 192.168.2.2 192.168.2.254 router r0 route static 192.168.2.0/24 1.0.0.2 router r1 route static 192.168.1.0/24 1.0.0.1 router r0 commit router r1 commit

OSPF Networking – Basic

Cleanup

vm kill all vm flush

Launch

vm config filesystem /home/ubuntu/minirouterfs/ vm config fifo 1 vm config net 1 2 vm config init /init vm config preinit /home/ubuntu/minirouterfs/preinit vm launch container r0 vm start r0 vm config net 1 3 vm launch container r1 vm start r1 router r0 route ospf 0 0 router r1 route ospf 0 0 router r0 route ospf 0 1 router r1 route ospf 0 1 router r0 commit router r1 commit

OSPF Networking – Cost

OSPF exposes many options that you can tweak with minirouter. This section covers the cost metric.

Cleanup

vm kill all vm flush

Topology

We will use the following simple topology:

vm config filesystem /root/uminirouterfs vm config preinit /root/uminirouterfs/preinit vm config networks a b vm launch container routerA vm config networks a c vm launch container routerB vm config networks b c vm launch container routerC router routerA interface 0 10.0.0.1/24 router routerA interface 1 10.0.1.1/24 router routerA route ospf 0 0 router routerA route ospf 0 1 router routerA commit router routerB interface 0 10.0.0.2/24 router routerB interface 1 10.0.2.1/24 router routerB route ospf 0 0 router routerB route ospf 0 1 router routerB commit router routerC interface 0 10.0.1.2/24 router routerC interface 1 10.0.2.2/24 router routerC route ospf 0 0 router routerC route ospf 0 1 router routerC commit vm start all

OSPF Costs

OSPF uses cost to determine which paths to route through. These costs are typically set using the inverse of the speed but can be overridden. We will change the cost to force different routes through the network.

Once the environment has launched, you can use traceroute through miniweb to see the path through the network:

// Connect to routerA via miniweb / # traceroute 10.0.2.1 traceroute to 10.0.2.1 (10.0.2.1), 30 hops max, 46 byte packets  1  10.0.1.2 (10.0.1.2)  0.009 ms  0.005 ms  0.005 ms  2  10.0.2.1 (10.0.2.1)  0.005 ms  0.005 ms  0.005 ms

In this environment, the path is A-C-B.

We can tweak the cost on the A-C edge for routerA using the following commands:

router routerA route ospf 0 1 cost 20 router routerA commit

The default cost is 10 so a cost of 20 changes the chosen route. After a few seconds, we can verify the new route:

// Connect to routerA via miniweb / # traceroute 10.0.2.1 traceroute to 10.0.2.1 (10.0.2.1), 30 hops max, 46 byte packets  1  10.0.2.1 (10.0.2.1)  0.009 ms  0.005 ms  0.006 ms

Other OSPF Options

There are many other interface options for OSPF which are primarily used to control properties of the OSPF communication between the routers. See the interface section here for more details.

miniccc

minimega is able to configure minirouter without networking by utilizing miniccc.

When a virtual machine or container is started with minimega a serial port is added.

This serial port is used as a command and control network when the miniccc agent is running on the virtual machine.

The minimega router command is able to issue the configuration changes over this serial back channel.

Bigger Network Example

Now that we have the basics out of the way let’s make a bigger network topology

Image of big.png

Let’s assign some aliases to each link

Image of big2.png

Now let’s assign some IP ranges for each link

A:  1.0.0.0/24 B:  2.1.0.0/24 B2: 2.2.0.0/24 B3: 2.3.0.0/24 C:  3.0.0.0/24 D:  4.0.0.0/24 E:  5.0.0.0/24 F:  6.0.0.0/24 G:  7.1.0.0/24 G2: 7.2.0.0/24 G3: 7.3.0.0/24 H:  8.0.0.0/24 I:  9.0.0.0/24 J:  10.0.0.0/24 K:  11.0.0.0/24

Cleanup

$ nuke # /home/ubuntu/launchme.sh new

Boot routers and virtual machines

vlans range 1500 1600 vm config memory 2048 vm config filesystem /home/ubuntu/minirouterfs/ vm config fifo 1 vm config init /init vm config preinit /home/ubuntu/minirouterfs/preinit vm config net A B B2 C vm launch container r0 vm config net D B B3 E vm launch container r1 vm config net E G G2 F vm launch container r2 vm config net C G3 G2 H I vm launch container r3 vm config net B3 K G G3 B2 vm launch container r4 vm config net I J vm launch container r5 vm start all  clear vm config vm config net A vm config memory 128 vm config disk /home/ubuntu/tinycore.qcow vm launch kvm l1 vm config net D vm launch kvm l2 vm config net K vm launch kvm l3 vm config net F vm launch kvm l4 vm config net H vm launch kvm l5 vm config net J vm launch kvm l6 vm start all

Configure networking

router r0 interface 0 1.0.0.1/24 router r0 interface 1 2.1.0.1/24 router r0 interface 2 2.2.0.1/24 router r0 interface 3 3.0.0.1/24 router r0 dhcp 1.0.0.1 range 1.0.0.1 1.0.0.254 router r0 route ospf 0 0 router r0 route ospf 0 1 router r0 route ospf 0 2 router r0 route ospf 0 3 router r0 commit  router r1 interface 0 4.0.0.1/24 router r1 interface 1 2.1.0.2/24 router r1 interface 2 2.3.0.1/24 router r1 interface 3 5.0.0.1/24 router r1 dhcp 4.0.0.1 range 4.0.0.1 4.0.0.254 router r1 route ospf 0 0 router r1 route ospf 0 1 router r1 route ospf 0 2 router r1 route ospf 0 3 router r1 commit  router r2 interface 0 5.0.0.2/24 router r2 interface 1 7.1.0.1/24 router r2 interface 2 7.2.0.1/24 router r2 interface 3 6.0.0.1/24 router r2 dhcp 6.0.0.1 range 6.0.0.1 6.0.0.254 router r2 route ospf 0 0 router r2 route ospf 0 1 router r2 route ospf 0 2 router r2 route ospf 0 3 router r2 commit  router r3 interface 0 3.0.0.2/24 router r3 interface 1 7.3.0.1/24 router r3 interface 2 7.2.0.2/24 router r3 interface 3 8.0.0.1/24 router r3 interface 4 9.0.0.1/24 router r3 dhcp 8.0.0.1 range 8.0.0.1 8.0.0.254 router r3 route ospf 0 0 router r3 route ospf 0 1 router r3 route ospf 0 2 router r3 route ospf 0 3 router r3 route ospf 0 4 router r3 commit  router r4 interface 0 2.3.0.2/24 router r4 interface 1 11.0.0.1/24 router r4 interface 2 7.1.0.2/24 router r4 interface 3 7.3.0.2/24 router r4 interface 4 2.2.0.2/24 router r4 dhcp 11.0.0.1 range 11.0.0.1 11.0.0.254 router r4 route ospf 0 0 router r4 route ospf 0 1 router r4 route ospf 0 2 router r4 route ospf 0 3 router r4 route ospf 0 4 router r4 commit  router r5 interface 0 9.0.0.2/24 router r5 interface 1 10.0.0.1/24 router r5 dhcp 10.0.0.1 range 10.0.0.1 10.0.0.254 router r5 route ospf 0 0 router r5 route ospf 0 1 router r5 commit

Everything is on Area 0 and through the magic of OSPF routing should be established between all the machines.

If a router or route goes down the routes should automatically update.

Name    Memory    VLAN                                                        IPv4 l5        128    [H (1511)]                                                [8.0.0.179] l6        128    [J (1514)]                                                [10.0.0.95] l1        128    [A (1500)]                                                [1.0.0.141] l2        128    [D (1504)]                                                [4.0.0.220] l3        128    [K (1513)]                                                [11.0.0.185] l4        128    [F (1509)]                                                [6.0.0.239] r0        2048    [A (1500), B (1501), B2 (1502), C (1503)]                [1.0.0.1, 2.1.0.1, 2.2.0.1, 3.0.0.1] r1        2048    [D (1504), B (1501), B3 (1505), E (1506)]                [4.0.0.1, 2.1.0.2, 2.3.0.1, 5.0.0.1] r2        2048    [E (1506), G (1507), G2 (1508), F (1509)]                [5.0.0.2, 7.1.0.1, 7.2.0.1, 6.0.0.1] r3        2048    [C (1503), G3 (1510), G2 (1508), H (1511), I (1512)]     [3.0.0.2, 7.3.0.1, 7.2.0.2, 8.0.0.1, 9.0.0.1] r4        2048    [B3 (1505), K (1513), G (1507), G3 (1510), B2 (1502)]    [2.3.0.2, 11.0.0.1, 7.1.0.2, 7.3.0.2, 2.2.0.2] r5        2048    [I (1512), J (1514)]                                     [9.0.0.2, 10.0.0.1]
Image of d3.png

Authors

The minimega authors

Created: 30 May 2017

Last updated: 26 May 2022