Wireless NIC bridge for KVM

Hello,

I kindly ask your advice on how to bridge a wireless card in Clear Linux, in the following situation:

  1. Clear Linux server installed on an Intel NUC that has 2 network card, one wired (eno1) and one wireless (wlp2s0)
  2. A KVM machine setup, with Home Assistant OS in it
  3. An already functioning bridge for this KVM, using the wired card, by following this rather old tutorial: https://brooks.sh/2017/12/22/configuring-kvm-on-clear-linux/

My config files are as follows:

/etc/systemd/network/br0.netdev

[NetDev]
Name=br0
Kind=bridge
MACAddress=xx:xx:xx:xx:xx:xx

/etc/systemd/network/br0.network

[Match]
Name=br0

[Network]
DHCP=yes

/etc/systemd/network/80-dhcp.network

[Match]
Name=eno1

[Network]
Bridge=br0

/etc/sysctl.d/90-bridge.conf

net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0

So far so good, the KVM has access to the internet, it sees all the other clients in my network and it is being seen by the router as a standalone client.

The issue is I would like to connect the Home Assistant inside the KVM to another subnet, to separate my IOT devices from the regular ones, like PCs, laptop etc. However, the KVM should auto discover devices from both subnets, and the only way to do that I think is to create a second bridge using the wifi card.

The tutorial I used doesn’t seem to work for wireless NICs, I am stuck at the 3rd config file, as I can’t find wlp2s0 relevant files in /lib/systemd/network/. I connected to wifi using nmtui, then tried to create a bridge using Cockpit GUI, but it doesn’t work, wifi loses connection and even forgets credentials for the network saved beforehand in nmtui.

Is this possible, or is there any other way to go for achieveng this?

PS. Sorry for long post, tried to be as explicit as possible.
Thanks!

Hi Cosmin,
I’m in the same situation and couldn’t find any way to make this work.
Did you manage to get the bridge up and running?

Thanks

Hello, a bit of evolution, with 2 setup points discovered.

I found that, for bridging, the wifi card and its driver must support 4addr. Fortunately, mine does, and I was able to set it automatically at boot using a oneshot service:

Create /etc/systemd/system folder, if not already existing:

sudo mkdir /etc/systemd/system

Create a service file in this folder:

sudo nano /etc/systemd/system/4addr.service

The file has this content, replace wlp2s0 with your wifi card id, if that’s the case:

[Unit]
Description=wlan-4addr
Wants=network.target
Before=network.target systemd-networkd.service
BindsTo=sys-subsystem-net-devices-wlp2s0.device
After=sys-subsystem-net-devices-wlp2s0.device

[Service]
Type=oneshot
ExecStart=/usr/sbin/iw dev wlp2s0 set 4addr on
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Enable this service at boot:

sudo systemctl enable 4addr.service

After reboot, iw dev wlp2s0 info command (from the network-basic bundle) should output something like this:

Interface wlp2s0
ifindex 3
wdev 0x1
addr xx:xx:xx:xx:xx:xx
ssid xxxxxxxxxxxxxxx
type managed
wiphy 0
channel 10 (2457 MHz), width: 40 MHz, center1: 2447 MHz
txpower 20.00 dBm
multicast TXQ:
qsz-byt qsz-pkt flows drops marks overlmt hashcol tx-bytes tx-packets
0 0 0 0 0 0 0 0 0
4addr: on

Second setup point, as per Clear Linux wireless manual setup instructions, the filename to use for wifi should be 25-wireless-$INTERFACE_NAME.network, where $INTERFACE_NAME is wlp2s0 in my case. So, I created /etc/systemd/network/25-wireless-wlp2s0.network with this content:

[Match]
Name=wlp2s0

[Network]
Bridge=br1

The other 2 files are similar to the ones for ethernet, except br0 is replaced with br1 everywhere.

If i do sudo systemctl restart systemd-networkd.service, the bridge works, and I get the following from networkctl (copy-paste only relevant lines, I have several docker networks also):

IDX LINK TYPE OPERATIONAL SETUP
3 wlp2s0 wlan enslaved configured
4 br1 bridge routable configured

But, after reboot, wireless works but the bridge doesn’t even appear in the list - it is enabled only after I restart systemd-network. I guess is this issue: https://github.com/systemd/systemd/issues/936 ?. This is where I took the oneshot service from…

Second, if wifi drops (router restart, signal loss etc), the bridge doesn’t manage to reconnect by itself, need to restart systemd-network again:

3 wlp2s0 wlan no-carrier configuring
4 br1 bridge no-carrier configuring

Still looking forward…

1 Like

Hello, you haven’t mentioned which wifi card you are using. Very few can be bridged at all, on any distro. And the real problem is the protocol. Your access point needs to support WDS as well.

It says here:

Important Note: Unfortunately, wireless interfaces cannot be attached to a Linux host bridge, so if your connection to the external network is via a wireless interface (“wlanX”), you will not be able to use this mode of networking for your guests.

It may be doable with certain wifi nics with virtualbox via vboxnetflt driver. You will need kernel headers for that:

You may be able to get it done with a Layer 3 workaround on kvm/libvirt using a tap interface and ip forwarding.

My card is an Intel®Centrino®Advanced-N 6235, product brief here https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/centrino-advanced-n-6235-brief.pdf.

iw list command shows (truncated due to large output size):

    Supported interface modes:
             * IBSS
             * managed
             * AP
             * AP/VLAN
             * monitor

…
Supported commands:
…
* set_wds_peer

As for router, it is a DLink DIR882 with custom Padavan firmware, and I have it like this:

1

As per that libvirt support article, I guess another way would be to passthrough the wifi card to the vm, I can try that if I can’t manage to bridge it.