NOVA中的虚拟机TAP设备的MAC为什么是FE开头?

Nova中的虚拟机如果大家观察其在物理机上tap设备的mac地址的时候,会发现这个mac地址和虚拟机的不一样,主要是第一个字节不一样:

#物理tap
19: tap1cb8937b-6b: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb master qbr1cb8937b-6b state UNKNOWN mode DEFAULT qlen 500
    link/ether fe:16:3e:3f:6b:d3 brd ff:ff:ff:ff:ff:ff
#虚拟机
[stack@udevstack01 neutron]$ neutron port-list | grep 1cb8937b-6b
| 1cb8937b-6bae-4e8c-bbdc-cdcdfb87731b | nic-1cb8937b | fa:16:3e:3f:6b:d3 | {"subnet_id": "4e43c6cf-a75f-461d-b8e7-d3bad007f251", "ip_address": "10.0.0.6"}   |

可以看到这里的mac地址在虚拟机中为fa:16:3e:3f:6b:d3,在物理机中为fe:16:3e:3f:6b:d3。为什么会这样呢?原因是因为linux中的bridge中的mac地址是会动态改变的,其mac地址等于其所有port中mac最小的那个port的mac地址。在libvirt的世界,当一个虚拟机生成后其mac地址是随机生成的,如果这个主机加到了bridge上并且其mac地址小于bridge中已有的所有port的mac地址,那么bridge的mac地址就会变成这个port的mac。在很多时候这种动态mac改变是会产生问题的:比如此时一个数据包可能依赖老的arp信息发给bridge,但是bridge就收不到了。

为了避免这种情况,libvirt的代码中会的把虚拟机随机生成的tap设备的mac地址的第一个字节改为fe,所以对于通常的情况:一个bridge下接了一个物理网卡和多个虚拟tap设备的情况,此时物理网卡的mac地址肯定是最小的(因为其余的虚拟tap都是fe),所以此时无论新plug到bridge上的port的mac地址是啥,其都不会小于物理网卡的地址,因此bridge的地址就不会变了:
virnetdevtap.c:

tapmac.addr[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*