15

I have a VM host (KVM) that's connected to a wireless router. I'd like the virtual guests to be in the same broadcast domain as the host; i.e, receive their IP from the router's DHCP. (=Layer 2 bridging)

According to KVM documentation it's impossible: 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. (I tried it anyway, and indeed, it doesn't work :) )

There are some resources in the Internet that suggest how to make a routed interface, and it works for me. But it's Layer 3, and the guests reside in a different IP subnet.

However, I used VirtualBox in the past - and wireless bridging works there.

I've found superuser question regarding VirtualBox, that explains: Many virtual machine programs come with a special "bridge" or "filter" driver which attaches to existing network interfaces and allows the program to send and receive packets (Ethernet frames) directly.

That's exactly the outcome I want - KVM virtualization with Ethernet bridging (Layer 2). Sadly, it appears that libvirt/KVM don't include such as a driver. But I assume that it can be achieved with some other Unix tool.

Zvika
  • 289
  • 1
  • 2
  • 7

4 Answers4

5

It is not "wireless adapter" doesn't support bridging. It is access point and WiFi host-to-ap protocol. When you establish connection you authenticate your adapter's MAC. The protocol has a space for three MACs: immediate authenticated participants and third - for any end point behind AP. So WiFi mobile station could send packet to any MAC, but only use its own MAC as source address. You couldn't send any packet with another source MAC other that authenticated - AP will reject that packet.

There is also WiFi protocol capable of true bridging, called WDS. That is done by allowing four MAC addresses in the packet: two - immediate authenticated participants, i.e. bridging APs, and two - end points (source and destination) whose packet is being transferred by WiFi bridge.

Read here http://wiki.mikrotik.com/wiki/Manual:Wireless_Station_Modes#802.11_limitations_for_L2_bridging about this.

It's a pity WDS is not well standartized, and each vendor evaluates it on its own in an incompartible way. Only if the WiFi alliance were more... user-oriented organization, they'll done spec better and we'll be able to do wifi bridging here and there, between arbitrary vendor solutions, and indeed between guest machines and wireless network!

Proxy-ARP is not L2 solution though, it is ROUTING solution, i.e. L3. It tricks both sides so you could have same subnet here and there, but still this is routing and by the way this somewhat messes up network. See MAC table on any machine to see what is going there: all MACs for "that side" are MAC of our proxy-arp router.

For true L2 solution you could try linux "MAC NAT" feature which is configured with ebtables utility. Since this is the only true L2 solution I know, I tend to think it is used by VirtualBox. However, it basically looks like proxy-arp. You certainly should be able to implement this this with KVM and libvirt.

5

I had exactly the same requirement as Zvika. By the way, his post on the subject is excellent. The alternative I found is this: configure a routed network in KVM in the range 192.168.1.160/28 (so, dedoimedo third solution, the "dirty hack") and then, instead of creating an ARP proxy the Zvika's way, I used parprouted, which is available in Ubuntu/Mint as a package with the same name. With parprouted, you can just type:

sudo parprouted virbr1 wlan0

et voilĂ , traffic works in both ways to/from the guest VM and the other devices in 192.168.1.0/24 network, as well as to/from external systems (e.g. Internet sites) if that network is behind a NAT.

This was hard, anyway, I spent days searching on this subject and no source was as clear as Zvika's blog entry!!

4

According to KVM's docs, it is not possible to use a bridge with a wireless NIC. I do not know the reason why even though I used to bridge the guest on VirtualBox.

I have spent some few hours to figure out how to connect the guest to the host's wireless network and I found out the easiest way to do it is using a TAP device. The only disadvantage of this method is that you can't use DHCP on the guest and you have to manually give it an IP address from the wireless network subnet (Which may cause IP conflicts or inconvenience in case of deploying lots of VMs).

Here are the steps to connect the guest on the host's wireless network using a TAP device:

0/ Enable IPv4 routing for the Linux kernel

sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

1/ Create a tap device named tap0 accessible from user guest (Replace with your username) without sudo:

sudo ip tuntap add mode tap tap0 user guest
sudo ip link set tap0 up

2/ Assign an IP address to the tap0 device (It doesn't have to be from the wireless network subnet):

sudo ip addr add 10.10.10.10/24 dev tap0

3/ Use parprouted (You might have to install it) to implement proxy arp bridging which allows bridging the guest Ethernet behind the host's wireless NIC.

sudo parprouted wlan0 tap0

(Replace wlan0 with your host's wireless interface)

4/ Adding some routing tables entries to allows packets to travel through the ends of the tap device:

sudo iptables -A INPUT -i tap0 -j ACCEPT
sudo iptables -A FORWARD -i tap0 -j ACCEPT
sudo iptables -A FORWARD -o tap0 -j ACCEPT

On the guest assign a static IP address from the host's wireless network subnet. For example if your wlan0 is on 192.168.1.0/24 then the guest can be configured with

sudo ip addr add 192.168.1.30/24 dev eth0

(eth0 is your guest's NIC)

or permanently in /etc/network/interfaces with:

auto eth0
iface eth0 inet static
  address 192.168.1.30
  netmask 255.255.255.0
  network 192.168.1.0
  broadcast 192.168.1.255
  gateway 192.168.1.25

Launch your guest with:

kvm -hda guest.img -m 512 -net nic -net tap,ifname=tap0,script=no

Now pinging works between all machines connected on your wireless network and the guests.

2

The official documentation is way too pessimistic. As always, someone smart has figured it out: you find the (lengthy) instructions to do this here. I tried it, it's a cinch.

Edit:

I am not sure why the first solution posted in the articled referenced above does not work for you, it did for me and you provide no extra information. Still, you may wish to consider an alternative solution, here, provided by Bohdi Zazen, which uses proxy-arp. I never tried this (sol. n.1 worked for me, so what was the point), but you may give it a chance.

MariusMatutiae
  • 48,517
  • 12
  • 86
  • 136