When creating VMs using libvirt, you can always use the default networking setup. The guests will use a dedicated domain, usually 192.168.122.0/24. However this has one big limitation – the other machines outside of the host cannot communicate with the guests. I have seen some solutions to workaround this, but then you have to configure each guest to accept packets coming in from outside the host. What I want to do here is to simplify the set-up and have the guests reside in the same domain as the host, and this can be done by creating a bridge.
If you are using NetworkManager, you can create the bridge from your host via the GUI provided by the nm-applet. In this example I am using lxqt, you can adapt it to your desktop environment. You can also do this via nmcli commands if you wish.
Right click on the nm-applet icon in your panel notification area. Choose ‘Edit Connections…’, click the plus/add sign, and choose ‘Bridge’ under the Virtual connections.
You can leave the default options as is. Take note of the interface name, here it is ‘bridge0’ – you will use this when creating NICs for your VMs. Under ‘General’ tab enable ‘Connect Automatically’ and disable STP in the ‘Bridge’ tab (up to you if you want these options – STP is not needed in my set-up and it takes some time to start up if enabled).
Under ‘Bridged Connections’ click on ‘Add’, pick ‘Ethernet’ and then ‘Create’, and choose the ethernet device that you want to be the bridge slave. You can adjust link negotiation fields here for your chosen interface.
Save, and now you have a working bridge for your host. To use it for your VMs in libvirt virtmanager GUI (I use the virtio device, it works well for me):
Here’s the xml snippet:
Now your guest will connect to your domain via this bridge.
Note: If you are having issues on the bridge connection especially after the next startup – most likely it is because the bridge is being defined but the related modules are not yet loaded. Here is what I did as per the libvirt documentation. First add the following to your sysctl conf file – In my case (Arch Linux), I put these in the /etc/sysctl.d/99-sysctl.conf:
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
Now to be sure the bridge modules are loaded at startup, I added the following through /etc/modules-load.d/bridge.conf file (of course you can name it any way you want just make sure you put a .conf extension):
Restart, and check to see if your bridge now works as intended.
Additional reading: libvirt wiki