当前位置: 首页 > news >正文

WSL2和multicast

shixudong@163.com

在《WSL2和VPN》一文后话中,简单提了一下WSL2(mirrored)在支持multicast方面的不足,当时并没有开展进一步的深入研究。近日在github上看到多篇issues(10735、12344)在讨论WSL2的组播问题,特别是WSL2(mirrored)和Windows主机之间无法进行组播通信,遂静下心来做了一番功课,得以形成此文。

一、WSL2的组播支持

WSL2新增mirrored模式,号称支持multicast,但无论是mirrored、bridged还是nat,三者其实都使用同一个Linux内核,对组播的支持在内核层面是无差别的。只是由于网络层面的不同,导致了三种模式对组播的支持程度有所差异而已。

在外部设备看来,nat模式下,组播包无法被转发出去,可认为WSL2(nat)不支持multicast;Mirrored和Bridged模式对组播的支持程度基本上是一样的,只是WSL2一直想要废弃bridged模式,所以才有mirrored模式号称支持组播一说。

WSL2向外部设备发送组播数据包没有问题,但WSL2官方内核不支持CONFIG_IP_MULTICAST,因此WSL2在接收组播包时无法发送组播加入信息。当网络上启用了IGMP snooping后,因为没有收到WSL2的组播加入信息,交换机压根不会将WSL2希望接收的组播包发送到Windows主机,导致WSL2无法接收外部设备发来的组播包。

对于这一情形,有两种解决方法可以让WSL2能够正常接收外部设备发来的组播包。

1、由Windows主机代为发送WSL2需要的组播加入信息。

2、使用CONFIG_IP_MULTICAST=y重新编译WSL2内核,支持WSL2发送组播加入信息。

二、WSL2(bridged)的组播优势和不足

WSL2(bridged)使用与主机不同的IP和MAC,WSL2和Windows主机之间的组播通信,与WSL2和外部设备之间的组播通信没有区别,因此WSL2可以顺利向Windows主机发送组播数据包。而且由于WSL2和Windows主机之间没有外部网络,故即使WSL2使用不支持CONFIG_IP_MULTICAST官方内核,也能顺利接收Windows主机发来的组播包。

针对WSL2桥接到主机有线网卡的情形,考虑到大多数网络已默认启用IGMP snooping功能,如前所述,WSL2(bridged)必须使用CONFIG_IP_MULTICAST=y的定制内核,才能顺利接收外部设备发来的组播包。

针对WSL2桥接到主机无线网卡的情形,即使外部网络没有启用IGMP snooping功能,依然有两种例外情况会导致WSL2无法接收外部设备发来的组播包:

1、如WSL2使用CONFIG_IP_MULTICAST=y的定制内核,WSL2在接收组播包时能够发送组播加入信息,但有些无线AP在识别到该组播加入信息后,将自动启用multicast_to_unicast功能,发往Windows主机的组播包被转换为以主机无线网卡MAC为目标的单播包,由于Windows网桥驱动功能太烂,不能依据三层组播IP对multicast_to_unicast进行逆转换,将单播目标MAC恢复成组播目标MAC,导致WSL2因使用与主机不同的MAC,反而无法接收组播包(Vmware桥接主机无线网卡时也有同样的问题,VirtualBox桥接可根据三层组播IP对multicast_to_unicast进行逆转换,不存在类似缺陷)。

2、如WSL2桥接的主机无线网卡固件具有multicast filter特性,由于WSL2在接收组播包时无法向主机无线网卡添加多址过滤条件,主机无线网卡也会主动拦截外部发给WSL2的组播包。

针对例外情形1,优先使用官方内核,不让WSL2发出组播加入信息;或者通过防火墙拦截WSL2发出的组播加入信息。此时无线AP一般不会启用multicast_to_unicast功能,外部设备发来的组播包能顺利被WSL2接收。

针对例外情形2,理论上的解决思路是让Windows主机也加入到WSL2接收组播包所需要的同一个组播组,此时将由Windows主机向自身无线网卡添加多址过滤条件,放行WSL2需要的组播包。该思路看起来很美妙,然而却和例外情形1相冲突,因为只要Windows主机加入到同一个组播组,必然会发送组播加入信息,触发无线AP自动启用multicast_to_unicast功能,导致WSL2无法接收组播包。因此还需要同时通过防火墙拦截Windows主机或WSL2发出的组播加入信息,方能保证WSL2顺利接收外部设备发来的组播包。

如外部网络启用了IGMP snooping功能,情形稍为复杂,这是因为大部分无线AP在检测到网络上启用IGMP snooping功能后,也能自动启用multicast_to_unicast功能。根据前面分析,此时WSL2将进入无解状态,无论内核是否启用CONFIG_IP_MULTICAST,都无法接收外部设备发来的组播包。该情形下可以改用WSL2(mirrored)解决。

三、WSL2(mirrored)的组播优势和不足

对于WSL2(mirrored)来说,在和主机无线网卡配合使用时,由于使用了和主机无线网卡相同的MAC,依然可以顺利接收外部设备通过无线AP发来的multicast_to_unicast组播包,不存在类似WSL2(bridged)的瑕疵。也就是说,WSL2无需考虑Win11主机使用有线网卡还是无线网卡,只要使用CONFIG_IP_MULTICAST=y的定制内核,就能顺利接收外部设备发来的组播包。

在不考虑WSL2和Windows主机之间相互组播通信时,显然WSL2(mirrored)对组播的支持更胜一筹。然而正是由于WSL2镜像机制的特殊性,导致无论内核是否启用CONFIG_IP_MULTICAST,WSL2(mirrored)和Windows主机之间均无法进行组播通信。下面分析具体原因并给出解决方案。

四、解决WSL2(mirrored)的组播不足

在《也谈tcpdump抓包》之五“tcpdump和lo”提到,Linux在进行本机组播通信时,根据默认路由选择对应的网卡,并直接在三层调用dev_loopback_xmit发送组播包,在该函数中又直接调用netif_rx接收组播包,因此本机组播通信全程不使用lo网卡。对于Windows来说,根据抓包结果判断,本机组播通信和单播通信一样,全程必须使用loopback设备。除了这个区别外,两者相同点是如果要发送的组播IP未在本机任何网卡完成组播注册工作,则不向本机发送组播包。

WSL2(mirrored)镜像了主机所有网卡(包括IP和MAC),针对主机loopback设备,还准备了半镜像网卡loopback0。对于WSL2来说,loopback0可不是什么逻辑网卡,而是实实在在的物理网卡(可用ethtool -i loopback0验证)。Windows实时监控WSL2内部系统调用,如监控到WSL2内部应用通过系统调用打开了相应端口,Windows就将外部设备发往该端口的数据包镜像到WSL2对应网卡的接收方向。Windows自发自收单播通信发生在主机loopback设备上,当WSL2内部有相应侦听端口时,主机发往loopback设备的数据包也会根据主机不同的发送网卡镜像到WSL2内部对应网卡的接收方向,当数据包源IP为主机127.0.0.1时,则镜像到loopback0网卡。

当我们希望从Windows主机向WSL2(mirrored)发送组播包时,如果主机没有同时加入该组播组,如前所述,主机并不会向loopback设备发送组播包,只会向主机网卡发送组播包,而主机发送方向的组播包显然不可能镜像到WSL2对应网卡的接收方向,因而WSL2接收不到组播包。针对该情形,解决办法是让Windows主机也加入到WSL2接收组播包所需要的同一个组播组,实现该组播IP在主机发送网卡的注册。此后Windows主机发送组播包时,也会向loopback设备发送一份,并根据主机组播发送网卡将组播包镜像到WSL2对应网卡的接收方向,使得WSL2能够顺利接收Windows主机发出的组播包。

在《也谈tcpdump抓包》一文还提到,Linux无法抓取自发自收组播包,而Windows则可在loopback设备上抓取自发自收组播包。而且如同Linux一样,Windows在loopback设备抓包时,也过滤了一半的数据包,仅在接收环节显示抓包结果,抓包程序的这一设计思路,本意是为了消除loopback设备上不必要的显示冗余。然而,当Windows主机将发往loopback设备的数据包镜像到WSL2内部网卡时,由于主机在发送链路上缺失接收环节,导致在loopback设备抓包时,根本抓不到从主机发到WSL2的包,只能抓到从WSL2回到主机的包(可用TCP单播通信验证)。

因此,在前述情形下,如Windows主机加入组播组后在另外一个端口侦听,那么Windows主机发给WSL2的组播包,虽然必须通过loopback设备,但由于组播是单向通信,并且主机没有接收环节,导致出现主机loopback设备上抓不到组播包、而WSL2对应网卡上却能抓到组播包的现象。如果不是对loopback设备抓包机制和数据包方向有清醒的认识(详见《也谈tcpdump抓包》之六“tcpdump和数据包方向”,Windows下虽无法抓取数据包方向,但数据包方向原理雷同),就会被搞得一头雾水,彷佛主机压根没往loopback设备发送过组播包。当Windows主机加入组播组并且侦听和WSL2一样的端口时(两者都需要启用SO_REUSEADDR,并且绑定组播地址而非INADDR_ANY),主机在loopback设备的发送链路上具备了接收环节,就能在loopback设备上正常抓取组播包了。

采用上述方案解决WSL2(mirrored)接收Windows主机发来的组播包,显然该过程在WSL2内部是可抓包的,在WSL2看来,这就是外来组播包,而非自发自收组播包。

在分析WSL2(mirrored)无法向Windows主机发送组播包的原因时,有必要复习一下WSL2(mirrored)的镜像原理:Windows实时监控WSL2内部系统调用,如监控到WSL2内部应用通过系统调用打开了相应端口,Windows就将外部设备发往该端口的数据包镜像到WSL2对应网卡的接收方向;Windows监控到WSL2向外发送数据包时,就将数据包镜像到Windows主机对应网卡的发送方向。至于WSL2的物理网卡loopback0,被称之为半镜像网卡,是因为主机发往loopback设备的数据包,也会根据主机的不同发送网卡镜像到WSL2对应网卡的接收方向,当数据包源IP为主机127.0.0.1时,则镜像到WSL2的loopback0网卡,然而反之却不成立。当WSL2向外发送数据包时,如果不加以特殊处理,不可能被Windows镜像到主机loopback设备的接收方向。

当我们希望从WSL2(mirrored)向Windows主机发送组播包时,WSL2根据默认路由选择对应的网卡发出组播包,Windows将其镜像到主机对应网卡的发送方向,显然该组播包不可能进入到Windows主机的接收环节。根据这一事实,要想WSL2向Windows主机发送组播包,只有在路由选择上动手脚,设法让Windows将WSL2发出的组播包镜像到主机loopback设备的接收方向,从而被Windows主机接收。前文所谓的特殊处理,就是用来干这事的,其实质就是WSL2(mirrored)专用的hostAddressLoopback处理机制,该机制通过策略路由实现了WSL2内部网卡(包括loopback0网卡)到主机loopback设备的反向镜像。因此,完全可以通过设置hostAddressLoopback=true,并借用其处理机制改变WSL2内部组播包的走向,将其镜像到主机loopback设备的接收方向。

对于没有采用connect方式(《TPROXY与Wireguard》文末小插曲也有提到),或者没有调用bind绑定源IP的组播发送程序,执行sudo ip route add 组播IP via 169.254.73.152 dev eth0 onlink后(此处eth0表示默认路由所在网卡),Windows主机就能顺利接收WSL2(mirrored)发出的组播包。但该方法有两个不足:一是改变了组播的走向,导致组播包发不到外部设备;二是由于Linux的路由查找机制,如果组播发送程序采用connect方式或者调用bind绑定了源IP,就无法改变组播包的走向。

另一种解决方法更为完美,完全可以克服以上两个不足,那就是同时借用hostAddressLoopback机制和《iptables TEE使用技巧》一文提到的iptables TEE。遗憾的是,WSL2官方内核CONFIG_NETFILTER_XT_TARGET_TEE is not set,也需要使用CONFIG_NETFILTER_XT_TARGET_TEE=y重新编译内核,然后执行如下三条命令即可(后两条执行顺序不能颠倒)。

sudo iptables -A OUTPUT -p udp -d 组播IP -j TEE --gateway WSL2的网卡IP(该IP表示默认路由所在网卡对应的IP)

sudo ip rule add from all ipproto icmp lookup local

sudo ip rule add from all lookup 128

第一条命令通过TEE克隆组播包,并且只改变克隆组播包的走向,因此不影响原始组播包继续发往外部设备。TEE采取了类似unconnect方式的路由寻址机制,故不受组播发送程序使用connect方式或者调用bind绑定源IP的限制。

由于TEE在路由寻址时,寻址条件相对简陋,没有protocol字段,而WSL(mirrored)的hostAddressLoopback机制仅适用于tcp/udp,所以还需要第三条命令去除hostAddressLoopback机制对protocol的限制。

第二条命令用于保护从WSL2内部ping自身网卡IP不受影响。

采用上述两种方法后(建议后一种),Windows主机能够顺利接收WSL2(mirrored)发出的组播包。而且在主机看来,由于组播包是从loopback设备接收的,这就是自发自收组播包,而非外来组播包。

很显然,如同WSL2(bridged)一样,WSL2(mirrored)和Windows主机之间的组播通信无需经过外部switch/bridge,不涉及IGMP snooping,所以WSL2内核也无需启用CONFIG_IP_MULTICAST=y。

五、Linux组播路由选择

Linux发送组播包时,组播发送程序应使用IP_MULTICAST_IF选项指定组播发送网卡,否则将由Linux路由选择相应的组播发送网卡。在IP_MULTICAST_IF指定INADDR_ANY作为组播发送网卡或者组播发送程序干脆没有使用IP_MULTICAST_IF选项时,内核将选择默认路由对应的网卡发送组播包,如需要通过其他网卡发送组播包,则需要添加静态路由指定组播出口网卡(无需指定gateway)。一旦确定了发送网卡,就在该网卡上进行组播发送。

通过路由选择组播发送网卡时,如静态路由指定了gateway,如果组播发送程序没有使用connect方式,或者没有调用bind绑定源IP,或者静态路由关联的出口网卡和IP_MULTICAST_IF选项指定的组播发送网卡一致时,组播包将通过单播方式发送到gateway,本文第四部分解决WSL2(mirrored)向Windows主机发送组播包的第一种方法就是使用了这一思路。

即使静态路由指定了gateway,由于Linux的路由查找机制,如果组播发送程序使用了connect方式,或者调用bind绑定了源IP,则组播包发送时将忽略该静态路由指定的gateway,但仍在该静态路由关联的出口网卡上进行组播发送。在该情形下,如继续希望能将组播包通过单播方式发送到指定的gateway,可使用本文第四部分第二种方法,利用iptables TEE类似unconnect方式的路由寻址机制,将组播包通过单播方式发送到TEE指定的gateway。

Linux接收组播包时,同单播接收侦听一样,既可以在组播地址上侦听,也可以在INADDR_ANY地址上侦听。同时组播接收程序还必须使用IP_ADD_MEMBERSHIP选项指定需注册的组播IP以及组播接收网卡,否则同样由Linux路由选择相应的组播接收网卡。在IP_ADD_MEMBERSHIP选项指定INADDR_ANY作为组播接收网卡时,内核将选择默认路由对应的网卡接收组播包。

当外来组播包达到本机时,IP层需要校验组播包到达网卡是否已注册该组播IP,如组播IP未在该网卡注册,IP层将丢弃该组播包(这也是即便交换机没有启用IGMP snooping,单播接收程序能接收广播包、却不能接收组播包的真实原因)。组播包通过IP层校验并到达本机UDP协议栈时,如组播接收程序已关闭IP_MULTICAST_ALL选项(默认开启),先前IP层已放行的从非指定组播接收网卡收到的组播包,仍会被UDP丢弃;此外,即使组播接收程序在INADDR_ANY地址上侦听,先前IP层已放行的非指定组播IP对应的组播包,也会被UDP丢弃。

Linux组播接收的上述特点,导致和单播接收的行为不完全一致,容易引起误解。由于内核只是在IP/UDP层针对组播IP进行了一些额外校验,最终仍然要调用单播接收所使用的UDP接收处理函数,因此组播接收程序在使用INADDR_ANY侦听时,一方面仍可以象单播接收那样接收所有网卡上到达的单播包,另一方面却并不能接收所有网卡上到达的组播包。如前所述,组播包必须在IP层被强行拦截一道,拦截掉那些组播IP未在到达网卡注册的组播包。到了UDP层,如组播接收程序没有改变IP_MULTICAST_ALL选项(默认开启),此时组播接收行为如同单播,IP层能放行的组播包都能被接收,包括从非指定组播接收网卡收到的组播包(组播IP须事先在到达网卡注册),以及已注册的其他组播IP对应的组播包。

六、多网卡Windows和WSL2(mirrored)

前面提到,Windows和Linux本机组播通信有一个共同点,即如果要发送的组播IP未在本机任何网卡完成组播注册工作,则不向本机发送组播包。换句话说,对于那些已在Windows相关网卡自动注册的组播IP(224.0.0.1/224.0.0.251/224.0.0.252/239.255.255.250),在单网卡环境下,Windows主机向这些组播IP发送组播包时,主机无需另行开启组播接收程序,也会向loopback设备发送组播包,并被WSL2(mirrored)上的组播接收程序顺利接收。

在多网卡Windows环境下(特别是包含了VPN网卡),对于那些已在Windows相关网卡自动注册的组播IP,Windows组播发送程序并不按照已有路由选择组播发送网卡,虽然这些组播包仍然会被发送到loopback设备,但往往被镜像到WSL2另一块网卡的接收方向。对于WSL2(mirrored)来说,如主机发来的这些组播IP(224.0.0.252/239.255.255.250)未在WSL2的另一块网卡自动注册,或者WSL2组播接收程序关闭了IP_MULTICAST_ALL选项,WSL2就无法接收这些来自主机loopback设备的组播包,除非在WSL2上添加静态路由指定了正确的组播接收网卡。

本文第四部分通过hostAddressLoopback处理机制+路由指定gateway双管齐下解决了WSL2(mirrored)向Windows主机发送组播包的问题。然而在多网卡Windows环境下,从WSL2(mirrored)向Windows主机发送那些已在Windows相关网卡自动注册的组播IP时,同样也会面临Windows组播接收程序并不按照已有路由选择组播接收网卡的问题。即使WSL2已通过指定gateway将组播包发到了主机loopback设备,但由于Windows组播接收网卡和WSL2组播发送网卡的不匹配,也会导致Windows主机无法接收这些组播包。此时,可在WSL2上调整静态路由所需的网卡或TEE所需的gateway,使得WSL2组播发送网卡和Windows组播接收网卡相匹配,以便Windows主机能够顺利接收这些WSL2已发送到主机loopback设备、并已在Windows相关网卡自动注册了组播IP的组播包。

本文第五部分阐述的Linux组播路由选择机制,同样也适用于那些已在Linux相关网卡自动注册的组播IP(224.0.0.1/224.0.0.251)。鉴于Linux组播路由选择相对Windows更为简洁明了,因此,针对上述多网卡环境下Windows和WSL2(mirrored)之间组播通信的特殊情形,解决方案一律绕开了Windows不可捉摸的组播路由选择机制,而是采用了在WSL2(mirrored)侧调整组播静态路由的方法加以实现。

多网卡Windows环境下非自动注册组播IP的路由选择,取决于组播路由224.0.0.0/4对应网卡的跃点数。常规情况下VPN网卡不会添加该路由,而Windows本身的物理网卡以及各种虚拟机平台生成的虚拟网卡将各自添加一条组播路由224.0.0.0/4指向对应网卡。鉴于虚拟机平台生成的虚拟网卡不能被WSL2正常镜像,无法和WSL2通信,因此最简单的做法就是降低Windows主机默认路由对应网卡的跃点数,确保Windows始终在主机默认路由对应的网卡上进行非自动注册组播IP的发送和接收。

七、Windows和Vmware

在分析Windows和WSL2之间组播互通问题的过程中,意外发现,Vmware虚拟机桥接到Windows无线网卡时,Windows主机也无法接收到Vmware虚拟机发送的组播包,反之则没有问题。这是由于Vmware采用了简单粗暴的桥接方式,将主机桥接网卡发送方向的数据包同时注入到该网卡的接收方向。在虚拟机桥接到主机无线网卡的情形下,接收方向被桥接注入的数据包也使用二层nat转换后的主机无线网卡MAC作为源MAC。Vmware虚拟机发出的组播包被桥接网卡分为两路,一路向外发送,另一路向主机发送,Windows内核检测到以自身无线网卡MAC名义发出的组播包同时出现在发送和接收方向,误以为产生了二层环路,主动丢弃了接收方向的组播包,导致Windows无法接收Vmware虚拟机发来的组播包。Windows主机发出的组播包同样被桥接网卡分为两路,接收方向的组播包也一样被Windows丢弃,但并不影响Vmware虚拟机接收该组播包。

显然,Windows主机无法接收Vmware虚拟机发送的组播包与WSL2(mirrored)和Windows主机之间无法组播通信有着本质的区别,前者是组播包已到主机无线网卡接收方向,并能被主机抓包,但后续被Windows内核丢包;后者纯粹是路由问题,组播包无法发送到接收方,接收方也压根抓不到包。因此,也就无法用后者改变组播包路由的思路解决前者面临的问题。

可通过引入Windows无线网桥来解决这一问题,让Vmware虚拟机桥接到Windows无线网桥,对于Vmware来说,无线桥接变成了有线桥接,由无线网桥履行二层nat转换功能。Vmware虚拟机发出的组播包被注入到无线网桥接收方向时,其源MAC仍是虚拟机网卡MAC而非主机无线网卡MAC,因而能被Windows主机顺利接收。

当Vmware虚拟机为Linux,并且网络上有IGMP查询器、switch启用了IGMP snooping,还有一种更巧秒的办法可以解决前述问题。在Linux虚拟机上执行如下命令后,Windows主机也能顺利接收Vmware虚拟机发送的组播包。

sudo bash -c "echo 1 > /sys/class/net/br0/bridge/multicast_querier"

sudo bash -c "echo 1 > /sys/class/net/eth0/brport/multicast_to_unicast"

sudo ebtables -A OUTPUT -p ipv4 --ip-proto igmp --ip-dst 224.0.0.1 -j DROP

该解决思路来自于本人疫情期间关于组播学习的一些心得,前两条命令用于启用Linux网桥(假设为br0)物理端口(假设为eth0)的multicast_to_unicast功能(同样可适用于有线网络),Linux虚拟机发送的组播包目标MAC被转换为单播MAC(主机无线网卡MAC),能被Windows主机接收。

第三条命令用于防止Vmware虚拟机(linux)网桥自带的IGMP查询器干涉网络上已存在的IGMP查询器。

前提条件是网络上有IGMP查询器、switch启用了IGMP snooping,Windows主机得以将组播IP加入信息定期向Linux虚拟机报告,确保虚拟机能长期保存主机发来的组播IP信息,持续为multicast_to_unicast功能提供有效的单播MAC。此处关键仍在于Windows主机无法接收虚拟机网桥IGMP查询器发出的组播查询包,因此也就无法主动向Linux虚拟机进行定期报告,而网络上的IGMP查询器,可使Windows主机顺便向Linux虚拟机进行定期报告。

本文第二部分提到WSL2桥接到主机无线网卡和无线AP的multicast_to_unicast功能之间的冲突,导致WSL2(bridged)无法接收外部设备发来的组播包。Vmware虚拟机(Linux)桥接主机无线网卡时也有同样的问题,WSL2可以采用mirrored方式解决,Vmware虚拟机(Linux)的类似问题又该如何解决呢?先透露一下答案,组合使用Windows无线网桥和Linux的ebtables命令。

为何一定需要Windows无线网桥呢?这和Vmware的二层nat转换机制有关,在《Virtualbox配置Linux guest桥和修改网卡MAC》一文中提到,在桥接无线网卡时,VirtualBox的二层nat转换机制依赖虚拟机网卡MAC,导致虚拟机里无法随意更改虚拟机网卡MAC。Vmware的二层nat转换不存在类似问题,但也有自己的特色:即只有看到了虚拟机外出数据包的源IP,才允许同样的IP作为目标IP从外部进入虚拟机。当外部设备发来的数据包目标IP为未知IP时,Vmware的二层nat转换压根就不将该数据包传给虚拟机,平时感觉不到这个特色是因为ARP在默默起作用(验证方法:手工修改虚拟机IP,主机通过静态ARP映射指向该IP,除非虚拟机先ping外部设备,否则主机永远无法ping通虚拟机)。

Vmware虚拟机桥接到Windows无线网桥后,无线桥接变成了有线桥接,由无线网桥而非Vmware履行二层nat转换功能。即使外部设备发来的数据包目标IP为Vmware未知的IP,也会被VMware如数传给虚拟机。一旦数据包到达了虚拟机,就可以使用etables对其上下其手,在Vmware虚拟机(Linux)上执行如下命令后,便不受无线AP的multicast_to_unicast功能影响,可以施施然接收外部设备发来的组播包了。

sudo ebtables -t nat -A PREROUTING -p ipv4 --ip-proto igmp --ip-dst 224.0.0.1 -j redirect

sudo ebtables -t nat -A PREROUTING -p ipv4 --ip-proto udp --ip-dst 224.0.0.0/4 -j redirect

在执行上述命令前,虽然外部设备发来的组播包也能到达虚拟机,但在经过无线AP的multicast_to_unicast转换后,组播包目标MAC被改为主机无线网卡MAC。到达虚拟机时,包类型被标记为PACKET_OTHERHOST
,后续被虚拟机三层DROP,导致虚拟机无法接收外部设备发来的组播包。

这两条命令的作用都是将满足条件的组播包目标MAC从主机无线网卡MAC修改为Linux网桥MAC,同时修改包类型为PACKET_HOST,使之能到达虚拟机三层,并能被三层进行常规处理(详见《Linux二层包类型对网络功能的影响分析》之二“包类型对桥的影响”)。第一条命令允许Linux接收IGMP查询器发来的组播查询包,并向外部IGMP查询器报告自己的组播加入信息,使得外部设备能向Vmware虚拟机(Linux)发送组播包。第二条命令允许Linux接收外部设备发来的组播数据包,并将其转交给上层组播接收程序。

这一解决方案无法适用于WSL2(bridged),这是由于WSL2桥接所依赖的Hyper-v使用了Switch技术,而VMware采用的是Hub技术,所以当组播包目标MAC被无线AP改成主机无线网卡MAC后,根本到不了WSL2(bridged)。

测试中发现,Vmware虚拟机桥接到主机无线网卡后,除了不支持multicast_to_unicast逆转换,居然能向Windows主机无线网卡添加多址过滤条件,解除了主机无线网卡拦截外部组播包的隐患。改为桥接Windows无线网桥后,这一隐性福利消失了。如遇到主机无线网卡固件具有multicast filter特性,还需要让Windows主机也加入到Vmware虚拟机接收组播包所需要的同一个组播组,由Windows主机向自身无线网卡添加多址过滤条件,放行Vmware虚拟机所需要的外来组播包。

http://www.cnnetsun.cn/news/3952514.html

相关文章:

  • Unity色彩管理新体验:HSV-Color-Picker-Unity预设功能实战教程
  • DevOps Interview Guide中的团队建设:打造高效协作的DevOps文化面试题解析
  • OpenMDAO优化算法全解析:从梯度法到进化算法的应用指南
  • 终极指南:Intervention Validation的IBAN与BIC验证规则实战应用
  • UI.Vision RPA完整指南:5步实现跨平台桌面自动化
  • 签完的合同到底履没履行?企业用电子跟踪别再靠人盯
  • HTML作业实战:从零基础到完整网页开发指南
  • MySQL 用 limit 为什么会影响性能?几种优化方案对比!
  • 探索gh_mirrors/ai/ai-directories:2024年最全面的AI工具目录清单
  • Samsung K4UHE3D4AB-MGCLT00:32Gb LPDDR4X 超低功耗内存技术规格与应用
  • 打造你的专属AI桌面伙伴:DyberPet开源框架深度解析
  • Storybook Design Token实战教程:构建美观的设计系统文档
  • ComfyUI_TensorRT支持哪些模型?完整兼容列表与性能测试
  • GeekIt 极客在线工具箱 V2.3.0 正式发布,增加一整套PDF工具箱
  • 【单片机毕业设计推荐】基于 STM32 单片机的智能大棚环境监测与自动控制系统设计 基于 STM32 单片机的农作物环境参数采集与智能调控装置设计(011706)
  • Flet多媒体处理架构深度解析:构建高性能音视频应用的技术实践
  • 构建高可用系统:Comedy框架的Actor故障恢复与监控
  • 5分钟上手mjga-scaffold:从环境配置到容器化部署的快速指南
  • 3个技巧让Windows风扇控制变得像呼吸一样自然
  • 从理论到实践:pySecurity带你掌握CVE-2012-1823漏洞分析与利用
  • docker-ddns完全指南:用Docker+Go+Bind9构建你的专属动态DNS服务
  • 从零到一:如何用SRE思维构建可靠的现代系统
  • 2026进口高低压成套设备溢价太严重,如何在保证性能的前提下控制采购成本?
  • 3DS破解终极指南:从零开始安装boot9strap自定义固件
  • 2026小程序制作平台哪家最实惠?关注这个几个维度才不吃亏!
  • 如何快速安装sublime-autoprefixer?5分钟上手教程
  • 100%采用率却43%需返工:Azul最新Java报告揭开AI编程的“质量悖论“
  • 快速上手postcss-scss:5分钟实现SCSS代码的PostCSS转换
  • 突破性FF16优化方案:解锁专业级超宽屏体验与性能调优
  • qgis2web常见问题解答:解决90%用户遇到的导出难题