Running OpenWrt (as a firewall/router) on a LXD host

Hi everyone,

So I’m getting started with LXD (super cool BTW, thank you all!) and to get my feet wet I decided to setup an all-in-one home-media-server/firewall doodah on a small mini-pc I had lying around, for the host OS I’m running Arch Linux (BTW :wink: ) on the latest zen kernel and for networking I’m using systemd-networkd and systemd-resolved.
Everything is working fine except for 2 things:
1- cannot pass a physical wifi device from host to container (ethernet works just fine though)
2- cannot reach the internet from the host even though host and openwrt can communicate (tested using iperf)

So here’s exactly what I’ve done so far:
:ballot_box_with_check: 1. setup a bridge device on the host to act as an internal switch






:ballot_box_with_check: 2. enable LXD socket: systemctl enable --now lxd.socket
:ballot_box_with_check: 2.1 Initialize LXD using: lxd init (without the default bridge).
:ballot_box_with_check: 3. create an OpenWrt instance: lxc launch images:openwrt/21.02 openwrt
:ballot_box_with_check: 3.1 add a wan interface: lxc config device add openwrt eth0 nic nictype=physical parent=eno1 name=eth0
:ballot_box_with_check: 3.2 add a lan interface: lxc config device add openwrt eth1 nic nictype=bridged parent=br0 name=eth1
:negative_squared_cross_mark: 3.3 add a wireless lan interface: lxc config device add openwrt wlan nic nictype=physical parent=wlan0 name=wlan

Error: Failed to start device “wlan”: Failed to attach interface: wlan0 to wlan: attaching specified netdev to the container failed

:ballot_box_with_check: 3.4 enable autostart: lxc config set openwrt boot.autostart true
:ballot_box_with_check: 3.5 set boot priority: lxc config set openwrt boot.autostart.priority 100
:ballot_box_with_check: 4. restart openwrt: lxc restart openwrt
:ballot_box_with_check: 5. connect to the OpenWrt web interface and configure wan and lan on eth0 and eth1 respectively (by default eth0 gets assigned as wan).
:ballot_box_with_check: 5.1 make OpenWrt is able to reach the internet. (e.g. ping
:ballot_box_with_check: 5.2 refresh package list and upgrade packages: opkg update && opkg upgrade $(opkg list-upgradable | cut -d " " -f 1)
:ballot_box_with_check: 5.3 install iperf opkg install iperf
:ballot_box_with_check: 5.4 run iperf in server mode iperf -s &
:ballot_box_with_check: 5.5 find out what ip address was assigned to host on lan: cat /tmp/dhcp.leases
:ballot_box_with_check: 5.6 ssh into host: ssh <user>@<assigned ip>
:ballot_box_with_check: 5.7 test connection between host and openwrt: iperf -c <openwrt-ip> -P $(nproc)
:negative_squared_cross_mark: 5.8 check if host can reach the internet ping or ping

There are some restrictions regarding passing in wifi devices, as I believe the parent device has to also be passed in.

Are you using the snap lxd package?

What is the role of the wifi interface, is it running hostapd as an access point or just as a client?

Quick update, so I managed to get the WAN connection working by switching over to openwrt/snapshot instead of openwrt/21.02.

How can I do that ? I thought I was passing in the whole device.

pacman -S lxd (Official arch repos).

On the host it’s unmanaged, the plan was to hand it over to OpenWrt to run it in AP mode as WLAN.

Do you have the iw tool installed on the host?


I’m not sure I’m afraid. There have certainly been issues around moving wireless NICs into containers in the past.

You didn’t answer my other question though?

Is it a hardware limitation perhaps ? is there a way to pass the PCI/USB device itself to the container ?

I’m sorry which one ?

Ah i missed it, this one.
I would suggest you run hostapd on the server, and connect it to a manual bridge which you can then connect the container to. This should be OK as normally you can’t bridge wifi interfaces, but in this case as its the access point it should be OK.

Good shout, I will give it a shot and see how it goes.
Quick question though, is there any way to pass a USB device to a container ?

You can use Instance configuration - LXD documentation or sometimes what you actually want/need to pass is the unix device(s) provided by the usb device, for that you can use Instance configuration - LXD documentation and/or Instance configuration - LXD documentation