Using a Raspberry Pi 2 as a Router on a Stick Starring NetBSD

A few weeks ago I set about upgrading my feeble networking skills by playing around with a Cisco 2970 switch. I set up a couple of VLANs and found the urge to set up a router to route between them. The 2970 isn’t a modern layer 3 switch so what am I to do?

Why not make use of the Raspberry Pi 2 that I’ve never used and put it to some good use as a ‘router on a stick’.

I could install a Linux based OS as I am quite familiar with it but where’s the fun in that? In my home lab I use SmartOS which by the way is a shit hot hypervisor but as far as I know there aren’t any Illumos distributions for the Raspberry Pi. On the desktop I use Solus OS which is by far the slickest Linux based OS that I’ve had the pleasure to use but Solus’ focus is purely desktop. It’s looking like BSD then!

I believe FreeBSD is renowned for it’s top notch networking stack and so I wrote to the BSDNow show on Jupiter Broadcasting for some help but it seems that the FreeBSD chaps from the show are off on a jolly to some BSD conference or another(love the show by the way).

It looks like me and the luvverly NetBSD are on a date this Saturday. I’ve always had a secret love for NetBSD. She’s a beautiful, charming and promiscuous lover(looking at the supported architectures) and I just can’t stop going back to her despite her misgivings(ahem, zfs). Just my type of grrrl!

Let’s crack on.

Download the image and install NetBSD on Micro SD card

On the OS of your choosing do something similar to the following

wget http://cdn.netbsd.org/pub/NetBSD/NetBSD-7.1.2/evbarm-earmv7hf/binary/gzimg/armv7.img.gz
gunzip armv7.img.gz
dd if=armv7.img of=/dev/<yourSDcard>
sync

Boot up

Put the micro SD card in your RPI2 and power on, set a root password.
Make /etc/ssh/sshd_config editable by issuing:

armv7# chmod +w /etc/ssh/sshd_config

Open /etc/ssh/sshd_config for editing, uncomment and set
PermitRootLogin yes

Lets try to create a VLAN interface

armv7# ifconfig vlan101 create
ifconfig: clone_command: Invalid argument
ifconfig: exec_matches: Invalid argument

Hmmm, I suspect VLANs are not enabled in the kernel, so we need to build a kernel with VLANs enabled

Not Using RPI to build,  too slow

Spin up a NetBSD VM in Virtualbox

Download Kernel Source

Follow instructions from the NetBSD Guide:
30.3.1. Downloading sources for a NetBSD release

I Dont think we needed xsrc.tgz but the others seem necessary for build.sh to work

On with the build prep

build# mkdir /usr/obj

The file /usr/src/sys/arch/evbarm/conf/RPI2 includes code from RPI so we only need to edit that.

build# vi /usr/src/sys/arch/evbarm/conf/RPI

Uncomment:

#pseudo-device vlan

Optionally uncomment:

#pseudo-device pf
#pseudo-device pflog

Lets build

build# cd /usr/src
build# ./build.sh -m evbarm -a earmv7hf tools
build# ./build.sh -m evbarm -a earmv7hf kernel=RPI2

Upon a successful build you should see something like

===> Kernels built from RPI2:
/usr/src/sys/arch/evbarm/compile/obj/RPI2/netbsd
===> build.sh ended: Sat Apr 28 19:21:38 BST 2018
===> Summary of results:
build.sh command: ./build.sh -m evbarm -a earmv7hf kernel=RPI2
build.sh started: Sat Apr 28 19:14:29 BST 2018
NetBSD version: 7.1.2
MACHINE: evbarm
MACHINE_ARCH: earmv7hf
Build platform: NetBSD 7.1.2 amd64
HOST_SH: /bin/sh
MAKECONF file: /etc/mk.conf (File not found)
TOOLDIR path: /usr/src/obj/tooldir.NetBSD-7.1.2-amd64
DESTDIR path: /usr/src/obj/destdir.evbarm
RELEASEDIR path: /usr/src/obj/releasedir
Updated makewrapper: /usr/src/obj/tooldir.NetBSD-7.1.2-amd64/bin/nbmake-evbarm
Building kernel without building new tools
Building kernel: RPI2
Build directory: /usr/src/sys/arch/evbarm/compile/obj/RPI2
Kernels built from RPI2:
/usr/src/sys/arch/evbarm/compile/obj/RPI2/netbsd
build.sh ended: Sat Apr 28 19:21:38 BST 2018
===> .

Woohooo,we have a kernel

Now on our RPI2, we just rename the old kernel (kernel7.img) to something else and scp /usr/src/sys/arch/evbarm/compile/obj/RPI2/netbsd.bin from our build system to kernel7.img in /boot on the RPI2.
Reboot

Test for vlan-ability

Try to create a VLAN Interface

armv7# ifconfig vlan101 create # no errors? looking good!
armv7# ifconfig vlan101 vlan 101 vlanif usmsc0 # no errors? looking even better! lets check ifconfig
armv7# ifconfig vlan101
vlan101: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
vlan: 101 parent: usmsc0
address: b8:27:eb:43:4e:3f
inet6 fe80::ba27:ebff:fe43:4e3f%vlan101 prefixlen 64 scopeid 0x3

Lets create another VLAN interface

armv7# ifconfig vlan102 create
armv7# ifconfig vlan102 vlan 102 vlanif usmsc0
armv7# ifconfig vlan102
vlan102: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
vlan: 102 parent: usmsc0
address: b8:27:eb:43:4e:3f
inet6 fe80::ba27:ebff:fe43:4e3f%vlan102 prefixlen 64 scopeid 0x4

Lets give the new interfaces IP addresses

armv7# ifconfig vlan101 inet 192.168.101.1/24 up
armv7# ifconfig vlan102 inet 192.168.102.1/24 up
armv7# ifconfig vlan101
vlan101: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
vlan: 101 parent: usmsc0
address: b8:27:eb:43:4e:3f
inet6 fe80::ba27:ebff:fe43:4e3f%vlan101 prefixlen 64 scopeid 0x3
inet 192.168.101.1 netmask 0xffffff00 broadcast 192.168.101.255
armv7# ifconfig vlan102
vlan102: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
vlan: 102 parent: usmsc0
address: b8:27:eb:43:4e:3f
inet6 fe80::ba27:ebff:fe43:4e3f%vlan102 prefixlen 64 scopeid 0x4
inet 192.168.102.1 netmask 0xffffff00 broadcast 192.168.102.255

Of course this wont persist a reboot

Create /etc/ifconfig.vlan101 with the contents

create
vlan 101 vlanif usmsc0
inet 192.168.101.1/24 up

Create /etc/ifconfig.vlan102 with the contents

create
vlan 102 vlanif usmsc0
inet 192.168.102.1/24 up

Set up packet forwarding

Check whether packet forwarding is enabled by issuing:

armv7# sysctl net.inet.ip.forwarding
net.inet.ip.forwarding = 0

Hmmm, it isn’t

armv7# sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1

Now it is but that’s fine for testing, lets make it permanent by adding the line:

net.inet.ip.forwarding=1

to /etc/sysctl.conf

Reboot and you should have vlan101, vlan 102 created with IP addresses and packet forwarding enabled. This is probably a good time to remove the remote access for root.

And thanks to Andy Ruhl on the netbsd-users mailing list for the proof reading.