(Last Updated On: April 20, 2019)

There are many choices for network configurations in the KVM host. In this post, I’ll guide you through two main choices to configure KVM networking. We’ll consider internal networking and external networking for Guest operating systems running on KVM.

The two ways to configure KVM networking we’ll cover are:

  • Using a Linux bridge with NAT for KVM guests
  • Using a Linux bridge (without NAT) for KVM guests

The other available ways to configure KVM networking that we won’t cover on this post are:

  • Using an Open vSwitch bridge with KVM guests
  • Using the MacVTap driver with KVM guests

Creating KVM Linux NAT-based bridge network

This network configuration uses a Linux bridge in combination with Network Address Translation (NAT) to enable a guest OS to get outbound connectivity regardless of the type of networking (wired, wireless, dial-up, and so on) used in the KVM host without requiring any specific administrator configuration.

Using this method to configure KVM networking is simple and straightforward.

The quickest way to get started is by utilizing existing default network configuration. Dump default network xml configuration using below command.

$ sudo virsh net-dumpxml default > br1.xml

You can edit this file accordingly and use it to define new network interface

Manually create xml file

Have a look at below file for general overview of how the file should look like:

Create a new file br1.xml

sudo vim br1.xml

Add network configuration parameters.

<network>
  <name>br1</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='br1' stp='on' delay='0'/>
  <ip address='192.168.10.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.10.10' end='192.168.10.100'/>
    </dhcp>
  </ip>
</network>


To define a network from an XML file without starting it, use:

$ sudo virsh net-define  br1.xml
Network br1 defined from br1.xml

To start a (previously defined) inactive network, use:

$ sudo virsh net-start br1
Network br1 started

To create transient network that cannot be set to autostart use:

$ sudo virsh net-create br1.xml
Network br1 created from br1.xml

To set the network to autostart, use:

$ sudo virsh net-autostart br1
Network br1 marked as autostarted

Check to Confirm if autostart flag is turned to yes – Persistent should read yes as well.

$ sudo virsh net-list --all
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 br1                  active     yes           yes
 default              active     yes           yes

To convert a network name to network UUID – previously defined UUID, use:

$ sudo virsh net-uuid br1
ed90dfcf-c895-4d5c-9d34-bd307f8c3ec0

Confirm that the bridge was successfully created

You can use brctlcommand provided by bridge-utils package to check available bridges on your Linux system

# brctl show br1
bridge name	bridge id		STP enabled	interfaces
br1		8000.525400515825	yes		br1-nic

Checking Ip address assigned to the interface

You can use ip command for this:

# ip addr show dev br1
19: br1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:51:58:25 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.1/24 brd 192.168.10.255 scope global br1
       valid_lft forever preferred_lft forever

Attaching an interface to a VM

In this example, I’ll attach br1 interface to the vm pxe that will be configured as Preboot eXecution Environment server.

  • This takes effect immediately, and the NIC will be persistent on further reboots.
  • Attach the interface as below:
$ sudo virsh attach-interface --domain pxe --type bridge \
--source br1 --model virtio --config --live  

$ sudo virsh domiflist pxe
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      bridge     virbr0     virtio      52:54:00:e9:ad:17
vnet1      bridge     br1        virtio      52:54:00:47:2f:eb

Detaching an interface attached to a VM

$ sudo virsh detach-interface --domain pxe --type bridge --mac 52:54:00:47:2f:eb --config

$ sudo virsh domiflist pxe
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      bridge     virbr0     virtio      52:54:00:e9:ad:17

Removing a network

To fully remove a network , follow steps below:

  • First destroy the network to put it in inactive mode:
$ sudo virsh net-destroy br1
Network br1 destroyed
  • Next, undefine the network.
$ sudo virsh net-undefine br1
Network br1 has been undefined
  • Confirm that the network is not listed as inactive/active.
$ sudo virsh net-list --all  
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              active     yes           yes
  • You can as well use brctl command to check:
$ sudo brctl show  br1
bridge br1 does not exist!

Creating KVM Linux bridge (without NAT) for KVM guests

An alternative to using a NAT-based network to configure KVM networking would be to use a standard Linux network bridge.

A network bridge is a Link Layer device which forwards traffic between networks based on MAC addresses and is therefore also referred to as a Layer 2 device. It makes forwarding decisions based on tables of MAC addresses which it builds by learning what hosts are connected to each network.

A software bridge can be used within a Linux host in order to emulate a hardware bridge, for example in virtualization applications for sharing a NIC with one or more virtual NICs.

Create Linux Bridge using nmcli

Nmcli is a command-line client for NetworkManager. It allows controlling NetworkManager and reporting its status.

To create a Linux bridge called br0 using nmcli, run the following commands:

nmcli con add type bridge con-name br0 ifname br0 autoconnect yes

This example demonstrates adding a bridge master connection and one slave.

  • The first command adds a master bridge connection, naming the bridge interface and the profile as br0.
  • The second command add slaves profile enslaved to br0. The slave will be tied to ens3interface.
  • The last command will disable 802.1D STP for the br0 profile.

Furthe modify the bridge to enable autoconnect, add ipv4 address and gateway:

nmcli connection modify br0 ipv4.addresses 192.168.10.5/24 \
ipv4.method manual ipv4.gateway 192.168.10.1  ipv4.dns  8.8.8.8 

Bring up the interface:

# nmcli con up br0
Connection successfully activated (master waiting for slaves) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/15)

# brctl show  br0
bridge namebridge idurlSTP enabledinterfaces
br0-slave-18000.000000000000no

Create Linux Bridge using brctl

If you don’t have networkmanager installed, you can use brctl command installed with the installation of bridge-utils to configure Linux bridge that we’ll use to configure KVM networking.

Create a new bridge:

sudo brctl addbr br0

Add a device to a bridge, for example eth0:

sudo brctl addif br0 eth0

Assigning an IP address:

sudo ip addr add dev br0 192.168.2.4/24
sudo ip route add default via 192.168.2.1 dev br0

Show current bridges and what interfaces they are connected to:

$ brctl show

Set the bridge device up:

$ sudo ip link set up dev br0

Delete a bridge, you need to first set it to down:

$ sudo ip link set dev br0 down
$ sudo brctl delbr br0
$ sudo brctl delbr br0

If you want to generate KVM VM templates, refer to:

How to Create CentOS / Fedora / RHEL VM Templates on KVM

To Automate deployment of VMs on KVM, check:

How to Provision VMs on KVM with Terraform

Further reading:

Mastering KVM Virtualization

Virtualization Essentials, 2nd Edition