Scott's Weblog The weblog of an IT pro specializing in virtualization, networking, open source, and cloud computing

Using KVM with Libvirt and macvtap Interfaces

In this post, I’m going to show you how to use KVM with Libvirt and macvtap interfaces for networking (as opposed to a Linux bridge or Open vSwitch). Along the way, I’ll provide some context around why this sort of approach might be interesting/useful to you.

In this post, I’ll assume you are already somewhat familiar with KVM and Libvirt; if you need an introduction to either of those, you might find this post, this post, and this post (all from my site) helpful.

Macvtap interfaces are related to macvlan interfaces (they share the same kernel driver), so you’ll want to first be sure your Linux kernel supports the macvlan driver. These commands will help you know if your kernel is good to go:

modprobe macvlan
lsmod | grep macvlan

If you get an error or the lsmod command returns no results, then you may have a problem using the macvlan driver. I tested this on Debian 8.1, Ubuntu 14.04, and CentOS 7.1, and all of them worked without any issues. If you have a relatively recent distribution of Linux, you should be fine.

Once you have KVM and Libvirt installed and working correctly, you’ll start by defining a Libvirt network to which any VMs you create will be connected. This snippet of XML code defines a Libvirt network that uses macvtap interfaces associated with the eth1 physical interface:

  <forward mode="bridge">
    <interface dev="eth1"/>

You would use the virsh net-define command with this XML to define the actual Libvirt network. Assuming the XML code above was stored in a file named macvtap-def.xml, you’d run this command:

virsh net-define macvtap-def.xml

Then you’d set the resulting Libvirt network to autostart and start it:

virsh net-autostart macvtap-net
virsh net-start macvtap-net

Then use virt-install (or the tool of your choice) to create a KVM guest domain attached to this new Libvirt network. CirrOS has a pre-built QCOW2 disk image (look here) that you can use with virt-install using a command like this (line-wrapped for readability):

virt-install --name=cirros --ram=256 --vcpus=1 \
--disk path=/home/user/cirros-0.3.2-x86_64-disk.img,format=qcow2 \
--import --network network:macvtap-net,model=virtio --vnc

Obviously, you’d need to change /home/user in the above command to the actual path you’re using in your environment (wherever you downloaded the CirrOS image).

Once this command completes, you’ll have a KVM guest domain running and attached to a macvtap interface. You can see the new macvtap interface by running ip link list; you’ll see an entry similar to the one shown below:

5: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 500
    link/ether 52:54:00:5c:15:d6 brd ff:ff:ff:ff:ff:ff

If you get into the KVM guest domain (you can do this by running virsh vncdisplay cirros and noting the VNC display where the guest’s console is accessible, then using SSH port forwarding to make that port accessible to your system), you’ll see that the MAC address of the macvtap interface on the host is identical to the MAC address of the virtual interface in the guest. This is a by-product of how macvtap/macvlan interfaces work; since there is no “intermediate” device or TAP interface, the MAC addresses on the host and in the guest will match (it is essentially the same interface in both places).

So why would one want to use macvtap interfaces, instead of a Linux bridge or Open vSwitch? One argument might be simplicity; aside from the macvlan kernel driver, there is nothing else to install, nothing else to configure, and no daemons to run. Of course, simplicity is a double-edged sword; there are also fewer features available in this sort of configuration. If you don’t need the extra functionality that you could obtain using the Linux bridge or Open vSwitch, then macvtap interfaces might be the right approach.

Other Resources

If you’re interested in playing with this but don’t want to spend a bunch of time building VMs and such, then go get Vagrant and the virtualization provider of your choice (I use VMware Fusion). After you’ve install those, visit my GitHub “learning-tools” repository and look in the kvm-macvtap directory. I’ve built a learning environment there that you can use to experiment with this functionality.

Be social and share this post!