Skip to content

Managing Networks in Libvirt

Get Network Information

Command Use
virsh net-list List active Networks
virsh net-list --inactive List inactive networks
virsh net-list --all List all networks
virsh net-info <network-name> Get Info of the network
virsh net-dumpxml <network-name> Get complete network definition

Managing Network State

Command Use
virsh net-start <network-name> Activate Network
virsh net-destroy <network-name> Deactivate Network
virsh net-autostart <network-name> Enable Auto Activation on boot
virsh net-autostart <networ-name> --disable Disable Auto activation on boot

Network Management

Command Use
virsh net-edit <network-name> Edit Network Definition XML (Temporary)
virsh net-define /path/to/xml Define a network (Create without starting)
virsh net-create /path/to/xml Define and activate a network (Create and Start)
virsh net-undefine <network-name> Remove defined network (delete network)

Creating XML for Network Definition

🧩 Element βœ… Required πŸ“˜ Description
<network> βœ… Yes Root element that wraps the entire network definition.
<name> βœ… Yes Unique name for the network.
<uuid> ❌ Optional Unique identifier; auto generated if omitted.
<bridge> βœ… Yes Defines the bridge device name (e.g., virbr0).
<forward> ❌ Optional Specifies forwarding mode (e.g., NAT, route); needed for external access.
<domain> ❌ Optional Sets DNS domain name for guests.
<ip> ❌ Optional Defines IP address and netmask for the network.
<dhcp> ❌ Optional Inside <ip>; enables DHCP and IP assignment.
<range> ❌ Optional Inside <dhcp>; sets DHCP IP range.
<host> ❌ Optional Inside <dhcp>; maps MAC to static IP.
<dns> ❌ Optional Custom DNS settings like host records or forwarders.
<portgroup> ❌ Optional VLAN tagging and port isolation.
<mtu> ❌ Optional Sets MTU size for the network.
<bandwidth> ❌ Optional QoS settings like inbound/outbound limits.
<route> ❌ Optional Adds static routes for guests.
<namespace> ❌ Optional Controls network namespace behavior.

Main XML component

<network>

</network>

name

<name>my-net</name>

bridge

<bridge name='virbr0' stp='on' delay='0'/>

or

<bridge name='virbr0'/>

:::info <bridge> element will create a virtual bridge that will be managed by libvirt :::

:::warning <bridge> element not to be used if using already existing bridge or any bridge that is already created and managed by some other service. :::


forward

If not specified, the network becomes host only network. VMs can communicate to each other also to host.

nat

<forward mode='nat'>
  <nat>
    <port start='1024' end='65535'/>
  </nat>
</forward>

route

<forward mode='route'/>

bridge

<forward mode='bridge'/>

:::info If interface is not specified this bridge network will be host-only network :::

<forward mode='bridge'>
  <interface dev='br0'/>
</forward>

:::info This will enable VMs to get IP from physical network (LAN) :::

private

<forward mode='private'/>

This is isolated mode, no access to host or external networks


ip

<ip address='192.168.100.1' netmask='255.255.255.0'>
  <!-- Optional sub-elements go here -->
</ip>

IP should always have IP addresses and not a network ID along with subnet mask.

dhcp

<dhcp>
  <range start='192.168.100.2' end='192.168.100.254'/>
  <host mac='52:54:00:aa:bb:cc' ip='192.168.100.10'/>
  <host mac='52:54:00:aa:bb:ed' ip='192.168.100.21'/>
</dhcp>

dns

<dns>
    <host ip='192.168.100.11'>
      <hostname>vm1.local</hostname>
    </host>
    <host ip='192.168.100.12'>
      <hostname>vm2.local</hostname>
    </host>
    <host ip='192.168.100.13'>
      <hostname>vm3.local</hostname>
    </host>
    <forwarder addr='8.8.8.8'/>
    <forwarder addr='1.1.1.1'/>
</dns>

route

<route address='192.168.200.0' netmask='255.255.255.0' gateway='192.168.100.1'/>

domain

If domain is not specified, then guest VM in that network can resolve the hostnames of all other guest VMs.

If specified, then hostname and FQDN can be resolve by all guest VMs in that network.

:::info If the guest VM has DNS server same as the IP of that Network :::

<domain name='mynet.local' localOnly='yes'/>

:::info localonly=’yes’ will not forward the query to external DNS avoiding unexpected results :::


Using virsh command to add or remove DNS entries to a network

To add a DNS entry

virsh net-update <network_name> \
add dns-host "<host ip='10.10.10.10'><hostname>vm01.test.com</hostname></host>" \
--live --config

To remove a DNS entry

virsh net-update <network_name> \
delete dns-host "<host ip='10.10.10.10'><hostname>vm01.test.com</hostname></host>" \
--live --config

To add a text record in DNS

virsh net-update default add dns-txt \
  "<txt name='example' value='hello world'/>" \
  --live --config

Using virsh commands to modify DHCP

To add a DHCP range

virsh net-update default add ip-dhcp-range \
  "<range start='192.168.122.100' end='192.168.122.120'/>" \
  --live --config

To remove DHCP range

virsh net-update default delete ip-dhcp-range \
  "<range start='192.168.122.100' end='192.168.122.120'/>" \
  --live --config