Pages

Wednesday, 21 September 2016

IGMP Snooping让Chromecast在OpenWRT下正常工作

把旧的路由换成了美版 Linksys 1900ac v2 其实是对曾经 Linksys WRT54G 感情的延续,以今天带有调侃的语气来说,那是『情怀』,是对逝去的追忆和缅怀。 虽然 Linksys 又被思科卖给了 Belkin,但对 OpenWRT 友好是不争的事实,刷个机也不需像网件一样写入 bootloader。ASUS 不锁 bootloader,可我从不用梅林。既然用惯了 OpenWRT,那就继续。再则,Linksys 1x00ac (Marvell) 在 OpenWRT 社区,内容已经很全了。只需把 OpenWRT 写入 1900AC v2 的第二片 ROM 就行,也可以刷回原厂固件,永不变砖。
鉴于手上两个 Chromecast 一代根本无法识别 5G Wifi 信号,又搞来个 Chromecast 2 代,虽然知道对于 video straming 来说 802.11n 的 300Mb/s 已经足够了,但有 802.11ac 和 5G 频段总还是想尝试下。
按照老套路弄完,然后激活 Chromecast 2 进行设置,可每次投屏后一直 stuck,电视画面停留在 Youtube 血红的 Intro 页面,或者 Netflix 的黑底红字,迟迟不进入节目。换回旧的路由则一切正常。
又一次不得不着手排查问题。Google 了一圈,发现了问题的出处:从 2.6.34 内核开始, OpenWRT 默认关闭了 IGMP Snooping 。1
在 Google Cast Help Forum 上也有回答 2
  • Your router will not be able to ‘discover or see’ your Chromecast on your WiFi network if you have UPnP or Multicast disabled.
  • Chromecast will not be able to communicate with your router if you have IGMP (Internet Group Management Protocol) disabled on your router or IGMP Proxy enabled on your router.
上述回答在 Google Cast Help Forum 另一个主题中得到了印证 3
  • Enable: Universal Plug and Play (UPnP), multicast, Internet Group Management Protocol (IGMP)
Chromecast Help 中列出了一些初始设置有兼容问题的路由器 4,并给出了解决方法,其中包括了 Apple Airport,Linksys E4200,网件的 R6300 和 N7000。只不过,在中国境内的使用 Chromecast 可以直接忽略这个兼容列表。 
研究了下 IGMP Snooping 这个东西,OpenWRT 官网是这么说的:
When a host wants to start receiving UDP multicast traffic, it needs to subscribe itself to a "UDP multicast group". Control of multicast groups is archived with IGMP protocol. Once a host is subscribed, all the traffic for this group is sent to it using broadcast L2 frames. This detail is important because common bridges just pass all the broadcast traffic to all the ports. So if you use Linux to bridge wireless and wired networks (usual scenario for home LANs) and you subscribe to a multicast group from one of the wired clients, the wireless will be hogged too. Luckily, starting from 2.6.34, the kernel has IGMP snooping feature for the software bridges (disabled by default in OpenWrt) which should prevent unnecessary traffic on ports that were not actually subscribing.
Another important consideration is that multicasting over wireless doesn't usually work as one might expect since it uses the lowest possible bitrate (to enable all clients to "hear" it) and also employs special tricks for power-saving. Basically, this makes multicasting useless for IPTV.
Thanks to IGMP snooping, igmpproxy should no longer cause wifi hogging and so you can have both igmpproxy and udpxy configured and running, accessing IPTV over wifi with udpxy when needed.
查看了自己的内核,是 3.18.23 ,因此必须手动开启 IGMP Snooping
解决方法很简单,官方文档都有写:
$ sudo opkg update
$ sudo opkg install kmod-bridge
....
  Configuring kmod-llc.
  Configuring kmod-stp.
  Configuring kmod-bridge.
首先,安装 kmod-bridge

config interface 'lan'
        option ifname 'eth1'
        ...
        option igmp_snooping '1'
接下来,修改  /etc/config/network ,在 br-lan 中加入 IGMP Snooping 选项

$ sudo echo "1" > /sys/devices/virtual/net/br-lan/bridge/multicast_snooping
然后,修改 multicast_snooping 的默认值改为 "1"

# reboot
最后,重启 OpenWRT

Done ! 接下来就能继续愉快收看节目了。

Recap:

猜测这个修改不仅对 Chromecast,而且对 Apple TV AirPlay,Kindle Fire TV 应该都有效。如果上述设备在 OpenWRT 下遇到投屏时卡在欢迎页面一直无法播放的情况,可以尝试这个办法,本质上就是打开 UPnP 或 MultiCast 让 Chromecast / Apple TV / Kindle Fire Stick 能够在局域网内被发现识别,同时打开 UDP IGMP Snooping 让节目顺利播放。如果路由不使用 OpenWRT 而是使用原厂固件,请确定(1)视频内容不受 GeoIP 限制 (2)已经突破国家防火墙的网络封锁 (3)参考 Chromecast 的初始设置不兼容列表,并根据提示修改。

References: