2. 交换机硬件平台剖析
一台 SONiC 交换机在软件视角下并不是"一块黑盒 ASIC",而是由多个可独立寻址、可独立观测的硬件子系统拼装而成。SONiC 的核心设计思想之一,就是把每个硬件子系统抽象成统一的软件对象,让上层网络协议栈(BGP、LLDP、ACL、QoS 等)不必关心底层是 Broadcom Tomahawk、Marvell Teralynx 还是 Mellanox Spectrum。理解这些抽象,是后续做平台适配和镜像构建的前提。
一、硬件组件全景
典型数据中心交换机(以 32×400G 为例)的硬件构成大致分为七类:
- CPU 子系统:通常为 x86(Intel Xeon-D、Atom C3000)或 ARM64(Marvell CN9130、NXP LX2160)。运行 SONiC 的 Linux 用户态与内核,通过 PCIe 连接交换芯片,通过 I2C/SMBus 连接各类管理器件。
- 交换芯片(ASIC):负责线速转发、ACL、QoS、隧道封装。对外暴露 SDK(如 Broadcom OpenNSL/SAI、Marvell Prestera SAI),SONiC 通过 SAI 接口调用。
- PHY / Retimer:在 ASIC SerDes 与前面板端口之间做信号整形、均衡、速率转换(如 100G→4×25G breakout)。部分平台 PHY 由 ASIC 内部集成,部分为外置芯片(如 Credo、Inphi)。
- 光模块:QSFP-DD/OSFP/SFP 等封装,通过 I2C 的 EEPROM(地址 0x50)暴露厂商、型号、温度、DDM 诊断信息。
- 风扇:多为 4~6 个热插拔风扇模块,通过 CPLD 或 BMC 的 PWM 通道调速,转速由 TACH 信号回读。
- 电源:1+1 或 2+2 冗余 PSU,通过 PMBus 报告输入电压、输出电流、温度、在位状态。
- 传感器:温度(LM75、TMP421)、电压(INA3221)、电流监控,分布在 ASIC 附近、光模块笼子、电源入口。
二、SONiC 的抽象层次
SONiC 把这些硬件统一收敛到几个关键抽象:
SAI(Switch Abstraction Interface):交换芯片的唯一入口。所有 VLAN、端口、下一跳、ACL、QoS 队列都通过 SAI 的 C API 下发。SAI 之上是 syncd 进程,它把 Redis 中的配置翻译成 SAI 调用;SAI 之下是厂商 SDK。平台适配时,只要厂商提供符合 SAI 版本的 SDK 库(libsai.so),SONiC 就能驱动该 ASIC。
platform 抽象:由 sonic-platform-daemons 中的 pmon、thermalctld、psud、syseepromd 等守护进程负责。它们读取平台厂商提供的 Python 插件(位于 /usr/share/sonic/device/<platform>/),把风扇、电源、温度、EEPROM 信息写入 Redis 的 STATE_DB 和 FAN_DB、PSU_DB、THERMAL_DB。
端口与光模块抽象:xcvrd 守护进程周期性读取每个端口的 EEPROM,把厂商名、序列号、温度、Rx Power 写入 STATE_DB 的 TRANSCEIVER_INFO 与 TRANSCEIVER_DOM_SENSOR 表。portmgrd 则根据 config_db 中的端口配置,通过 SAI 设置 admin up/down、MTU、FEC 模式。
三、组件与抽象路径对照
下面这张图把硬件组件、SONiC 守护进程、Redis 表、以及对外接口的对应关系画在一起,便于在适配时快速定位"某个硬件该改哪个文件"。
四、平台适配时最常改动的三处
结合上面的抽象路径,平台适配工作可以聚焦到三个位置:
- SAI 库与 profile:厂商提供的
libsai.so必须与 SONiC 使用的 SAI 头文件版本匹配(如 SAI 1.11、1.12)。同时需要提供sai.profile,指定 ASIC 初始化配置、端口映射表、SerDes 参数。若版本不匹配,syncd启动时会报SAI_API_VERSION不兼容。 - platform 插件:在
device/<vendor>/<platform>/下提供fan.py、psu.py、thermal.py、sfp.py、eeprom.py。这些插件通过 sysfs 或 I2C 读写硬件,返回统一字典。例如风扇插件需实现get_speed()、set_speed()、get_status()。 - 端口配置:
port_config.ini或platform.json定义每个前面板端口对应的 ASIC 通道、lane 数、速率、FEC 模式。这是portmgrd初始化端口的依据,也是 breakout 配置的来源。
show platform fan 或 show interface transceiver 中显示异常时,先确认对应守护进程是否运行(docker exec pmon supervisorctl status),再检查插件脚本能否在设备上独立执行并返回合理值,最后核对 Redis 中对应表项是否被正确写入。
五、一个具体的抽象示例:光模块温度读取
以读取 QSFP-DD 光模块温度为例,完整链路如下:
# 1. xcvrd 通过 I2C 读取 EEPROM 页 0xA0 偏移 0x16(温度高字节)
# 2. 温度 = 有符号整数,单位 1/256 ℃
# 3. 写入 STATE_DB:
# TRANSCEIVER_DOM_SENSOR|Ethernet0
# temperature: 42.5
# 4. CLI 查询:
show interface transceiver dom Ethernet0
# 输出: Temperature: 42.5 C
如果平台适配时 sfp.py 中的 I2C 地址映射写错(例如把 0x50 写成 0x51),xcvrd 会持续报 Failed to read EEPROM,show interface transceiver 显示 N/A。这就是抽象层与硬件层脱节的典型表现。
六、小结
SONiC 对硬件的抽象可以概括为"三条路径、四类数据库、五个守护进程":SAI 管 ASIC,platform 插件管风扇/电源/传感器,EEPROM 解析管光模块;数据统一落到 CONFIG_DB、STATE_DB、FAN_DB/PSU_DB、THERMAL_DB;由 syncd、xcvrd、thermalctld、psud、pmon 分别维护。平台适配的本质,就是让这三条路径在目标硬件上都能正确工作,并让数据在 Redis 中可查、可管、可告警。