海信的 LTF7263 一直是 10G EPON Stick 的首选方案之一,但海信的固件兼容性比较差,时常出现买家买到后发现与自己的线路不兼容的情况,LZ 就是受害者之一。
问题的表现为在没有插入光纤的时候,可以通过 telnet 和 SSH 访问,设置 MAC 、LOID 等参数,但在插入光纤后,SSH 和 telnet 断开,ping 无响应,探测不到 PPPoE server ,疑似“死机”。
使用卖家提供的 debug 方法获取 OLT 注册的日志: 开启一个 SSH 连接用来输出日志,然后开启一个 telnet 连接到管理命令行:
$ telnet 192.168.0.1 2233
...
Cortina>enable
Cortina#config
Cortina(config)#ssh-debug /dev/pts/0
Cortina(config-oam)#debug oam 8
Cortina(config-oam)#debug oam-org 8
Cortina(config-oam)#pkt-dump all
日志会输出到 SSH 所在的窗口,插入光纤,SSH 窗口输出以下 log 后连接中断:
...
ctc_oam_onu_vlan_set(): L2806, index is Valid, index = 1
ctc_oam_onu_vlan_set(): L2816, vlan mode = 1
ctc_oam_onu_vlan_set(): L2825, default vlan tpid:0x8100, tag:0x1
ctc_oam_onu_tag_vlan_set_adapt: oam_port = 1, TPID = 0x8100, tag = 0x1
_ctc_add_def_vlan(): L1691, PVID 1 on oam_port 1
用同样的方法在 LZ 手上另一条 LTF7263 可以成功注册的线路上抓取 log ,工作正常的 log 为:
...
ctc_oam_onu_vlan_set(): L2806, index is Valid, index = 1
ctc_oam_onu_vlan_set(): L2816, vlan mode = 0
ctc_oam_onu_transparent_vlan_set_adapt(): L2363, oam_port = 1, vlan_mode: transparent
...
故猜测是 OLT 侧配置的区别,工作正常的线路 OLT 侧配置为 VLAN tranparent 模式,“死机”的线路 OLT 侧配置为 VLAN tag 模式,由于固件中的 bug ,在设置 VLAN 的时候,丢失了 LAN 侧的 IP ,又由于 OLT 侧下发的 VLAN 并不是 PPPoE 所在的真实 VLAN ,导致探测不到 PPPoE 服务器。
询问卖家后得知 LTF7263 并没有可用的固件更新,故 LZ 尝试自行修改固件绕过这个 bug 。思路是忽略掉 OLT 下发的 VLAN 模式配置,强制使用 VLAN 透传模式。
日志中的信息比较充足,有函数名行号等信息,通过按 string filter 可以得到与 OLT 注册相关的逻辑全部在 /usr/lib/libca-oam.so.1.0.0
中,通过反汇编这个 so 文件,定位到函数 ctc_oam_onu_vlan_set()
,之后就可以通过 printf 输出的行号等信息查找到 vlan mode 所在的地址:
...
0x0000000000000174: 38 00 A8 8F lw $t0, 0x38($sp)
0x0000000000000178: 00 0B 03 24 addiu $v1, $zero, 0xb00 // 行号 0xb00 = 2816
0x000000000000017c: 04 00 09 91 lbu $t1, 4($t0) // 读取 vlan mode
0x0000000000000180: 18 00 A3 AF sw $v1, 0x18($sp)
0x0000000000000184: 2C 80 83 8F lw $v1, -0x7fd4($gp)
0x0000000000000188: E4 83 99 8F lw $t9, -0x7c1c($gp)
0x000000000000018c: 40 00 A2 AF sw $v0, 0x40($sp)
0x0000000000000190: EC 0A 63 24 addiu $v1, $v1, 0xaec
0x0000000000000194: 3C 00 A8 AF sw $t0, 0x3c($sp)
0x0000000000000198: 1C 00 A9 AF sw $t1, 0x1c($sp) // 将 vlan mode 写入 printf 参数
0x000000000000019c: 38 00 A9 AF sw $t1, 0x38($sp)
0x00000000000001a0: 14 00 B0 AF sw $s0, 0x14($sp)
0x00000000000001a4: 10 00 A3 AF sw $v1, 0x10($sp) // 将行号写入 printf 参数
0x00000000000001a8: 25 38 00 00 move $a3, $zero
0x00000000000001ac: 08 00 06 24 addiu $a2, $zero, 8
0x00000000000001b0: 05 00 05 24 addiu $a1, $zero, 5
0x00000000000001b4: 09 F8 20 03 jalr $t9 // 调用 printf
0x00000000000001b8: 25 20 00 00 move $a0, $zero
...
将对应的位置改为:
0x000000000000017c: 25 48 00 00 move $t1, $zero // 强制设置 vlan mode = 0
把修改过的 so 文件复制到 LTF7263 中覆盖原始固件,重启之后插入光纤,log 中显示已强制使用 vlan transparent 模式:
...
ctc_oam_onu_vlan_set(): L2806, index is Valid, index = 1
ctc_oam_onu_vlan_set(): L2816, vlan mode = 0
ctc_oam_onu_transparent_vlan_set_adapt(): L2363, oam_port = 1, vlan_mode: transparent
...
“死机”现象不再出现,查看后续 log 显示 OLT 注册成功,对应的 VLAN 可以探测到 PPPoE server ,拨号后测速达标,问题解决。希望海信的工程师可以在后续的固件中彻底修正这个问题。
分享一下传输文件和patch so文件的方法。比较方便的传输文件的方法是直接使用nc来建立连接,例如PC的IP为192.168.0.100:
PC端准备接收文件:
$ nc -l 5000 < /dev/null > libca-oam.so.1.0.0
猫棒端检查md5并发送文件:
# md5sum /usr/lib/libca-oam.so.1.0.0
a8d470daea0afcd627ccd0dc206caf36 /usr/lib/libca-oam.so.1.0.0
# nc 192.168.0.100 5000 < /usr/lib/libca-oam.so.1.0.0
PC端接收到文件后验证md5,验证无误后打patch并传输到猫棒:
$ md5sum libca-oam.so.1.0.0
a8d470daea0afcd627ccd0dc206caf36 libca-oam.so.1.0.0
$ xxd libca-oam.so.1.0.0 | sed 's/0003f480: 0400 0991/0003f480: 2548 0000/' | xxd -r > libca-oam.so.1.0.0.patched
$ md5sum libca-oam.so.1.0.0.patched
19a0de2ee15bf7dc583e703078c69caf libca-oam.so.1.0.0.patched
$ nc -l 5000 < libca-oam.so.1.0.0.patched
猫棒端接收文件并验证:
# nc 192.168.0.100 5000 < /dev/null > libca-oam.so.1.0.0
# md5sum libca-oam.so.1.0.0
19a0de2ee15bf7dc583e703078c69caf libca-oam.so.1.0.0
验证md5无误后覆盖原固件:
# cp libca-oam.so.1.0.0 /usr/lib/libca-oam.so.1.0.0
# reboot
本文转载自@wsxhwyy 发布在V2EX的主题,不代表淡定定定哥立场,如若侵权,请联系我删除