家里的路由器有万兆光口,可以用猫棒直接代替运营商的光猫吗?

缘起

家里那台中国移动给配的 ZTE F663N 光猫,已经服役 6 年多了。

这玩意儿当年我就吐槽过——只有 LAN1 一个千兆口、限制 4 个终端、Wi-Fi 还停留在 2.4GHz 802.11n。当时实在受不了,就有了那篇 《解包和打包中兴光猫配置文件》,写了个工具把 cfg 解包改桥接,套自己的路由器和 AC Wi-Fi,总算把 100M 跑满了。

带宽从最早的 50Mbps 一路升到现在的 500Mbps,光猫这台硬件却没换过,一直在原地扛着。年头一长,老化的迹象就藏不住了:莫名其妙断流、PPPoE 重拨不上来、TR-069 后台时不时被推一份「看似为你好」的配置回来、最近半年甚至到了三五天就得手动重启一次的程度。修一台疲态尽显的运营商光猫,还要继续替它擦屁股,实在没意思。

正好赶上换路由器,挑了一台 BeeconMini SEED AC5——MT7987 SoC、2.5G 双 RJ45、自带 SFP 槽、带 PoE 输出。SFP 槽这个配置就很有意思:插一根 SFP 光猫棒,光纤直接进路由器,运营商那台砖头就可以扔抽屉里了。PoE 输出留着以后扩 AP 不用走砖头电源,这条也是加分项。

顺手再吐槽一句:现在所有运营商的 IPTV 都还在死磕「魔百盒 + 多播 VLAN」这套上古架构。智能电视、Apple TV、安卓盒子早就什么都能装,节目源完全可以做成一个 App,账号鉴权 + DRM 在云端搞定就行——非要塞一个独立硬件 + 多播 VLAN,本质是业务捆绑、硬件 KPI、加上多一道防盗看的物理壁垒。这套配下来网络拓扑直接复杂 N 倍,也是为什么大量用户最后还是认栽用回运营商光猫。这篇就把怎么绕开它记一下。




整体拓扑

SFP 光猫棒:选什么、怎么进

这次用的是 HSGQ DFP-34X-2C2,Realtek RTL960x 方案。选它有两个理由:

  1. 能刷 ODI 固件,telnet 进去用 flash get / flash set 直接读写 boot 参数,比改运营商光猫的固件友好十倍。
  2. 社区资料齐全,OMCI 字段克隆有现成参考。

猫棒的进入方式:

ItemValue
Default IP192.168.1.1(无 DHCP,本机配静态 192.168.1.2)
默认账号admin / admin
Web UI192.168.1.1
Telnettelnet 192.168.1.1

固件用 Anime4000/RTL960x 仓库里的 ODI 系列。我实际刷的是 M114_sfp_ODI_Vlan_220414.tar(2022-04-14 的 VLAN 构建)。

扒运营商参数(克隆原光猫)

要让 OLT 接受这根猫棒,得让它自报家门跟原光猫一模一样。每家运营商的注册逻辑不太一样:

  • 广东移动:PLOAM 密码 = LOID(ASCII 转 hex)
  • 上海移动:取原光猫的 LOID 当 PLOAM 密码(再加 SN 和 VLAN ID)

需要的字段(下面用 <placeholder> 表示需要替换为实际值):

  • GPON_SN(如 CMHIxxxxxxxx,从原光猫超管页或 OMCI 抓出)
  • GPON_PLOAM_PASSWD(hex 形式,下面会讲怎么算)
  • ELAN_MAC_ADDR(原光猫 LAN MAC)
  • OUI(取 MAC 前 3 字节)
  • OMCI 相关:HW_CWMP_MANUFACTURER, HW_CWMP_PRODUCTCLASS, HW_HWVER, OMCI_SW_VER1/2, GPON_ONU_MODEL, OMCI_VEIP_SLOT_ID, OMCI_OLT_MODE
⚠️ 以下命令里所有具体值都是示例占位。实际克隆时请用你自己原光猫的真实参数,不要照抄博客里的字符串——那既不会工作,也不该公开。

最关键的一步是 OMCI 字段——OLT 在 OMCI 协商阶段会校验厂商和型号,对不上就拒绝注册。OLT 看的不是光猫外壳上印的型号,而是它在协商里报上来的那一串字段,所以克隆要从 OMCI 视角抄,不能从用户视角抄。从原光猫的 ctromfile.cfg(解码后的 OMCI/管理配置 XML)能看到 OLT 实际看到的是什么字段,照抄就行。

我家原光猫是 ZTE F663N,但它 OMCI 上 ONU Vendor ID 报的是 MTKc(MediaTek 芯片),ONU ModelEPONONU Hardware VersionPT632V1.0——这些都不能写错。F663N 内部 cfg 怎么解出来的,可以参考我之前那篇 解包打包工具

MAC_KEY 重生成

HSGQ 固件 V1.0-220304+ 引入了 MAC_KEY,每次改 ELAN_MAC_ADDR 都要重新生成:

echo -n "hsgq1.9aMAC_ADDR_UPPERCASE" | md5sum
# 例: hsgq1.9aAABBCCDDEEFF → <对应的 32 位 md5>

烧入 profile

最后用一组 flash set 把克隆参数刷进去:

flash set PON_VENDOR_ID ZTEG
flash set HW_CWMP_MANUFACTURER ZTEG
flash set HW_CWMP_PRODUCTCLASS F663N
flash set HW_HWVER PT632V1.0
flash set OMCI_VEIP_SLOT_ID 255
flash set OMCI_OLT_MODE 3
flash set OMCI_FAKE_OK 1
flash set OMCI_SW_VER1 V1.1.0P1T9
flash set OMCI_SW_VER2 V1.1.0P1T9
flash set GPON_ONU_MODEL EPON
flash set GPON_SN <你的_GPON_SN>
flash set GPON_PLOAM_PASSWD <LOID_的_hex>
flash set ELAN_MAC_ADDR <原光猫_LAN_MAC>
flash set MAC_KEY <md5_of_hsgq1.9a+大写MAC>
flash set OUI <MAC前3字节用逗号分隔>
flash set HW_SERIAL_NO <原光猫_HW_serial>
reboot
⚠️ PLOAM 错了 ONU 会被拒,可恢复;但 SN 克隆错了可能被运营商风控标记。先在小范围验证再上线。
另外提一句合规:克隆 SN/MAC 是灰色地带,本文记的是自家电路上的折腾过程,不是教你去蹭别人的宽带。运营商真要查,PON 口下挂的设备都是看得见的。

猫棒重启后插回 SFP 槽,OLT 收到注册请求,验证通过会下发 PPPoE/IPTV/TR-069 的 service profile。

路由器配 VLAN:先把容易的搞定

下游路由器用的是 SEED AC5(iStoreOS,MT7987),SFP 槽里就是上面那根猫棒,所以从猫棒出来的所有 VLAN 都直接落在 eth1 上。需要识别四个 VLAN:

VID用途
41互联网(PPPoE 拨号)
46TR-069 管理
48IPTV 单播控制(DHCP / 鉴权 / EPG / 回看 / 时移)
900IPTV 多播视频流(直播)

**互联网 / TR-069 这部分是常规操作。**PPPoE 在 OpenWrt 里就是标准配置:

uci set network.wan.proto='pppoe'
uci set network.wan.device='eth1.41'
uci set network.wan.username='<你的宽带账号>@139.gd'
uci set network.wan.password='<密码>'
uci commit network
ifup wan

TR-069 类似,DHCP 拿地址但关掉 default route 和 peer DNS,避免污染主路由表:

uci set network.tr069.proto='dhcp'
uci set network.tr069.device='eth1.46'
uci set network.tr069.defaultroute='0'
uci set network.tr069.peerdns='0'

到这里互联网部分跑通——PPPoE 拨号、IPv6、CGNAT 全都正常,2.5G 物理口直接打满。

难的是 IPTV。这才是这篇文章的重头戏。

IPTV:以为很简单,结果……

家里有长辈,他们不像年轻人都看网络点播,习惯坐沙发上看电视直播——这也是为什么必须把 IPTV 跑通,不能「算了用网络版凑合」。

最初看这事是真不当回事的。原来那台 F663N 光猫上有一个独立的 IPTV LAN 口,运营商出厂时就把对应的 VLAN、PPPoE/IPoE、组播参数都在光猫内部配好了,魔百盒直接插那个口就能开机看直播,用户根本不需要知道 VLAN 48、VLAN 900 这些东西的存在。所以我换猫棒的时候很自然地想:那不就是把这一个口的逻辑挪到自己路由器上吗?给机顶盒拉一个 VLAN,配下 DHCP,应该半小时搞完。

结果整整折腾了一天。

第一阶段:只配 VLAN 48,发现少了点东西

最初的想法很朴素:VLAN 48 是单播控制,VLAN 900 是多播视频,先把 VLAN 48 弄通看看魔百盒能不能开机。

eth1.48 起一个接口、放一个 br-iptv、给魔百盒一个 DHCP——很顺利就跑起来了:

  • ✅ 魔百盒能开机、能登录、能鉴权
  • ✅ 频道列表、EPG 正常加载
  • 回看正常、时移正常(这俩走 HTTP 单播,VLAN 48 就够了)
  • 直播没画面

奇了怪了,回看都能看,怎么直播反而不行?看了一下才反应过来:直播走的是组播,封装在 VLAN 900 里,单纯把 VLAN 48 通了根本没把直播流喂下来。

试过的弯路(避坑)

在搞清楚要上 igmpproxy 之前,我先试了两条看起来更省事的路子,都不通,记下来给后人避坑:

弯路 A:VLAN 48 + VLAN 900 都做 untagged 扔同一个桥

直觉上是把所有 IPTV 流量都堆给魔百盒,让它自己处理。结果魔百盒同时从 VLAN 48 和 VLAN 900 收到 DHCP 响应,拿到两个 IP,状态机直接卡住——注册不上 IPTV 平台。

弯路 B:在 AC5 的交换芯片上把 LAN6 配两个 untagged VLAN

打算让交换机硬件层面就把两个 VLAN 都送到魔百盒口。结果发现 AC5 的 eth1 交换芯片不支持同一个端口配置两个 untagged VLAN——这是硬件限制,VLAN ingress 表里一个 port 只能落到一个 PVID。换句话说,想「魔百盒口同时收 VLAN 48 和 VLAN 900 的 untagged 帧」在 MT7987 这套交换芯片上根本配不出来。

走完这两条死路之后才确认:多播必须在路由器上做 L3 处理,不能指望硬件 L2 解决。

第二阶段:L2 桥跨 VLAN flood——还是不行

下一个直觉:把 eth1.48(控制 VLAN)和 eth1.900(多播 VLAN)扔进同一个 bridge br-iptv,开 IGMP snooping,让多播在桥里 flood 给魔百盒——这跟原 F663N 内部 IGMP-Proxy 的逻辑大致是一样的。

这套在 MT7987 上根本不工作。魔百盒能拿单播 IP,能登录,但选频道之后还是没画面。

抓包发现:

  • eth1.900 RX 哗哗地涌进多播包(一个频道几百 kB/s)
  • eth1.48 TX 几乎纹丝不动
  • bridge mdb show dev br-iptv 全空——即使魔百盒在发合法的 IGMP v2 report

三个原因,每个都能让你怀疑人生:

  1. MTK PPE / hwnat 在劫持流量。iStoreOS 默认 flow_offloading_hw=1,硬件加速会在 Linux bridge 之前就把多播包消化掉。即便 multicast_snooping=0 让桥强制 flood,硬件这层也拦着不放。
  2. 桥的 IGMP snooping mdb 表始终空的。桥本身没 IP,querier 源 IP 是 0.0.0.0,snooping 模块在这种状态下不会正确学习魔百盒的 join report。
  3. 同 trunk 的 split-horizon:魔百盒和 carrier 都通过同一根物理 eth1 走 VLAN 48 上来,Linux bridge 默认不会把流量送回入口端口(除非开 hairpin),所以即便桥成功转发,魔百盒也收不到 carrier 的回包。

结论:这套必须上 L3,让内核多播路由(MFC)来干这事,绕开桥和硬件加速

第三阶段:igmpproxy L3 方案

整体思路:

/etc/config/network 关键部分:

# br-iptv 只放魔百盒这一侧
config device
    option name 'br-iptv'
    option type 'bridge'
    list ports 'eth1.48'
    option igmp_snooping '1'
    option multicast_querier '0'   # 让 igmpproxy 当 querier

config interface 'iptv'
    option proto 'static'
    option device 'br-iptv'
    option ipaddr '192.168.99.1'
    option netmask '255.255.255.252'
    option defaultroute '0'

# eth1.900 独立做 upstream
config interface 'iptv_mcast'
    option proto 'static'
    option device 'eth1.900'
    option ipaddr '10.0.0.2'
    option netmask '255.255.255.0'
    option defaultroute '0'
    option peerdns '0'

防火墙加一个区让两边互通:

config zone
    option name 'iptv'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'
    list network 'iptv'
    list network 'iptv_mcast'

最重要:硬件 flow offload 必须关掉

uci set firewall.@defaults[0].flow_offloading_hw='0'
uci set firewall.@defaults[0].flow_offloading='1'      # 软件 offload 留着

/etc/config/igmpproxy

config igmpproxy
    option quickleave 1

config phyint iptv_mcast
    option network 'iptv_mcast'
    option direction 'upstream'
    list altnet '183.235.0.0/16'

config phyint iptv
    option network 'iptv'
    option direction 'downstream'
    list altnet '100.64.0.0/10'

/etc/init.d/igmpproxy enable
/etc/init.d/igmpproxy restart

收尾的坑:altnet 不能写 0.0.0.0/0

第一遍配的时候我图省事在 upstream 和 downstream 两边都写了 altnet 0.0.0.0/0igmpproxy 死活不工作,日志一直在刷:

warn igmpproxy: No interfaces found for source 100.98.x.y

ip mroute show 永远是 Iif: unresolved

原因在 igmpproxy 0.4getIfByAddress() 实现:它用最长前缀匹配来决定 IGMP 报文是从哪个 phyint 进来的。两边都是 0.0.0.0/0(mask = 0),两个接口都「匹配」但优先级一致,函数返回 NULL,IGMP 报文直接被拒收。

修法是给两边各自一个能区分来源 IP 的具体段

  • upstream eth1.900altnet 183.235.0.0/16 —— carrier 多播头端的源段(用 tcpdump -i eth1.900 -nn 'multicast' 实测确认)
  • downstream iptv (br-iptv):altnet 100.64.0.0/10 —— 运营商 CGNAT 大段(实测魔百盒拿到的就是 100.98.x.x 之类的 IP,全在这段里)

改完重启 igmpproxy,立即就工作了。

验证

# 内核 MFC 已建立路由
$ ip mroute show
(183.235.0.17,239.10.0.114)  Iif: eth1.900  Oifs: br-iptv  State: resolved

# br-iptv 出口数据流飙升(一个 HD 频道大约 3-4 MB / 12s)
$ ip -s link show br-iptv | grep -A1 TX
TX:  bytes  packets ...
     3418950   2589

# 魔百盒 IGMP join 在 eth1.48 入口可见
$ tcpdump -i eth1.48 -nn -e 'igmp'
<MBOX-MAC> > 01:00:5e:0b:00:44, vlan 48, p 0,
  <MBOX-IP> > 239.11.0.68: igmp v2 report 239.11.0.68

电视画面瞬间出来,遥控切台也丝滑。

三层心法

把这件事拆成三个层次记住:

  1. 运营商 PON 鉴权 = 克隆 OMCI 字段。SN / PLOAM 是公开的克隆要点,OMCI 那一堆 HW_CWMP_*OMCI_SW_VER*GPON_ONU_MODEL 才是 OLT 真正用来识别「你是不是合法设备」的地方。
  2. PPPoE / TR-069 / IPTV 单播 = L2 透传就行。VLAN 41/46/48 在 OpenWrt 上当成普通 8021q sub-interface 处理,连标准 NAT/DHCP 流程都能跑。注意 IPTV 的回看和时移都走单播 HTTP,只配 VLAN 48 就够;唯独直播是多播,必须额外处理 VLAN 900。
  3. 多播 IPTV ≠ L2 转发。在 MT7987 这类带 PPE 硬件加速的平台上,L2 桥跨 VLAN flood 多播是不工作的。正解是 L3:igmpproxy + 关 hwnat + altnet 写具体段

附带踩出来的几条经验:

  • getIfByAddress 的最长前缀匹配会让 0.0.0.0/0 成为陷阱,写 altnet 一定要用能区分来源的具体段。
  • flow_offloading_hw 默认开但对多播路由有害,软件 flow offload (flow_offloading=1) 是安全的——这个组合是 MT7987 这一代 SoC 上多播工作的硬条件。
  • multicast_querier=1 在桥没 IP 的情况下源会变成 0.0.0.0,许多机顶盒和 snooping 模块对这种 query 处理有问题——交给 igmpproxy 做 querier 反而更可靠。
  • 别试图在交换芯片上让一个端口同时 untagged 两个 VLAN,至少 MT7987 这套硬件不支持。

后记

跑了一段时间,记录一下实际效果:

  • 那台 ZTE F663N 已经收进抽屉吃灰,光纤直接进 AC5 的 SFP 槽。
  • PPPoE 的 500M 带宽轻轻松松跑满,2.5G 内网也能稳定 280MB/s+。
  • 直播 4K 频道流畅、回看时移都正常,切台没感觉跟原来有什么不同——这条最关键,验收通过。
  • 不再需要每隔几天去重启那台砖头光猫,省心。

回头看,这次折腾的本质是把光猫这个最后的「运营商飞地」也收进自己的网络管理体系里。六年前那次解 cfg 改桥接是软改,治标;这次直接把硬件也换掉,治本。下一步可能是 PoE 那条 LAN 出去带个吸顶 AP,全屋 Wi-Fi 6E 也升一升,不过那是另一篇文章了。

参考

编辑于 2026-05-15 · 著作权归作者所有
相关文章
iPhone 18 Pro系列或迎来7项升级,自研C25G基带能否终结信号顽疾?为什么越来越多的人不接陌生电话导致联络困难?如何评价 6 月 1 日华为发布路由 Q7 电线版?搭载的 PLC3.0 技术如何实现全屋跑满千兆?诺基亚发布首款微聊手机,售价199元,可视频通话,但连不了WiFi,该机在当前市场生存空间大吗?iPhone 18 Pro系列或迎来7项升级,自研C25G基带能否终结信号顽疾?朋友教了我一个办法,终于登上了那个一直进不去的电报!如何评价 6 月 1 日华为发布路由 Q7 电线版?搭载的 PLC3.0 技术如何实现全屋跑满千兆?软路由是否被过度神化?2026年初能在中国漫游的英国esim实体号码保号套餐盘点如何评价 6 月 1 日华为发布路由 Q7 电线版?搭载的 PLC3.0 技术如何实现全屋跑满千兆?如何阻止骚扰电话?运营商竞合,1月份还有哪些套餐可以办?为什么现在只有香蕉出了mt7988的路由器?华为路由好不好?如何评价 6 月 1 日华为发布路由 Q7 电线版?搭载的 PLC3.0 技术如何实现全屋跑满千兆?【限时上架】2026年流量卡扛把子?230G通用流量巨大杯?!这样的配置能薅多久?诺基亚发布首款微聊手机,售价199元,可视频通话,但连不了WiFi,该机在当前市场生存空间大吗?月租 5 美元,在国内拥有一个真正能用的美国手机号如何获取一个可以长期使用海外实体电话卡?2026随身WiFi实测:49 元机型把200元档按在地上摩擦?