19

I'm using qemu/kvm whith bridged networking. In the host machine there are several "vnetX" network interfaces without IP. I'm looking for a way to know which vnetX belong to a virtual machine.

I tried to match the MAC Address values on these interfaces with the MACs on the virtual machines (or the XML which defines them), but doesn't match.

There's brctl show which shows the vnet interfaces that belongs to a bridge, but this is not useful info.

Is there a way to know that relation? Thx!!

9 Answers 9

19

How about this (example for vnet13):

$ VNET=vnet13; for vm in $(virsh list | grep running | awk '{print $2}'); do virsh dumpxml $vm|grep -q "$VNET" && echo $vm; done

Here we use virsh dumpxml to show dynamic properties about the VM, which are not available in the static XML definition of the VM in /etc/libvirt/qemu/foo.xml. Which vnetX interface is attached to which VM is such a dynamic property. Same goes for the VM's MAC addresses.

2
  • 5
    I use this slight modification to list which vm has which interface: for vm in $(virsh list | grep running | awk '{print $2}'); do echo -n "$vm:"; virsh dumpxml $vm| grep -oP "vnet\d+" ; done
    – zje
    Oct 20, 2014 at 23:10
  • If you are investigating an oVirt 'node' you can use the same command but virsh should be run in 'read only' mode. Just add -r parameter to each virsh call.
    – karlacio
    Jan 11, 2016 at 21:56
6

Try virsh dumpxml $domain, you'll see something like:

  <interface type='network'>
  <mac address='52:54:00:9d:9d:10'/>
  <source network='default'/>
  <target dev='vnet1'/>
  <model type='e1000'/>
  <alias name='net1'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/>

the alias name is what is used in the qemu-kvm command line, so if you run ps -ef |grep qemu|grep net1 from my example, you will see the actual command syntax used for this interface.

6

Run virsh domiflist myVM. This command will list all the interfaces related to VM myVM.

 Interface   Type      Source      Model    MAC
---------------------------------------------------------------
 vnet0       bridge    mgtbridge   virtio   52:54:00:3c:f3:df
 vnet1       bridge    habridge    virtio   52:54:00:8a:b3:b6
 -           hostdev   -           -        52:54:00:b0:eb:b7
 -           hostdev   -           -        52:54:00:44:26:94
1
  • wow! I asked this nine years ago! I no longer work with KVM so I can not fact check it ... but I guess it is ok, here's your karma :D
    – theist
    Jul 30, 2021 at 11:50
3

Every one of the solutions given above assumes that the VMs are being managed by libvirt. It is quite possible to run QEMU VMs without that, in which case you cannot use virsh or look at XML to find the answer.

In the case of running QEMU VMs from a "raw" command line:

  1. tcpdump -i tap0 -f 'icmp' (substitute whichever tap interface you're interested in)

  2. Ping each candidate VM until you see packets in the trace. The interface you are tracing when ICMP packets appear is the one you're looking for!

Conversely you can start a ping to a particular VM and then tcpdump each tap interface in turn until one "lights up". Depends whether you're interested in finding the VM that matches the tap interface, or the tap interface that matches the VM.

2

Based on @daff response:

for vm in $(virsh list | grep running | awk '{print $2}'); do echo "$vm: " && virsh dumpxml $vm | grep  "vnet" | sed "s/[^']*'\\([^']*\\)'[^']*/\\t\\1/g"; done

Output Example:

vm1:
    vnet0
vm2:
    vnet1
vm3:
    vnet2
vm4:
    vnet3
    vnet4
vm5:
    vnet5
4
  • There were a few issues for me with the sed command, but once I'd fixed those it worked exactly as I needed. I'm not sure if the issue is with my shell, but escaping a single quote within outer single quotes by using two of them didn't work. I replaced the outer single quotes after the sed with double quotes and removed the escaping from the single quotes within the command, and that worked. Apr 14, 2023 at 10:35
  • There is no double quote in the sed command... but just replacing them is OK. This sound weird, but is true: Double single quote inside a single quote string is a single quote char. For example, echo 'A''B' will echo A'B.
    – 0x3333
    Apr 15, 2023 at 12:26
  • It may do that on the shell / system you have, but on Debian 11 with Bash 5.1.4, echo 'A''B' just gives AB. But echo "A'B" does what is needed. Apr 17, 2023 at 13:24
  • You are right! I updated the answer with a sed using double quote.
    – 0x3333
    Apr 18, 2023 at 14:10
1

Match IP Addresses from Arp cache to VM

# vm mac address list
for vm in $(virsh list | grep running | awk '{print $2}'); do \
  echo -n "$vm "; \
  virsh dumpxml $vm| grep -oP "52:54:[\da-f:]+" ; 
done > vm_mac.list

# vm ip list
arp -i virbr0 | grep '52:' | while read addr ; do \
  ip=$(echo $addr | awk '{print $1}'); \
  mac=$(echo $addr | awk '{print $3}'); \
  vm=$(grep "$mac" vm_mac.list | awk '{print $1}'); \
  echo "$vm $ip $mac"; \
done | sort

Sample output:

vm66 192.168.191.112 52:54:00:ab:e8:cb
vm67 192.168.191.207 52:54:00:88:66:e7
vm67 192.168.191.241 52:54:00:88:66:e7
vm68 192.168.191.197 52:54:00:c5:e1:30
vm69 192.168.191.254 52:54:00:b6:f6:0f
vm70 192.168.191.232 52:54:00:08:7f:49
vm71 192.168.191.113 52:54:00:e7:6f:2b
1
  • Very useful for host-bridge network. I had to make a slight change: arp -i virbr0 -> arp -n -i br0
    – Ries
    May 19, 2020 at 19:54
1
for vm in $(virsh list  --state-running --name); do \
echo $vm; \
virsh domifaddr $vm; \
done

Example output:

client1

Nombre     dirección MAC       Protocol     Address
------------------------------------------------------------------------------

vnet2      52:54:00:2c:7a:f0    ipv4         192.168.122.63/24
1
  • I submitted a edit for your code quotes, but you should include an explanation along with your code. Mar 27, 2018 at 13:52
1

This will list all running VMs along with their interfaces:

for vm in $(virsh list --state-running --name); do echo "$vm: " && virsh domiflist $vm | sed -n "3,$ { s,^,\t,; p }"; done
1
  • This is an even better answer than 0x3333's one, and works as given with no edits! Apr 14, 2023 at 10:41
0

The MAC address of the vnetX interfaces belongs to the host, not the guest. brctl showmacs br0 will show the MACs detected by the bridge, but you'd then need to cross reference the port number with the list of interfaces from brctl show.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .