光猫-路由单线复用下的拨号频繁掉线问题
有段时间折腾光猫设置后,在设备和架构都没变的情况下,路由器每隔几个小时都会发生一次重拨。通常家宽在拨号后,因为安全性和增值服务等原因,运营商会设置一个强制重拨的时间,到达时间会主动将用户踢下线触发重拨更换IP,但不应该一天重拨好几次,频繁更换ip会造成短暂的断网,影响正常使用。应该不是这个强制重拨的机制。
除此之外,还有一个保活的机制,运营商会向路由器主动发送一个LCP Echo Request,等待路由器回应LCP Echo Reply,一来一回确认当前拨号连接仍然有效,若失效则会主动发送LCP terminated by peer来关闭连接。这个保活除了运营商可以发起,部分路由器固件也支持主动发起Request检测PPPOE链路状态。在发生频繁掉线后,路由器日志显示No response to 5 echo-requests,起初认为是运营商局端设备懒得回应,导致路由器误以为链路异常主动关闭了连接,所以索性我也关掉了路由器侧的LCP Echo检测。
但是掉线问题还是没有解决,依旧每隔几个小时发生掉线,这次的日志内容显示LCP terminated by peer,这个是局端设备主动发送报文踢下线的。

网络拓扑与配置回顾
光猫
桥接模式,关闭DHCP,PON口上网业务绑定VID41,将LAN4设置为VLAN绑定模式并设置为41/41。

路由器OpenWRT单臂配置
路由器的wan口在op上为eth1,在eth1上创捷子接口eth1.41,用来处理带VID41的帧,并作为PPPoE拨号的WAN口。

将eth1加入br-lan桥,作为局域网LAN口,处理内网设备流量。

此时完成了单线复用,光猫--路由器的网线同时承载两种数据,分别是PPPoE的上网数据和LAN的内网数据,通过VLAN来隔离。
默认情况下,子接口eth1.41会继承物理接口eth1的MAC地址,而br-lan作为桥接设备,其MAC地址也通常取自第一个加入的端口(即eth1),因此两者MAC地址相同。

省流—解决办法
在确认过运营商侧以及光信号无异常的情况下,在网上搜索到一个可能性:触发了光猫固件的bug[1],因为不可能给光猫修bug,贴主和评论区网友提出了两种解决办法:1.放弃使用VLAN,2.给接口设置不同MAC地址。我采取了方法2,给eth1.41单独设置了一个新的MAC地址,已经完美解决,不再频繁掉线了。


至此,如果你也在单线复用中遇到了一样的问题,也可以尝试使用以上两种解决方法。
如果你对为什么改mac就能解决这个问题感兴趣的话,可以继续往下看,下面的内容是我对这个问题的分析:
正常的保活流程
运营商 OLT 发给你的 PPPoE 报文(包括 LCP echo-request 保活请求),是带 VID41 的以太网单播帧,目的 MAC 是你路由器拨号接口(eth1.41)的 MAC 地址。
光猫 PON 口收到该帧,匹配到桥接规则:VID41 的帧透传到对应 LAN 口,不修改、不剥离 VLAN 标签,直接从 LAN 口发给路由器 eth1 口。
路由器 eth1 口收到带 VID41 的帧,Linux 内核先处理 VLAN:
识别到 VID41,将帧交给对应的子接口 eth1.41,剥离标签后上送协议栈。
绑定在 eth1.41 上的 pppd 进程,捕获到该 LCP 保活请求,立即回应 LCP echo-reply。
路由器 eth1.41 发出的 PPPoE 回应报文,内核自动打上 VID41 标签,从 eth1 物理口发给光猫。
光猫 LAN 口收到带 VID41 的帧,匹配桥接规则,透传到 PON 口,完整保留标签发给运营商 OLT。
运营商收到回应,确认链路正常,不会断开连接。
光猫的潜在Bug与MAC地址冲突
当eth1.41和br-lan拥有相同的MAC地址时,光猫作为二层桥接设备,会通过源地址学习建立MAC地址表。由于路由器发出的带VLAN 41标签的帧(来自eth1.41)和发出的无标签帧(来自br-lan)都使用相同的源MAC,光猫会在两个不同的VLAN上下文中记录同一个MAC指向同一个物理端口:
在VLAN 41的转发表中,该MAC对应LAN口。
在无标签的转发表中,该MAC也对应同一个LAN口。
这种重复条目可能导致光猫的交换芯片在处理来自ISP侧的帧时发生混淆。例如,当ISP发送一个带VLAN 41标签的LCP Echo请求(目的MAC为路由器的WAN口MAC)时,光猫本应查找VLAN 41的转发表,找到对应端口并保留标签转发。但由于该MAC同时存在于无标签表中,某些有缺陷的固件可能错误地选择了无标签表项,从而将帧以无标签形式从LAN口发出。
路由器收到这个 untag 帧后,内核的处理逻辑是:
没有 VLAN 标签 → 不会交给 eth1.41 子接口,只会交给物理口 eth1,进而交给 br-lan 桥处理。
pppd 进程,是绑定在 eth1.41 接口上的,只会捕获从 eth1.41 接口收到的 PPPoE 报文,从 br-lan 接口进来的报文,pppd 完全收不到。
最终结果:pppd 没有收到 LCP 保活请求,不会发送回应。运营商超时后,认为链路失效,主动发送LCP terminated by peer断开连接。
为什么修改 eth1.41 的 MAC 地址就解决了?
将 eth1.41 的MAC地址改为与br-lan不同后,两个接口的MAC不再相同。此时:
路由器发出的带VLAN 41标签的帧源MAC为新MAC,光猫在VLAN 41表中学习到该新MAC对应LAN口。
路由器发出的无标签帧源MAC仍为原MAC(br-lan的MAC),光猫在无标签表中记录原MAC对应同一LAN口。
这样,光猫的MAC地址表中,两个MAC分别属于不同VLAN,没有冲突。当ISP发送带VLAN 41标签的LCP Echo请求(目的MAC为新MAC)时,光猫能正确查找VLAN 41表,找到对应端口,并加上标签后转发。路由器通过eth1.41收到带标签的帧,正常处理并回应,从而保持PPPoE会话稳定。
故网友提供的两个方法,本质都是规避这个光猫 bug:
放弃 VLAN:单 VLAN 流量,不会出现同一个 MAC 在多 VLAN 的情况,自然不会触发 bug,但会因此改变网络拓扑;
修改 MAC 地址:让两个 VLAN 的流量用不同 MAC,避免光猫 MAC 地址表混乱,是不改变组网拓扑的最优解。
参考文献:
[1]记录一次北京联通千兆光纤Openwrt拨号不停断线问题的解决(https://zhuanlan.zhihu.com/p/437784130)
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

值友3568496843
校验提示文案
值友3568496843
校验提示文案