Vmware和multicast

Vmware和multicast shixudong163.com在分析Win11主机和WSL2之间组播互通问题的过程中详见《WSL2和multicast》意外发现Vmware虚拟机桥接到Windows无线网卡后Windows主机也无法接收Vmware虚拟机发送的组播包反之则没有问题。这是由于Vmware处理桥接模式下的包发送过于简单粗暴直接将主机桥接网卡发送方向的数据包同步注入到该网卡的接收方向。在虚拟机桥接到主机无线网卡的情形下接收方向注入的数据包也使用二层nat转换后的主机无线网卡MAC作为源MAC。Vmware虚拟机发出的组播包到达主机后分为两路一路继续向外发送另一路注入到无线网卡接收方向Windows内核检测到以自身无线网卡MAC名义发出的组播包同时出现在发送和接收方向误以为产生了二层环路主动丢弃了接收方向的组播包导致Windows无法接收Vmware虚拟机发来的组播包。Windows主机发出的组播包同样分为两路实际上还有一路发往loopback注入到无线网卡接收方向的组播包也因同样的原因被Windows丢弃但并不影响Vmware虚拟机接收该组播包也不影响Windows主机通过loopback自发自收该组播包。Windows主机无法接收Vmware虚拟机发送的组播包与无法接收WSL2mirrored发送的组播包有着本质的区别前者是组播包已到主机无线网卡接收方向并能被主机抓包但后续被Windows内核丢包后者纯粹是路由问题不涉及桥接或无线网卡组播包无法发送到主机接收方向主机上也就根本谈不上抓包一说。显然无法使用后者改变组播包路由的思路来解决前者面临的问题。可通过引入Windows无线网桥来解决这一问题让Vmware虚拟机桥接到Windows无线网桥对于Vmware来说无线桥接变成了有线桥接由无线网桥负责二层nat转换。Vmware虚拟机发出的组播包被注入到无线网桥接收方向时其源MAC仍是虚拟机网卡MAC而非主机无线网卡MAC因而能被Windows主机顺利接收。当Vmware虚拟机为Linux时有一种更巧秒的办法可以解决前述问题从而无需借助Windows无线网桥。在外部网络或Windows主机上跑一个IGMP查询器同时在Linux虚拟机上执行如下四条命令后就一切OKWindows主机也能顺利接收Vmware虚拟机发来的组播包。sudo ebtables -t nat -A PREROUTING -p ipv4 --ip-proto igmp --ip-dst 224.0.0.1 -j DROPsudo ebtables -A OUTPUT -p ipv4 --ip-proto igmp --ip-dst 224.0.0.1 -j DROPsudo bash -c echo 1 /sys/class/net/br0/bridge/multicast_queriersudo bash -c echo 1 /sys/class/net/ens192/brport/multicast_to_unicast该解决思路来自于本人疫情期间关于组播学习的一些心得第一条命令不让外部网络或主机发来的查询报文被Linux网桥IGMP snooping处理阻止虚拟机外出网卡成为router port。此处需注意不能使用filter/INPUT来DROP因为其执行时点要晚于网桥IGMP snooping。第二条命令可防止虚拟机网桥自带IGMP查询器影响外部网络上的IGMP查询器。后两条命令用于启用Linux虚拟机网桥br0外出网卡ens192的mcast_to_unicast功能同样适用于有线网络只要该端口不是router port虚拟机网桥驱动将发给主机的组播包目标MAC转换成单播MAC主机无线网卡MAC就不会被Windows内核误以为二层组播环路而丢包并顺利接收。该思路的关键是外部网络上要有IGMP查询器或在Windows主机跑一个IGMP查询器在外发IGMP查询报文时也会发给自己一份。主机接收到查询报文后持续向外发送IGMP reportVmware桥接负责同步注入到Linux虚拟机确保虚拟机网桥维护的主机网卡MAC长期有效持续为mcast_to_unicast提供单播MAC。此处主机为何不能直接利用虚拟机上的IGMP查询器原因仍在于虚拟机桥接无线网卡时发出的IGMP查询报文不能被Windows主机接收因此VMware桥接也就无法主动向Linux虚拟机注入IGMP report。而外部网络或主机上的IGMP查询器可触发VMware桥接顺便向Linux虚拟机定期注入IGMP report。《WSL2和multicast》提到WSL2桥接主机无线网卡如果无线AP启用IGMP snooping功能或者外部网络上有IGMP查询器由于Windows无线网桥不支持mcast_to_unicast逆转换因此和无线AP的mcast_to_unicast功能发生冲突导致WSL2bridged无法接收外来组播包。Vmware虚拟机Linux桥接主机无线网卡也不支持mcast_to_unicast逆转换WSL2可以采用mirrored方式解决Vmware虚拟机的类似问题又该如何解决呢先透露一下答案同时使用Windows无线网桥和Linux的bridge/ebtables命令。既然Windows无线网桥不支持mcast_to_unicast逆转换那Vmware虚拟机引入Windows无线网桥的意义又何在呢虚拟机桥接无线网卡无论是Vmware或者Windows网桥都需要提供二层nat转换功能虚拟机数据包外出时负责将数据包源MAC转换为主机无线网卡MAC同时维护虚拟机源IP和主机无线网卡MAC之间多对一的映射关系。外来数据包到达主机无线网卡时如数据包目标MAC为广播/组播就直接传给虚拟机。如数据包目标MAC为主机无线网卡MAC则根据目标IP去匹配前述映射关系如匹配成功就将目标MAC转换为虚拟机MAC然后传给虚拟机。当外来单播数据包目标IP为未知IP时必然无法匹配映射关系目标MAC为主机无线网卡MAC的unicast组播包显然也符合这一情形。对于这些匹配失败的外来数据包Vmware和Windows网桥各自的二层nat转换处理机制并不相同。VMware虚拟机桥接主机无线网卡时Vmware的二层nat转换提供了额外的安全防护不会将前述匹配失败的外来数据包传给虚拟机。而改为桥接Windows无线网桥后由无线网桥负责二层nat转换但其功能相对简单会把前述匹配失败的外来数据包原封不动传给Vmware。对于Vmware来说无线桥接变成了有线桥接不再需要二层nat转换因此也是照单全收后如数传给虚拟机完全由虚拟机去DROP不需要的数据包。虚拟机桥接无线网桥后来自无线AP的unicast组播包能够到达虚拟机但因目标MAC为主机无线网卡MAC和虚拟机MAC不一致包类型被标记为PACKET_OTHERHOST后续被虚拟机三层DROP导致虚拟机仍然无法接收外来组播包。这时就轮到bridge/etables出场了在虚拟机上执行如下两条命令后也一切OK不再受无线AP启用mcast_to_unicast影响虚拟机能顺利接收外来组播包。sudo ebtables -t nat -A PREROUTING -p ipv4 --ip-proto igmp --ip-dst 224.0.0.1 -j redirectsudo ebtables -t nat -A PREROUTING -p ipv4 --ip-proto udp --ip-dst 224.0.0.0/4 -j redirect这两条命令就是将外来的unicast组播包目标MAC从主机网卡MAC修改为Linux网桥MAC同时修改包类型为PACKET_HOST使之能被虚拟机三层进行常规处理详见《Linux二层包类型对网络功能的影响分析》之二“包类型对桥的影响”。第一条命令允许虚拟机接收外部IGMP查询器发来的IGMP查询报文后续虚拟机就能向外发送IGMP report外来组播数据包就不会受到IGMP snooping影响能够发往虚拟机。第二条命令允许虚拟机接收外来组播数据包并将其交给上层组播接收程序。在《WSL2和multicast》还提到当Vmware虚拟机桥接的主机无线网卡固件具有multicast filter特性时Vmware本身能使主机无线网卡multicast过滤功能失效解除了主机无线网卡拦截外部组播包的隐患。改为桥接Windows无线网桥后这一隐性福利消失了。但由于无线AP目前大都支持mcast_to_unicast外来组播包到达主机无线网卡时已变为unicast组播包不会被主机无线网卡拦截。外部网络上的IGMP查询器能使Vmware虚拟机定期发出IGMP report让mcast_to_unicast持续保持激活便可对冲掉主机无线网卡的multicast filter特性同样可以解除掉主机无线网卡拦截外部组播包的隐患。最后顺便补充一下对于Vmware虚拟机桥接无线网桥或无线网卡的情形外来数据包到达主机无线网卡时其目标MAC要么是广播/组播要么就是主机无线网卡MAC。而且由于ARP协议在默默起作用外来数据包目标IP要么也是广播/组播要么就是主机IP或虚拟机IP理论上不可能出现未知IP不包括unicast组播包这种特殊情况。要验证二层nat转换对未知IP的处理机制可以手工修改虚拟机IP并用iptables阻止外出的IGMP/UDP/TCP数据包然后在外部设备上将该IP静态映射到主机无线网卡MAC或者在主机上将该IP静态映射到虚拟机MAC。如虚拟机不发送Gratuitous ARPLinux默认不发送除非虚拟机先ping外部设备或主机否则外部设备或主机永远无法ping通虚拟机修改后的IP。如虚拟机桥接无线网桥虚拟机上能抓到目标MAC为主机无线网卡MAC的外来ping包在组播接收程序初始发出的IGMP report超时前还能抓到目标MAC为主机无线网卡MAC的外来unicast组播包。如虚拟机直接桥接无线网卡由于Vmware二层nat转换额外提供的安全防护机制虚拟机上根本抓不到上述包。这一区别也正是Vmware虚拟机需要引入Windows无线网桥的意义所在。然而本文解决方案却无法适用于WSL2bridged和桥接无线网卡的Hyper-v虚拟机尽管这两者本来就必须使用Windows无线网桥。这是由于VMware采用的是Hub技术而WSL2桥接所依赖的Hyper-v使用了Switch技术。目标MAC为主机无线网卡MAC的外来unicast组播包直接被Hyper-v交换机转发到了主机vEthernet网卡根本到不了WSL2bridged和Hyper-v虚拟机自然也就无法像Vmware那样在虚拟机内部做进一步处理了。