Creating bridge manually
To enable support for bridged networking I followed the guide from arch wiki.
Step 1: Disable any Network manager you might have installed
We are going to use netctl. For that we need to disable any network manager we have active, e.g.:
sudo systemctl stop dhcpcd@<interface>.service sudo systemctl disable dhcpcd@<interface>.service # or sudo systemctl stop NetworkManager.service sudo systemctl disable NetworkManager.service
It might be a good idea to reboot also.
Step 2: Install netctl
Install netctl of course:
sudo pacman -S netctl
Step 3: Create a netctl profile
Now we are going to create our netctl bridge profile. Copy /etc/netctl/examples/bridge to /etc/netctl/bridge :
sudo cp /etc/netctl/examples/bridge /etc/netctl/bridge
In this example, we create a bridge called br0 which has real Ethernet adapter eth0
sudo nano /etc/netctl/bridge Description="Example Bridge connection" Interface=br0 Connection=bridge BindsToInterfaces=(eth0) IP=dhcp #IP=static #Address='192.168.1.125/24' #Gateway='192.168.1.1' ## Ignore (R)STP and immediately activate the bridge SkipForwardingDelay=yes
This will use the dhcp to assign IP address, but you can also assign static IP. For more info look the arch wiki.
Now enable and start the profile:
sudo netctl enable bridge sudo netctl start bridge
Your network should be up and running now.
ip addr
Step 4: Configure QEMU
Copy /etc/qemu/bridge.conf.sample to /etc/qemu/bridge.conf .
sudo cp /etc/qemu/bridge.conf.sample /etc/qemu/bridge.conf
Modify /etc/qemu/bridge.conf to contain the name of the bridge profile we created earlier so that it can be used by QEMU:
sudo nano /etc/qemu/bridge.conf # add this allow br0
Step 5: Creating bridge manually
We will replace the normal Ethernet adapter with a bridge adapter and bind the normal Ethernet adapter to it. Install bridge-utils :
sudo pacman -S bridge-utils
Enable IPv4 forwarding:
sudo sysctl net.ipv4.ip_forward=1 # and to make it permanent sudo -s echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-sysctl.conf
Load the tun module and configure it to be loaded on boot
sudo -s modprobe tun echo "tun" > /etc/modules-load.d/tun.conf
Create the /etc/qemu-ifup and /etc/qemu-ifdown scripts:
#!/bin/sh echo "Executing /etc/qemu-ifup" echo "Bringing up $1 for bridged mode..." sudo /usr/bin/ip link set $1 up promisc on echo "Adding $1 to br0..." sudo /usr/bin/brctl addif br0 $1 sleep 2
#!/bin/sh echo "Executing /etc/qemu-ifdown" sudo /usr/bin/ip link set $1 down sudo /usr/bin/brctl delif br0 $1 sudo /usr/bin/ip link delete dev $1
Adapt the group and the permissions:
sudo chown root:kvm /etc/qemu-ifup sudo chown root:kvm /etc/qemu-ifdown sudo chmod 750 /etc/qemu-ifup sudo chmod 750 /etc/qemu-ifdown
Use visudo to add the following to your sudoers file:
Cmnd_Alias QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl %kvm ALL=NOPASSWD: QEMU
It is recommended for performance and security reasons to disable the firewall on the bridge
sudo nano /etc/sysctl.d/10-disable-firewall-on-bridge.conf # add the following net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
and apply the changes immedietly
sudo sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf
If you get errors here the you have to probably load the br_netfilter module and configure it to be loaded on boot
sudo -s modprobe br_netfilter echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf sudo sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf
Adapt your QEMU script
Final step is to adapt your existing script that you use to launch your VM client. To use bridged networking the script should look like this:
USERID=$(whoami) # Get name of newly created TAP device; see https://bbs.archlinux.org/viewtopic.php?pid=1285079#p1285079 precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort) sudo /usr/bin/ip tuntap add user $USERID mode tap postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort) IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation")) # This line creates a random MAC address. The downside is the DHCP server will assign a different IP address each time printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) # Instead, uncomment and edit this line to set a static MAC address. The benefit is that the DHCP server will assign the same IP address. # macaddr='52:54:be:36:42:a9' qemu-system-i386 -net nic,macaddr=$macaddr -net tap,ifname="$IFACE" $* sudo ip link set dev $IFACE down &> /dev/null sudo ip tuntap del $IFACE mode tap &> /dev/null