北京联通猫棒 IPTV


故事背景:家里拉了很多年的千兆,这两年才从 FTTB 换成 FTTH。但是之前买的千兆套餐不送 IPTV 了,而光改的时候,联通的工作人员帮我改了桥接,但是所有口都绑定了 Internet。现在开通IPTV需要初装费,还要月费,所以我就没开通。本来是不想折腾的,因为实在没空,但是被催了好久猫棒的事情,所以就临时下了个单,花了一天做了些实验。

网络结构:北京联通。UBNT EdgeRouter-4 + 兮克交换机 + 猫棒(XE-99S,10G EPON)。本来试图迁移 ER-4 到 VyOS,改动的东西太多了,暂时放弃了,就选择加了个交换机,但是实际上是不需要管理交换机,只需要光转电,且 SFP+ 的模块在 ER-4 的 SFP 口是不能用的。

过渡步骤

  1. 先保证猫棒能替代光猫,即使用交换机单独把 3961 拆出来。参考配置截图的4号口。
  2. 使用trunk,把需要的vlan放进trunk里,将路由器 pppoe 改到 vif 3961 里。配置截图中的3号口。
  3. 处理 iptv。

1/2 不用介绍了。主要是步骤3。

我的光猫没有iptv 的配置(除了一个 3964的 vlan id),所以只能靠网上的信息。搜到的截图里,光猫有个组播vlan的配置,有些还有 igmp proxy的开关;ODI的猫棒里有现成的功能,但是很遗憾我用的这个猫棒没有。

询问卖家,加了个群,从群友 Timk 处获知,需要将组播的流量发给 vlan 4000(或者可能是 3996),他推荐的做法是 vlan mapping。这个信息很有用。联想到之前看到的截图,猜测unicast的请求是在 3964,multicast 的是在4000或3996,光猫这边使用igmp proxy,都将请求合在一起发在绑定的网口里。

最早实现的目标是,EdgeRouter上搞 udpxy,然后自己改个m3u8 给播放器看。所以为了验证这个,尝试分别对3964、3996、4000 在 udpxy 启动时和被触发请求时抓 igmp包,但是很遗憾都失败了。后来想了想,反正EdgeRouter空余一个口,直接一起 bridge 了,接上网线用mac测,确实可用。

有效配置如下:(eth1 是 WAN)

# 建bridge,不用分配IP,我测过分配IP了udpxy也不好使
set interfaces bridge br0

# 从 3964 vlan 里能拿到 dhcp 的包,获得IP
set interfaces ethernet eth1 vif 3964 bridge-group bridge br0

# 组播vlan,我的场景下是 3996,我图省事两个都加了
set interfaces ethernet eth1 vif 3996 bridge-group bridge br0
set interfaces ethernet eth1 vif 4000 bridge-group bridge br0

# 出口
set interfaces ethernet eth2 bridge-group bridge br0

遗留问题是,路由上跑 udpxy 的方案没成功,多出来的这个网口还得想法子找个双网口的主机给lan共享,我交换机的口不够用了。

先到这里吧。

multicast (组播) 转 unicast(单播)

先更新 udpxy 的问题。前边提到了我的几次实验,其实理论上我都成功了,但是没法验证自己是否真的成功。

先贴 udpxy 的日志。

2024-01-06 18:48:24.928266 CST c(23194) Mcast listener socket=[6] set up

2024-01-06 18:48:24.928773 CST c(23194) min socket buffer = [65536], max space to use = [1500], Rmsgs = [1]

2024-01-06 18:48:24.929774 CST c(23194) Data buffer will hold up to [1] messages

2024-01-06 18:48:24.930262 CST c(23194) RTP (over UDP) stream assumed, no checks

2024-01-06 18:48:24.930802 CST c(23194) socket 6: RCV timeout set to 0 sec, 0 usec

2024-01-06 18:48:24.931307 CST c(23194) socket 6: SEND timeout set to 0 sec, 0 usec

2024-01-06 18:48:24.931806 CST c(23194) current send buffer size is [44800] bytes for socket [9]

2024-01-06 18:48:24.932304 CST c(23194) current receive buffer size is [180224] bytes for socket [6]

2024-01-06 18:48:24.932809 CST c(23194) send buffer size set to [180224] bytes for socket [9]

2024-01-06 18:48:24.933596 CST c(23194) Sent HTTP response code=[200], reason=[OK] to socket=[9]

HTTP/1.1 200 OKM

Server: udpxy 1.0-25.1 (prod) standard [Linux 5.10.176 mips]M

Content-Type:application/octet-streamM

M

2024-01-06 18:48:24.934261 CST c(23194) Relaying traffic from socket[6] to socket[9], buffer size=[2048], Rmsgs=[1], pauses=[0]

2024-01-06 18:48:29.943893 CST c(23194) read_buf: socket time-out on read2024-01-06 18:48:29.944369 CST c(23194) read_data - EOF

2024-01-06 18:48:29.944857 CST c(23194) Exited relay loop: received=[-1], sent=[0], quit=[0]

2024-01-06 18:48:29.945620 CST c(23194) multicast-group [DROP]

2024-01-06 18:48:29.946151 CST c(23194) Mcast listener socket=[6] closed

2024-01-06 18:48:29.947111 CST c(23194) Child process=[23194] exits with rc=[0]

2024-01-06 18:48:29.948116 CST S(22960) *** Caught SIGCHLD (18) ***

2024-01-06 18:48:29.948632 CST S(22960) Waiting on exited children

2024-01-06 18:48:29.949140 CST S(22960) Client [23194] has exited.

2024-01-06 18:48:29.949629 CST S(22960) Deleted client: pid=[23194]

2024-01-06 18:48:29.950121 CST S(22960) Cleaned up 1 children, 0 still running

2024-01-06 18:48:29.950609 CST S(22960) INTERRUPTED, yet will continue.

2024-01-06 18:48:29.951086 CST S(22960) Waiting for input from [2] fd's, NO timeout

过程中,在 ER-4 上抓包,没有什么有效信息,其中可能有关的:

  1. udpxy 是 igmp v2 而 VLC 是 igmp v3
  2. 两个用的 igmp 的地址不一样,印象中前者是 .1,后者是 .22

最终的方案,在我尝试用一个 OpenWRT 的小路由装上 udpxy 接入 eth2 并同样失败后,切换到了 msd_lite,成功了。虽然我也不知道身边的大佬们怎么用 udpxy 做到的,难不成 3996 和 4000 的要求不一样?

目前我的进展,使用 msd_lite 已经成功能在 ER-4 上为 LAN 提供类似 udpxy 的服务。msd_lite 安装请参考 EdgeRouter 4 Install msd_lite.

配置修改只有 multicast / ifName 设置成了 br0。

启动我用的 post-config.d,没验证过,但是我其他脚本都是这么干的。

root@ubnt:~/msd_lite/build# chmod +x /config/scripts/post-config.d/99-start-msd_lite
root@ubnt:~/msd_lite/build# more  /config/scripts/post-config.d/99-start-msd_lite
#!/bin/bash

/usr/local/bin/msd_lite -d -c /etc/msd_lite.conf

验证之前,需要提一句,br0 我没有配地址,所以操作之前,需要先设置一下地址

set interfaces bridge br0 address dhcp

再执行脚本或者手工执行命令,启动服务。

VLC 打开 http://192.168.11.1:7088/rtp/239.3.1.245:2000 验证。

基本完结。不需要第二主机了。

增加一个地址生成器 https://iptv.rst.im/

另外,可能的 iproute2 实现,没试过,出问题别找我。

ip link add name br0 type bridge
ip link set dev br0 up

ip link add link eth1 name eth1.3964 type vlan id 3964
ip link set eth1.3964 up
ip link set eth1.3964 master br0

ip link add link eth1 name eth1.3996 type vlan id 3996
ip link set eth1.3996 up
ip link set eth1.3996 master br0

ip link add link eth1 name eth1.4000 type vlan id 4000
ip link set eth1.4000 up
ip link set eth1.4000 master br0

ip link set eth2 up
ip link set eth2 master br0

有空再画个带光口 SFP+ 的 PVE 主机的推荐拓扑。基本思路是再搞个vm,单独一个网口跟路由 vm 的 eth2 出口放在一个单独的 br 里,再udpxy 对lan提供服务。

参考信息

  1. iptv 源 https://gist.github.com/sdhzdmzzl/93cf74947770066743fff7c7f4fc5820
  2. 交换机配置图,其实除了有光口,管理功能是没有意义的。

Leave a Reply

Your email address will not be published. Required fields are marked *