🌑

802.11ac on FreeBSD with wifibox

Posted at — Apr 20, 2022

Introduction

wifibox is a great project that brings Linux wifi drivers to FreeBSD. I only recently learned about the project from a reddit post on r/freebsd.

Wifibox creates a bhyve virtual machine running Alpine Linux with your system’s wifi device passed through to the Linux system. The question then is: “Why would I want to do this?” If your wifi works great under FreeBSD, then you probably don’t want to go through the trouble of setting up wifibox.

Myself, I have a couple of Thinkpads (T480 and an X1g6) that have intel wireless cards in them. The iwm driver works but doesn’t provide much speed. With wifibox, I’m able to connect to wifi access points via 802.11ac. Native FreeBSD drivers do not yet support higher speeds than 802.11g as far as I’m aware.

Diagram

The basic mechanics of wifibox as I understand them are:

   +---------+
   | FreeBSD +-------------+
   +-----+---+             |
         +---+---+         |
         | Bhyve |         |
         +----+--+         |
              +--+----+    |
   +----------+ Linux |    |
   |          +--^----+    |
   |             |         |
+--v--+   +------+----+    |
|tap0 |   |wifi device|    |
+----++   |pci3/0/0   <----+
     |    +-----------))
     |                  )))))
     |                      )))----------------+
    +v-------------+           ) access point  |
    | wifibox0     |           ----------------+
    +--------------+

Bhyve creates a virtual network card that’s represented here by tap0. tap0 is joined to a FreeBSD bridge named wifibox0. The bridge has an IP address assigned to it that can communicate with the IP assigned to tap0 inside the Linux VM. I use 10.0.0.1 for the Linux VM host and 10.0.0.2 on the wifibox0 bridge since that’s the default for wifibox.

All IP connections are then routed through the wifibox0 bridge and through the Linux virtual system’s wifi via a default route on the FreeBSD host.

The Linux system handles the driver mechanics and wifi association negotiation. For that to work, wifibox requires a seperate version of wpa_supplicant in the virtual machine and a seperate wpa_supplication.conf configuration file.

Installation

There is a wifibox port for FreeBSD that makes installation easy.

1
pkg install wifibox

Configuration

I was a bit confused at first when configuring wifibox after installing the pkg. The man page (man wifibox) specifies modifying the *.conf.sample files in the /usr/local/etc/wifibox/ directory to configure it but does not specify which settings are necessary for software to start.

UPDATE 4/25/22 The author of wifibox is making changes to the *.conf.sample files that spell out which options are required. The options are no longer commented out and a sane default configuration is used.

Here are the files and configurations that worked for me.

bhyve.conf

First thing you’ll need is the location of the wifi card on your PCI bus. This is the address you pass to bhyve.

My wifi card is located on pci0:3:0:0 using the iwm driver as found with the pciconf utility.

1
2
3
4
5
$ pciconf -lv | grep -B3 -i wireless

iwm0@pci0:3:0:0:        class=0x028000 rev=0x78 hdr=0x00 vendor=0x8086 device=0x24fd subvendor=0x8086 subdevice=0x0010
    vendor     = 'Intel Corporation'
    device     = 'Wireless 8265 / 8275'

The bhyve.conf configuration file is necessary for wifibox to function. The passthru variable specifies the location you just found with pciconf but with slashes instead of colons. See the example below from my host.

/usr/local/etc/wifibox/bhyve.conf

# These are the default values for launching the bhyve(8) guest.
# Please, at least set the `passthru` value to match with the
# slot/bus/ofunction of the wireless PCI device, which can be obtained
# from the output of the pciconf(8) tool.

cpus=1       # number of CPUs allocated for the guest
memory=90M   # amount of memory allocated for the guest
passthru=3/0/0    # expected format: "s/b/f", e.g. "3/0/0"
console=yes   # "yes" actives the nmdm(4) console

rc.conf

Configuring rc.conf is straightforward if you don’t drift too far from the defaults. The devmatch lines are required to stop the intel driver from loading instead of passing through to the Linux VM. If a driver is loaded that uses the wifi card, wifibox will fail to start.

/etc/rc.conf

devmatch_enable="YES"
devmatch_blocklist="if_iwm if_iwlwifi"

defaultrouter="10.0.0.1"
ifconfig_wifibox0="inet 10.0.0.2/24"

core.conf

I had some debugging todo on wifibox before it would work correctly. To capture all the output I required for debugging the issue, I turned on info logging.

/usr/local/etc/wifibox/core.conf

# These are the default values that control the overall behavior of
# wifibox.

loglevel=info # level of logging: none < error < warn < info < debug

wpa_supplicant.conf

Luckily, this is likely a straight copy of the /etc/wpa_supplicant.conf file on your local system.

/usr/local/etc/wifibox/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1

network={
    ssid="guest"
    key_mgmt=NONE
}

Starting wifibox

Starting the software is simple, just execute wifibox start as root.

1
# wifibox start

Once wifibox was up and running and I was able to connect to my internal network, I found I was able to download speeds up to 20MB/s from my home file server. Much better than 2MB/s using the iwm driver!

Debugging

I had a little trouble with the software working on 13.1-RC3 and had to modify the wifibox script a bit.

Essentially, the vmm.ko driver was not being found by the wifibox script. I made a quick edit to /usr/local/sbin/wifibox and changed the vmm.ko line to include the full path:

1
: "${VMM_KO:=/boot/kernel/vmm.ko}"

UPDATE 4/25/22 After upgrading to 13.1-RC4, this issue appears to have gone away.

Checking Status

You can check the status of the wifi connection by using wpa_cli inside the Linux virtual system.

In the console, execute wpa_cli -i wlan0 then run status to see the status of the wifi connection.

You should have something that looks like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
jgrafton@arachnid$ doas wifibox console
Connecting, type "~." to leave the session...
Connected

Welcome to Alpine Linux 3.15
Kernel 5.15.32-0-lts on an x86_64 (/dev/ttyS0)

wifibox login: root
wifibox:~# wpa_cli -i wlan0
wpa_cli v2.9
Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.

Interactive mode

> status
bssid=74:ac:b9:bb:27:46
freq=5745
ssid=router
id=0
mode=station
wifi_generation=5
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
ip_address=192.168.1.44
p2p_device_address=38:ba:f8:7c:d2:0c
address=38:ba:f8:7c:d2:0b
uuid=9318a6ce-962d-52fb-940a-0f1540dc42c0
ieee80211ac=1

Conclusion

wifibox is definitely a great option for getting AC speeds on a FreeBSD host with an Intel wireless networking card. It’s a little more work get setup than just a straight wireless connection but not terribly so.

UPDATE 4/25/22 Thanks to the wifibox author for integrating changes to the project so quickly after reading this blog post!