Wifibox on my GhostBSD laptop

Tired of having issues with WiFi connectivity when using my Dell Lattitude 5591 laptop I decided to investigate Wifibox as a solution. Now I have been using it for almost a week and I have to say that for FreeBSD, this is the way.

Project FreeBSD Wifibox: https://github.com/pgj/freebsd-wifibox

Wifibox deploys a Linux guest to drive a wireless networking card on the FreeBSD host system with the help of PCI pass-through. There have been guides on the Internet to suggest the use of such techniques to improve the wireless networking experience on FreeBSD, of which Wifibox tries to implement as a single easy-to-use software package.

Installation

I installed Wifibox using the GhostBSD Software Station:

I simply searched for “wifibox” and the dependencies followed:

  • grub2-bhyve
  • socat
  • wifibox
  • wifibox-alpine
  • wifibox-core

Configuration:

After the installation to the system, check the sample configuration files provided in the /usr/local/etc/wifibox directory and follow the instructions to create a working configuration, otherwise wifibox will refuse to start. For systems that might be put in sleep mode, e.g. laptops, there is a sample devd.conf(5) configuration file in the /usr/local/etc/devd directory that can be used to restart wifibox on resume.

get wifi card specs:

I used pciconf -lBbcevV iwm0 to get the pci address of my Wi-Fi card

iwm0: <Intel(R) Dual Band Wireless AC 9560>
iwm0@pci0:0:20:3

Then I added it to the bhyve.conf file

Wifibox configuration

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

cpus=1
memory=128
console=yes
passthru=0/20/3

I edited the provided devd/wifibox.conf file so that Wifibox continues to work after putting the laptop to sleep. I copied these settings from the discussions on the wifibox github page. These settings have been working for me so far.

cat /usr/local/etc/devd/wifibox.conf

# This is a `devd(8)` configuration file to run the resume action of

# wifibox on the ACPI resume event. Review the contents and create a

# copy of it without the `.sample` extension to use it. Restart the
# `devd` service once the file has been created.

notify 11 {
match "system" "ACPI";
match "subsystem" "Suspend";
action "logger 'Stopping wifibox before suspend' && /usr/local/sbin/wifibox stop && /etc/rc.suspend acpi $notify";
};

notify 11 {    
match "system" "ACPI";    
match "subsystem" "Resume";    
action "/etc/rc.resume acpi $notify && logger 'Starting wifibox after resume and getting IP via DHCP' && /sbin/kldunload vmm && /sbin/kldload vmm && /usr/local/sbin/wifibox start guest && /sbin/dhclient wifibox0";
};

The next file I edited was the /usr/local/etc/wifibox/wpa_supplicant/wpa_supplicant.conf file. All I had to do was copy over the WiFi settings for my connection from the FreeBSD /etc/wpa_supplicant.conf file

Next configure the Host:

Disable local WiFi and enable Wifibox

By default, PCI pass-through is disabled for AMD-based hardware, hence it must be explicitly enabled via the corresponding syctl(8) variable. This can be done by adding the following line to either /etc/sysctl.conf or /boot/loader.conf depending on whether vmm(4) is going to be loaded by wifibox or it is already loaded at boot.

added this line to /boot/loader.conf

# Wifibox
hw.vmm.amdvi.enable=1

In order to make wifibox work as a system service, the following line has to be added to rc.conf(5).

wifibox_enable="YES"

At the same time, make sure that no FreeBSD driver is configured for the same device and remove all the related settings from there. The devmatch(8) utility might be used to stop any conflicting drivers from loading automatically. For example, the iwm(4) and iwlwifi(4) native drivers could be disabled in rc.conf(5) as shown below.

devmatch_enable="YES"
devmatch_blocklist="if_iwm if_iwlwifi"

I made the following changes to my /etc/rc.conf file:

Disabled local wifi:

#WiFi
#wlans_iwm0="wlan0"
#ifconfig_wlan0="WPA DHCP"
#create_args_wlan0="wlanmode sta regdomain FCC country US"
##wlandebug_wlan0="+state +node +auth +assoc +dot1xsm +wpa +scan"

Enabled Wifibox service:

#wifibox
wifibox_enable="YES"
devmatch_enable="YES"
devmatch_blocklist="if_iwm if_iwlwifi"
#DHCP
ifconfig_wifibox0="SYNCDHCP"
background_dhclient_wifibox0="YES"
defaultroute_delay="0"
# end wifibox

This is how /etc/rc.conf looks on my terminal emulator:

Using Wifibox

The wifibox0 networking interface can be brought up with the use of the netif service.
# service netif start wifibox0
For static IP address configurations, the routing service has to be restarted as well.
# service routing restart

After configuring Wifibox and GhostBSD to use Wifibox I restarted my computer. Then I ran:

#service netif start wifibox0

and Wifibox instantly connected to my WiFi! To verify that Wifibox was working as intended. I ran a speed test and was able to get the fastest speed available on my WiFi network connection and hardware:

Idle Latency: 6.47 ms (jitter: 0.84ms, low: 5.83ms, high: 7.14ms)

Download: 556.38 Mbps (data used: 982.2 MB)
20.03 ms (jitter: 16.97ms, low: 8.80ms, high: 286.34ms)

Upload: 235.55 Mbps (data used: 229.0 MB)
11.10 ms (jitter: 5.34ms, low: 5.31ms, high: 32.83ms)

Packet Loss: 0.0%

Connect WiFi box on login/restart:

Every time the computer is logged off or restarted the networking interface needs to be manually brought up:
# service netif start wifibox0

This is a PITA of course so I created a simple script
~/scripts/wifibox_restart.sh

#!/bin/sh
doas service routing restart
doas service netif restart wifibox0

which I added to my
System > Preferences > Personal > Startup Applications

Now when I log in, the startup script re-establishes the connection. The last caveat is what happens when I set the machine to sleep and wake it back up. The wifibox0 interface fails to reconnect. So I added a menu item so I can easily bring the interface back up and connect to the network:

Findings

Never issue a service wifibox restart. This freezes the computer. Sometimes service wifibox restart guest works. Most times it also freezes the computer and restarts it.

Best way to manage Wifibox is to use the console and issue commands there. These are a few examples of the commands I use:

wpa_supplicant tool has its own associated service and it can be checked by the following command.

# rc-service wpa_supplicant status

Sometimes it is connected to the wrong Access Point (I have 3 at the house) and I need it to reconnect quickly I may just restart Wifibox from the console:

# rc-service networking restart

I hope this helps someone…

Edit #1

Another way to bring the wifibox0 interface is to create a /etc/rc.local script. This file probably doesn’t exist on your machine because its the old way of doing rc scripting but this seems to be the easiest way to have wifibox work upon restart of the machine.

For some reason on reboot the the wifibox0 interface fails to get an IP from DHCP, seems to be because the interface doesn’t exist before the bhyve VM is started, work around until I find a solution:

Edit `/etc/rc.local’:

/sbin/dhclient wifibox0

Reboot, all should be good

https://forums.sheridancomputers.co.uk/t/how-to-setup-wifibox-on-freesbd/102
Edit #2

To reliably have the WiFi connection working upon waking from sleep we need to re-edit the /usr/local/etc/devd/wifibox.conf Thanks to q-pa https://github.com/pgj/freebsd-wifibox/issues/31#issuecomment-1698575652

notify 11 {
match "system" "ACPI";
match "subsystem" "Resume";
action "/etc/rc.resume acpi $notify && logger 'Starting wifibox after resume and getting IP via DHCP' && /sbin/kldunload vmm && /sbin/kldload vmm && /usr/local/sbin/wifibox start guest && /sbin/dhclient wifibox0";
};

Design a site like this with WordPress.com
Get started