I wanted to setup bridge networking with my main Arch Linux box so that I could connect to virtual machines in KVM. I was using the MACVTAP connection in Libvirtd, however that prevents you from being able to connect to the virtual machines due to the Linux host not knowing how to talk to the MAC addresses of the virtual machines with them being on the same interface card (https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_host_configuration_and_guest_installation_guide/app_macvtap). There are hacks to setup a MACVTAP network connection for the host as well, but it is best practice to use a bridged connection instead.

Configuring the Bridge Network

I’m not going to get into complete details here on how to do this, as there are many guides on the internet for doing this. I am, however, going to provide a link to the Arch Wiki with the standard steps for the network tools of your choice, I personally am using Network Manager mainly because it works for me. When researching implementing this configuration, I seem to find a lot of old documentation for CentOS 6/Debian 7 which is not up to date with today’s standards. The Arch Wiki article is reputable and also up to date in this case.

Configuring the Firewall

This was the main problem I ran into when setting up a bridge network, older articles by Red Hat has lead me to the solution which I will provide both how to solve in iptables, and firewalld.

IPTables

iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

FirewallD

firewall-cmd --permanent --direct --passthrough ipv4 -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
firewall-cmd --reload

The code above is the secret to getting the bridge connection to work within a virtual machine. Without it, DHCP was not working, and manually setting an IP address does not lead to a working interface for IPv4.

Disabling Net Filter

In reviewing implementation of bridging, there always seem to be one change everyone makes to improve performance of bridged networks. And that is to disable the network filter. Doing so is fairly simple, adjust the files below.

/etc/sysctl.d/bridge.conf

net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0

/etc/udev/rules.d/99-bridge.rules

ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf"

You can then run sysctl -p /etc/sysctl.d/bridge.conf manually to load the system configurations.

Final LibvirtD Network Configurations

Now that the bridged network is setup, you can setup the network configuration for your virtual machines. There are two ways to do this, you can setup a shared device name in virt-manager, or you can configure via xml like so:

<interface type="bridge">
  <source bridge="br0"/>
  <mac address="52:00:00:00:00:00"/>
</interface>

Or, you can setup a network in libvirtd as follows to make it an easy selection.

cat > /tmp/br0.xml <<XML
<network>
  <name>br0</name>
  <forward mode="bridge"/>
  <bridge name="br0" />
</network>
XML
virsh net-define /tmp/br0.xml
virsh net-start br0
virsh net-autostart br0
virsh net-list --all

Start your Virtual Machine and you should be good to go!