With libvirt/qemu/kvm you can define a bridge (or more) to be used by the guest machines. The libvirt machinery should take care of the creation of the bridge - normally called virbr0 with virbr0-nic (to work around some quirks) - and will normally also take care to insert firewall rules - by way of iptables - to ensure connectivity (forwarding, accepting traffic between guests, sometimes denying outbound/inbound traffic on virbr0 altogether).

Now, I am currently in the process of migrating to nftables and I enjoy the added flexibility and the powerful syntax which for all my use cases surpasses my past experience with iptables/ip6tables and ipset in tandem. Alone the fact that I can express certain rules as pertaining to the inet family as a whole instead of IPv4 and IPv6 individually, makes it worthwhile.

Alas, libvirt officially only supports iptables or firewalld.

Now my question is this: is there a canonical way of dealing with this situation and what is it?

Here are a few scenarios I have contemplated (all without firewalld):

  1. use nftables but use the update-alternatives machinery to ensure libvirt will find an iptables (and so on) to call
  2. move bridge creation away from libvirt and into netplan, then use other means to dynamically insert the necessary rules
  3. use nftables but leave iptables active -- from all I understand this is probably the worst idea, because they are bound to clash in some edge cases or in general

1 Answer 1


My approach is below. Not sure if canonical, a pretty high bar, but seems to work well with current tools. Fell to this approach after noticing issues getting internet access for two new Qemu/KVM Windows 10 guests on my Fedora 34 host - DHCP didn't seem to be working for the guest W10 interface and iptables absence was flagged in some random virtual machine manager (VMM) error message (can't remember now!).

Host: on Fedora 34 5.13.12-200.fc34.x86_64 a) used nftables (already migrated) and snat for guest internet access, firewalld and iptables were already inactive b) used iproute2 to create the bridge interface with IP address at boot time

Guest: a) for both Windows 10 Qemu/KVM images specified the bridge interface, created at the host, using VMM, b) used a static IP address for the Windows 10 interface while in the guest's Windows 10 settings

Note the bridge interfaces are created at boot time. A tunnel interface is created when the Windows 10 is started and connects to the bridge.

Some pertinent host configuration snips for one bridge

  1. iproute2 statements
/usr/sbin/ip link add name virbr1 type bridge
/usr/sbin/ip link set virbr1 up
/usr/sbin/ip address add dev virbr1 broadcast
  1. nft snat
table nat {
      chain nat {
              type nat hook postrouting priority 100;
              policy accept;
              ip saddr counter snat to *myipaddr*;

The XML detail for one bridge from VMM view.

<interface type="bridge">
  <mac address="52:54:00:xx:xx:xx"/>
  <source bridge="virbr1"/>
  <target dev="vnet0"/>
  <model type="e1000e"/>
  <alias name="net0"/>
  <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .