I spent some time working with macvlan interfaces on KVM hypervisors last weekend. They’re interesting because they’re not really a bridge. It allows you to assign multiple MAC addresses to a single interface and then allow the kernel to filter traffic into tap interfaces based on the MAC address in the packet. If you’re looking for a highly detailed explanation, head on over to waldner’s blog for a deep dive into the technology and the changes that come along with it.
Bridging can become a pain to work with, especially when you’re forced to add in creative filtering rules and keep them updated. The macvlan interfaces can help with that (read up on VEPA mode). There are some interesting email threads showing that macvlan interfaces can improve network performance for various workloads. Low latency workloads can benefit from the simplicity and low overhead of macvlan interfaces.
systemd-networkd and macvlan interfaces
Fortunately for us, systemd-networkd makes configuring a macvlan interface really easy. I’ve written about configuring bridges with systemd-networkd and the process for macvlan interfaces is similar.
In my scenario, I have a 1U server with an ethernet interface called
enp4s0 (read up on interface naming with systemd-udevd). I want to make a macvlan interface for virtual machines and I’ll be attaching VM’s to that interface via macvtap interfaces. It’s similar to bridging where you make a bridge and then give everyone a port on the bridge.
Start by creating a network device for our macvlan interface:
# /etc/systemd/network/vmbridge.netdev [NetDev] Name=vmbridge Kind=macvlan [MACVLAN] Mode=bridge
I’ve told systemd-networkd that I want a macvlan interface set up in bridge mode. This will allow hosts and virtual machines to talk to one another on the interface. You could choose
vepa for the mode if you want additional security. However, this will force traffic out to your upstream switch/router and makes it challenging for hosts and guests to communicate with each other.
Now that we have a device configured, let’s configure the IP address for the macvlan interface (similar to configuring a bridge):
# /etc/systemd/network/vmbridge.network [Match] Name=vmbridge [Network] IPForward=yes Address=192.168.250.33/24 Gateway=192.168.250.1 DNS=192.168.250.1
Let’s tell systemd-networkd that our physical network interface,
enp4s0, is part of this interface:
# /etc/systemd/network/enp4s0.network [Match] Name=enp4s0 [Network] MACVLAN=vmbridge
This is very similar to a configuration for a standard Linux bridge. Once you’ve reached this step, you’ll most likely want to reboot to ensure all of your network devices come up properly.
Attaching a virtual machine
Attaching a KVM virtual machine to the macvlan interface is quite easy. When you’re creating a new VM using
virt-manager, look for this setting in the wizard:
If you’re installing via
virt-install just use the following argument for your network configuration:
You’ll end up with interfaces like these after creating multiple virtual machines:
mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500 link/ether 52:54:00:83:53:f2 brd ff:ff:ff:ff:ff:ff promiscuity 0 macvtap mode bridge addrgenmode eui64 15: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500 link/ether 52:54:00:f1:76:0b brd ff:ff:ff:ff:ff:ff promiscuity 0 macvtap mode bridge addrgenmode eui64 17: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500 link/ether 52:54:00💿53:34 brd ff:ff:ff:ff:ff:ff promiscuity 0 macvtap mode bridge addrgenmode eui64 20: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500 link/ether 52:54:00:18:79:d3 brd ff:ff:ff:ff:ff:ff promiscuity 0 macvtap mode bridge addrgenmode eui64