0

Upon a shutdown and reboot the vnet(xx) adapter assigned to the VM from the VM host changes.

Is there any way to keep it a specific vnet(xx), for example vnet20 after it's shutdown for whatever reason and then rebooted.

vidarlo
  • 6,654
  • 2
  • 18
  • 31

1 Answers1

0

This is documented there (emphasis mine):

Overriding the target element

...
<devices>
  <interface type='network'>
    <source network='default'/>
    <target dev='vnet1'/>
  </interface>
</devices>
...

If no target is specified, certain hypervisors will automatically generate a name for the created tun device. This name can be manually specified, however the name should not start with either 'vnet', 'vif', 'macvtap', or 'macvlan', which are prefixes reserved by libvirt and certain hypervisors. Manually specified targets using these prefixes may be ignored.

So it's possible but vnet20 couldn't be chosen to not clash. The manually defined interface will still only exist only while the VM is running.

This is probably good enough to apply network filtering rules using ebtables, iptables or nftables, and with probably much more efforts with other tools like route configuration or tc (they can only work with existing interfaces so have to be run whenever the VM is started).

To apply this on a VM named myvm, one can use virsh edit myvm (or from an authorized user on the hypervisor probably virsh -c qemu:///system edit myvm) to alter its settings. For example if the interface to change was defined with MAC address of 52:54:00:12:34:56 and to be used on a bridge named virbr0, find a block looking similar to below:

    <interface type='bridge'>
      <mac address='52:54:00:12:34:56'/>
      <source bridge='virbr0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>

and add an entry with the fixed target device name (let's use myvmtap0):

    <interface type='bridge'>
      <mac address='52:54:00:12:34:56'/>
      <source bridge='virbr0'/>
      <target dev='myvmtap0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>

The VM has to be stopped and started (not just restarted) for this to take effect.

This is scriptable with XML related tools, but XML looks more difficult than for example JSON. For example using xmlstarlet, the (one-long-line sequence of) commands below should do the same change as above, as long as it wasn't done before:

virsh -c qemu:///system dumpxml --inactive myvm | \
  xmlstarlet ed --subnode "domain/devices/interface[mac[@address='52:54:00:12:34:56']]" --type elem -n 'target' \
                --insert 'domain/devices/interface/target' --type attr -n dev -v 'myvmtap0' | \
  virsh -c qemu:///system define /dev/stdin --validate

Caveat: don't use blindly. Especially: it's not clearly documented if one can use a pipe (/dev/stdin above) instead of a file to redefine a domain (ie a VM)).

Again: the VM must then be completely stopped and then started (not simply restarted) for this to take effect.

Some credits go to:

A.B
  • 11,090
  • 2
  • 24
  • 45