Customizing dnsmasq DHCP Options with libvirt: Advanced Network Boot Configuration


8 views

When working with libvirt's network configuration, you'll notice the DHCP options for network booting are quite limited. The current implementation only exposes two parameters through the bootp element:

<bootp file='test.ipx' server='10.10.10.2'/>

This generates the following dnsmasq configuration:

dhcp-boot=test.ipx,,10.10.10.2

Many network boot scenarios require more sophisticated DHCP options that aren't directly supported by libvirt's current implementation. For example:

dhcp-userclass=set:ipxe,iPXE
dhcp-boot=tag:ipxe,http://matchbox.foo:8080/boot.ipxe

Method 1: Using libvirt hooks

Create a hook script that modifies the dnsmasq configuration after libvirt generates it:

#!/bin/bash
# /etc/libvirt/hooks/network

if [ "$1" = "default" ] && [ "$2" = "started" ]; then
    echo "dhcp-userclass=set:ipxe,iPXE" >> /var/lib/libvirt/dnsmasq/default.conf
    echo "dhcp-boot=tag:ipxe,http://matchbox.foo:8080/boot.ipxe" >> /var/lib/libvirt/dnsmasq/default.conf
    systemctl restart libvirtd
fi

Method 2: Custom dnsmasq instance

Disable libvirt's built-in dnsmasq and run your own instance:

<network>
  <name>default</name>
  <forward mode='nat'/>
  <dhcp>
    <range start='192.168.122.2' end='192.168.122.254'/>
  </dhcp>
  <dnsmasq:options xmlns:dnsmasq="http://libvirt.org/schemas/network/dnsmasq/1.0">
    <dnsmasq:option value="conf-file=/etc/dnsmasq.d/custom.conf"/>
  </dnsmasq:options>
</network>

Method 3: Direct configuration modification

For temporary testing, you can directly edit the generated configuration:

# Find the PID of dnsmasq
ps aux | grep dnsmasq

# Edit the temporary config file
vim /var/lib/libvirt/dnsmasq/default.conf

# Add your custom options and restart
systemctl restart libvirtd

The libvirt project is actively developed, and there's an open feature request for more flexible DHCP options. You might want to:

  • Subscribe to libvirt mailing lists for updates
  • Consider contributing patches if you need this functionality urgently
  • Monitor GitHub issues for progress on this feature

When working with libvirt's network configuration, the built-in dnsmasq integration provides limited DHCP options through the bootp element. The current implementation only supports:

<bootp file='test.ipx' server='10.10.10.2'/>

Which generates the following dnsmasq configuration:

dhcp-boot=test.ipx,,10.10.10.2

Many network boot scenarios require more sophisticated DHCP options that aren't exposed through libvirt's XML interface. Specifically, we often need:

  • Custom DHCP user classes
  • Conditional boot file assignments
  • Additional dnsmasq parameters

For example, when working with iPXE, we might need configuration like:

dhcp-userclass=set:ipxe,iPXE
dhcp-boot=tag:ipxe,http://matchbox.foo:8080/boot.ipxe

Method 1: Post-Processing the Generated Configuration

While libvirt doesn't directly support these options, you can modify the generated configuration:

# Create a script to append custom options
echo "dhcp-userclass=set:ipxe,iPXE" >> /var/lib/libvirt/dnsmasq/default.conf
echo "dhcp-boot=tag:ipxe,http://matchbox.foo:8080/boot.ipxe" >> /var/lib/libvirt/dnsmasq/default.conf

# Restart the network
virsh net-destroy default
virsh net-start default

Note: This approach is fragile as libvirt may overwrite the configuration during network restarts.

Method 2: Using Custom Configuration Snippets

Recent versions of dnsmasq support including additional configuration files:

# Create a custom config directory
mkdir -p /etc/libvirt/dnsmasq-custom

# Add your custom options
echo "dhcp-userclass=set:ipxe,iPXE" > /etc/libvirt/dnsmasq-custom/ipxe.conf
echo "dhcp-boot=tag:ipxe,http://matchbox.foo:8080/boot.ipxe" >> /etc/libvirt/dnsmasq-custom/ipxe.conf

# Modify the libvirt network definition
virsh net-edit default

Add this to your network XML:

<dnsmasq:options>
  <dnsmasq:option value='--conf-dir=/etc/libvirt/dnsmasq-custom'/>
</dnsmasq:options>

Method 3: Full Custom dnsmasq Configuration

For complete control, you can disable libvirt's built-in dnsmasq and run your own instance:

# Edit your network XML to disable dnsmasq
virsh net-edit default

Add or modify:

<domain name='example.com' localOnly='yes'/>
<dhcp>
  <range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>

Then create a custom dnsmasq configuration file at /etc/dnsmasq.d/libvirt-custom.conf:

interface=virbr0
bind-interfaces
dhcp-range=192.168.122.2,192.168.122.254
dhcp-userclass=set:ipxe,iPXE
dhcp-boot=tag:ipxe,http://matchbox.foo:8080/boot.ipxe
  • Always test changes in a development environment first
  • Be aware of libvirt version differences in dnsmasq integration
  • Consider using network filters for more complex scenarios
  • Document your customizations for future maintenance