F
Member
光模块出问题时,多数人的第一反应是登录交换机翻 DDM 页面。但如果机器是 Linux 主机、网卡是普通服务器网卡,或者你需要在脚本里批量采集,命令行工具链才是正解。这篇把常用的几个工具和它们的坑整理成一套可复用的采集脚本。
一、ethtool:最基础也最容易读错
ethtool eth0 看链路状态、速率、双工
ethtool -m eth0 读模块信息(需 root)
ethtool -m eth0 raw on 输出原始十六进制,配合 hexdump 看具体字节
关键字段解读:
Identifier 0x03 = SFP/SFP+,0x0d/0x11 = QSFP 系列
Vendor name / OUI 厂商标识,白名单校验就查这个
Laser output power 发射光功率,单位 mW 或 dBm(看驱动版本)
Receiver signal average optical power 接收光功率
Module temperature 模块壳温,不是环境温度
坑 1:单位不统一
不同内核版本、不同厂商驱动,ethtool 输出的单位可能是 mW 也可能是 dBm,
脚本里必须判断单位,否则会算出荒谬的值。
稳妥做法:用 raw 模式自己解析,绕过驱动的单位转换。
坑 2:部分驱动需要先打开 DDM
有些老驱动默认不读 A2h 页,需要 ethtool --set-priv-flags 或者
加载模块时给参数(比如 ixgbe 的 allow_unsupported_sfp=1)。
这类参数有风险,生产环境慎用。
二、i2c-tools:直接读 EEPROM,最可靠
SFP 模块在 I2C 上表现为两个设备地址:
0x50 = A0h 页(静态信息:厂商、型号、序列号、波长、距离)
0x51 = A2h 页(动态信息:温度、电压、偏置、光功率、告警阈值)
命令:
i2cdetect -l 列出所有 I2C 总线
i2cdetect -y <bus> 扫描该总线上的设备,找到 0x50/0x51
i2cdump -y <bus> 0x50 dump A0h 页全部 256 字节
i2cget -y <bus> 0x51 0x00 w 读温度(16 位,需处理符号)
温度解析:A2h 页 0x00-0x01 是 16 位有符号整数,单位 1/256 °C。
raw = 0x1A80 = 6784 → 6784/256 = 26.5 °C
负温度要按补码处理,Python 里用 struct.unpack('>h', ...) 最省事。
光功率解析:0x06-0x07(Tx)与 0x08-0x09(Rx),单位 0.1 μW。
raw = 0x0BB8 = 3000 → 300.0 μW = 10*log10(0.3) = -5.23 dBm
坑:不同封装的页结构不一样
QSFP/QSFP-DD 有多页结构,需要先写页选择寄存器(0x7F)再读,
直接 i2cdump 只能看到第 0 页。别拿 SFP 的解析器去解 QSFP。
三、devlink:新一代的统一下发接口
devlink port show
devlink port param show
部分驱动支持通过 devlink 读光模块信息,接口比 ethtool 稳定,
但目前覆盖不全,只能作为补充。
四、一个可复用的采集脚本思路
我们内部用 Python 写了一个采集器,逻辑是:
1. 遍历 /sys/class/net/ 下所有物理网口
2. 对每个网口执行 ethtool -m,失败则回退到 i2c 直读
3. 解析出:温度、Tx Power、Rx Power、Bias、厂商、型号、序列号
4. 计算告警位:对照 A2h 页的阈值(0x00-0x27),判断是否越限
5. 输出 JSON,推到时序数据库
关键设计:
一定要采集"阈值",不只是"实时值"。
不同模块的告警门限不同,只采实时值无法判断是否越限。
一定要采集"误码计数"(rx_crc_errors、rx_missed_errors),
光功率正常但误码增长,说明是物理层脏,不是功率问题。
五、排查顺序(我们固化的 SOP)
1. ethtool eth0 —— 先确认链路是否 up,速率协商是否正确
2. ethtool -m eth0 —— 看温度、光功率是否在合理区间
3. ethtool -S eth0 | grep -E "err|drop|crc" —— 看误码与丢包计数
4. 对比对端 —— 一端的 Tx 对应另一端的 Rx,两端一起看才能判断是发端弱还是收端差
5. A/B 换线 —— 换跳线、换端口、换模块,每次只换一个变量
6. 光功率计实测 —— DDM 读数在高温段可能失真,实测为准
六、几个常见误判
误判 1:Rx Power 显示 -20 dBm 就认为模块坏了
先算链路预算。10 km 链路 + 4 个连接器,插损可能就 6 dB,
加上发射功率 -3 dBm,收到 -9 dBm 是正常的。-20 dBm 要查是不是跳线脏了。
误判 2:温度 70°C 就报警
工业级模块的壳温上限是 85°C,70°C 属于正常工作区间。
真正要看的是"温度与误码的相关性",温度升高误码也升高,才是问题。
误判 3:FEC 纠正计数增长就换模块
FEC corrected 增长说明物理层有劣化,但还没到影响业务的程度。
正确做法是建立基线,看增长率。缓慢增长是老化,突增是污染或弯折。
—— 北亿纤通(F-tone Networks)光互联技术团队
技术资料:https://www.f-tone.com
一、ethtool:最基础也最容易读错
ethtool eth0 看链路状态、速率、双工
ethtool -m eth0 读模块信息(需 root)
ethtool -m eth0 raw on 输出原始十六进制,配合 hexdump 看具体字节
关键字段解读:
Identifier 0x03 = SFP/SFP+,0x0d/0x11 = QSFP 系列
Vendor name / OUI 厂商标识,白名单校验就查这个
Laser output power 发射光功率,单位 mW 或 dBm(看驱动版本)
Receiver signal average optical power 接收光功率
Module temperature 模块壳温,不是环境温度
坑 1:单位不统一
不同内核版本、不同厂商驱动,ethtool 输出的单位可能是 mW 也可能是 dBm,
脚本里必须判断单位,否则会算出荒谬的值。
稳妥做法:用 raw 模式自己解析,绕过驱动的单位转换。
坑 2:部分驱动需要先打开 DDM
有些老驱动默认不读 A2h 页,需要 ethtool --set-priv-flags 或者
加载模块时给参数(比如 ixgbe 的 allow_unsupported_sfp=1)。
这类参数有风险,生产环境慎用。
二、i2c-tools:直接读 EEPROM,最可靠
SFP 模块在 I2C 上表现为两个设备地址:
0x50 = A0h 页(静态信息:厂商、型号、序列号、波长、距离)
0x51 = A2h 页(动态信息:温度、电压、偏置、光功率、告警阈值)
命令:
i2cdetect -l 列出所有 I2C 总线
i2cdetect -y <bus> 扫描该总线上的设备,找到 0x50/0x51
i2cdump -y <bus> 0x50 dump A0h 页全部 256 字节
i2cget -y <bus> 0x51 0x00 w 读温度(16 位,需处理符号)
温度解析:A2h 页 0x00-0x01 是 16 位有符号整数,单位 1/256 °C。
raw = 0x1A80 = 6784 → 6784/256 = 26.5 °C
负温度要按补码处理,Python 里用 struct.unpack('>h', ...) 最省事。
光功率解析:0x06-0x07(Tx)与 0x08-0x09(Rx),单位 0.1 μW。
raw = 0x0BB8 = 3000 → 300.0 μW = 10*log10(0.3) = -5.23 dBm
坑:不同封装的页结构不一样
QSFP/QSFP-DD 有多页结构,需要先写页选择寄存器(0x7F)再读,
直接 i2cdump 只能看到第 0 页。别拿 SFP 的解析器去解 QSFP。
三、devlink:新一代的统一下发接口
devlink port show
devlink port param show
部分驱动支持通过 devlink 读光模块信息,接口比 ethtool 稳定,
但目前覆盖不全,只能作为补充。
四、一个可复用的采集脚本思路
我们内部用 Python 写了一个采集器,逻辑是:
1. 遍历 /sys/class/net/ 下所有物理网口
2. 对每个网口执行 ethtool -m,失败则回退到 i2c 直读
3. 解析出:温度、Tx Power、Rx Power、Bias、厂商、型号、序列号
4. 计算告警位:对照 A2h 页的阈值(0x00-0x27),判断是否越限
5. 输出 JSON,推到时序数据库
关键设计:
一定要采集"阈值",不只是"实时值"。
不同模块的告警门限不同,只采实时值无法判断是否越限。
一定要采集"误码计数"(rx_crc_errors、rx_missed_errors),
光功率正常但误码增长,说明是物理层脏,不是功率问题。
五、排查顺序(我们固化的 SOP)
1. ethtool eth0 —— 先确认链路是否 up,速率协商是否正确
2. ethtool -m eth0 —— 看温度、光功率是否在合理区间
3. ethtool -S eth0 | grep -E "err|drop|crc" —— 看误码与丢包计数
4. 对比对端 —— 一端的 Tx 对应另一端的 Rx,两端一起看才能判断是发端弱还是收端差
5. A/B 换线 —— 换跳线、换端口、换模块,每次只换一个变量
6. 光功率计实测 —— DDM 读数在高温段可能失真,实测为准
六、几个常见误判
误判 1:Rx Power 显示 -20 dBm 就认为模块坏了
先算链路预算。10 km 链路 + 4 个连接器,插损可能就 6 dB,
加上发射功率 -3 dBm,收到 -9 dBm 是正常的。-20 dBm 要查是不是跳线脏了。
误判 2:温度 70°C 就报警
工业级模块的壳温上限是 85°C,70°C 属于正常工作区间。
真正要看的是"温度与误码的相关性",温度升高误码也升高,才是问题。
误判 3:FEC 纠正计数增长就换模块
FEC corrected 增长说明物理层有劣化,但还没到影响业务的程度。
正确做法是建立基线,看增长率。缓慢增长是老化,突增是污染或弯折。
—— 北亿纤通(F-tone Networks)光互联技术团队
技术资料:https://www.f-tone.com