[libvirt] Different mac address used in libvirtd

Hi, I found libvirtd will create vnet0 with a different mac other than the one defined in domain file. The mac in Domain file will be used by qemu-kvm. I want to know how libvirtd decides the mac for vnet0, Who can give me a hint about the location of the libvirtd codes which does this work? I cannot find how the libvirtd translates the mac from one defined in domain file to vnet0's one in src/util/bridge.c: brSetInterfaceMac() Thanks Yong Sheng Gong [root@robinlinux eclipsecdt]# virsh dumpxml 2 <domain type='kvm' id='2'> <name>instance-00000002</name> <uuid>03e9993b-eafa-4021-b929-4a51ce9635d5</uuid> <memory>524288</memory> <currentMemory>524288</currentMemory> <vcpu>1</vcpu> <os> <type arch='x86_64' machine='pc-0.14'>hvm</type> <kernel>/var/lib/nova/instances/instance-00000002/kernel</kernel> <initrd>/var/lib/nova/instances/instance-00000002/ramdisk</initrd> <cmdline>root=/dev/vda console=ttyS0</cmdline> <boot dev='hd'/> </os> <features> <acpi/> </features> <clock offset='utc'> <timer name='pit' tickpolicy='delay'/> <timer name='rtc' tickpolicy='catchup'/> </clock> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/nova/instances/instance-00000002/disk'/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> <interface type='bridge'> <mac address='fa:16:3e:28:64:c2'/> <source bridge='br100'/> <target dev='vnet0'/> <filterref filter='nova-instance-instance-00000002-fa163e2864c2'> <parameter name='DHCPSERVER' value='10.0.1.1'/> <parameter name='PROJNET' value='10.0.1.0'/> <parameter name='PROJMASK' value='255.255.255.0'/> <parameter name='IP' value='10.0.1.2'/> </filterref> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <serial type='file'> <source path='/var/lib/nova/instances/instance-00000002/console.log'/> <target port='0'/> <alias name='serial0'/> </serial> <serial type='pty'> <source path='/dev/pts/1'/> <target port='1'/> <alias name='serial1'/> </serial> <console type='file'> <source path='/var/lib/nova/instances/instance-00000002/console.log'/> <target type='serial' port='0'/> <alias name='serial0'/> </console> <input type='tablet' bus='usb'> <alias name='input0'/> </input> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1' keymap='en-us'> <listen type='address' address='127.0.0.1'/> </graphics> <video> <model type='cirrus' vram='9216' heads='1'/> <alias name='video0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <memballoon model='virtio'> <alias name='balloon0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </memballoon> </devices> </domain> [root@robinlinux eclipsecdt]# ifconfig vnet0 vnet0 Link encap:Ethernet HWaddr FE:16:3E:28:64:C2 inet6 addr: fe80::fc16:3eff:fe28:64c2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:553 errors:0 dropped:0 overruns:0 frame:0 TX packets:1485 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:136360 (133.1 KiB) TX bytes:280590 (274.0 KiB)

On Wed, Jun 20, 2012 at 07:01:17PM +0800, Yong Sheng Gong wrote:
Hi, I found libvirtd will create vnet0 with a different mac other than the one defined in domain file. The mac in Domain file will be used by qemu-kvm. I want to know how libvirtd decides the mac for vnet0, Who can give me a hint about the location of the libvirtd codes which does this work?
I cannot find how the libvirtd translates the mac from one defined in domain file to vnet0's one in src/util/bridge.c: brSetInterfaceMac()
<interface type='bridge'> <mac address='fa:16:3e:28:64:c2'/> <source bridge='br100'/> <target dev='vnet0'/> <filterref filter='nova-instance-instance-00000002-fa163e2864c2'> <parameter name='DHCPSERVER' value='10.0.1.1'/> <parameter name='PROJNET' value='10.0.1.0'/> <parameter name='PROJMASK' value='255.255.255.0'/> <parameter name='IP' value='10.0.1.2'/> </filterref> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface>
The XML mac address config, sets the MAC address for the *guest* NIC, ie what the guest uses as its eth0.
[root@robinlinux eclipsecdt]# ifconfig vnet0 vnet0 Link encap:Ethernet HWaddr FE:16:3E:28:64:C2 inet6 addr: fe80::fc16:3eff:fe28:64c2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:553 errors:0 dropped:0 overruns:0 frame:0 TX packets:1485 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:136360 (133.1 KiB) TX bytes:280590 (274.0 KiB)
vnet0 is the backend of the guest NIC, and its MAC addr is more or less irrelevant to functioning of the guest itself, since traffic does not originate on this NIC. The only important thing is that this TAP device must have a high value MAC address, to avoid the bridge device using the TAP device's MAC as its own. Hence when creating the TAP Device libvirt takes the guest MAC addr and simply sets the top byte to 0xFE Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

(slowly working through libvir-list backlog from when I was on vacation...) On 06/29/2012 11:53 AM, Daniel P. Berrange wrote:
On Wed, Jun 20, 2012 at 07:01:17PM +0800, Yong Sheng Gong wrote:
Hi, I found libvirtd will create vnet0 with a different mac other than the one defined in domain file. The mac in Domain file will be used by qemu-kvm. I want to know how libvirtd decides the mac for vnet0, Who can give me a hint about the location of the libvirtd codes which does this work?
I cannot find how the libvirtd translates the mac from one defined in domain file to vnet0's one in src/util/bridge.c: brSetInterfaceMac() <interface type='bridge'> <mac address='fa:16:3e:28:64:c2'/> <source bridge='br100'/> <target dev='vnet0'/> <filterref filter='nova-instance-instance-00000002-fa163e2864c2'> <parameter name='DHCPSERVER' value='10.0.1.1'/> <parameter name='PROJNET' value='10.0.1.0'/> <parameter name='PROJMASK' value='255.255.255.0'/> <parameter name='IP' value='10.0.1.2'/> </filterref> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> The XML mac address config, sets the MAC address for the *guest* NIC, ie what the guest uses as its eth0.
[root@robinlinux eclipsecdt]# ifconfig vnet0 vnet0 Link encap:Ethernet HWaddr FE:16:3E:28:64:C2 inet6 addr: fe80::fc16:3eff:fe28:64c2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:553 errors:0 dropped:0 overruns:0 frame:0 TX packets:1485 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:136360 (133.1 KiB) TX bytes:280590 (274.0 KiB) vnet0 is the backend of the guest NIC, and its MAC addr is more or less irrelevant to functioning of the guest itself, since traffic does not originate on this NIC.
Actually there is one way that the MAC address of the tap device affects proper operation of guest networking - if you happen to set the tap device's MAC identical to the MAC used by the guest, you will get errors from the kernel similar to this: kernel: vnet9: received packet with own address as source address There was a bug filed about this (someone tried to set their guest's MAC address to start with 0xFE): https://bugzilla.redhat.com/show_bug.cgi?id=798467 and a corresponding check was added to libvirt to prevent it from happening.
The only important thing is that this TAP device must have a high value MAC address, to avoid the bridge device using the TAP device's MAC as its own. Hence when creating the TAP Device libvirt takes the guest MAC addr and simply sets the top byte to 0xFE
participants (3)
-
Daniel P. Berrange
-
Laine Stump
-
Yong Sheng Gong