4. 数据包格式:InfiniBand数据包结构、头部字段、数据负载与CRC

4.1 数据包的整体层次结构

InfiniBand 的数据包并非单一扁平结构,而是由多个协议层头部依次封装而成。理解这一层次关系是掌握报文格式的基础。一个完整的 InfiniBand 数据包从外到内依次为:LRH(Local Routing Header,本地路由头) → GRH(Global Routing Header,全局路由头,可选) → BTH(Base Transport Header,基础传输头) → 扩展传输头(如 RETH/RDMA 扩展头、原子操作头等,按需出现) → 数据负载(Payload) → I-CRC(Invariant CRC,不变校验) → V-CRC(Variant CRC,可变校验)。其中,LRH 和 V-CRC 由链路层负责生成与解析,而 GRH、BTH 及上层字段则由网络层和传输层处理。链路层关注的核心是 LRH、I-CRC 与 V-CRC 的正确性。

关键区分:I-CRC 覆盖从 LRH 之后到 Payload 结束的所有字段(即“不变”部分),而 V-CRC 覆盖整个数据包(包括 LRH 和 I-CRC)。这种设计使得交换机在转发时只需修改 LRH(如下一跳 DLID)并重新计算 V-CRC,而无需触碰 I-CRC,从而大幅降低转发延迟。

InfiniBand 数据包链路层封装结构 LRH 本地路由头 8 字节 GRH 全局路由头 40 字节(可选) BTH 基础传输头 12 字节 扩展传输头 RETH/原子等 0~64 字节 Payload 数据负载 0~4096 字节 I-CRC 不变校验 4 字节 V-CRC 可变校验 2 字节 I-CRC 覆盖范围(GRH 之后至 Payload 末尾) V-CRC 覆盖范围(整个数据包) 链路层处理区域 发送端 生成 LRH + 计算 V-CRC 交换机转发 修改 DLID + 重算 V-CRC 接收端 校验 V-CRC + 校验 I-CRC

4.2 LRH 关键字段详解

LRH 是链路层最核心的头部,共 8 字节,由发送端的 HCA(Host Channel Adapter)或交换机端口生成。它决定了数据包在子网内的物理转发路径。LRH 各字段布局如下表所示:

字段 位宽 偏移 说明
VL 4 bit 0-3 虚拟通道编号,用于 QoS 和流控隔离
LVer 4 bit 4-7 链路版本号,当前固定为 0x0
SL 4 bit 8-11 服务等级,映射到 VL 仲裁权重
RNR NAK 1 bit 12 接收未就绪 NAK 指示(仅用于某些控制包)
DLID 16 bit 16-31 目的本地 ID,交换机依据它做转发决策
Reserved 5 bit 32-36 保留位,必须为 0
LNH 2 bit 37-38 下一头部类型:00=GRH,01=BTH,10=GRH+BTH
SLID 16 bit 48-63 源本地 ID,标识发送端口

其中 DLID 是交换机逐跳转发的最关键依据。当数据包到达交换机时,交换机的链路层解析 LRH,提取 DLID,查询转发表后,将数据包从对应端口发出,并重写 DLID 为下一跳的端口 LID(若需要),同时更新 V-CRC。SLID 则用于接收端识别发送方身份,也用于构建反向路径。

4.3 I-CRC 与 V-CRC 的生成与校验流程

CRC 的计算是链路层保证数据完整性的核心机制。I-CRC 采用 32 位 CRC(多项式 0x11EDC6F41),V-CRC 采用 16 位 CRC(多项式 0x1021)。两者的计算覆盖范围不同,设计意图也不同。

  1. 发送端流程:首先组装 LRH、GRH(如有)、BTH 及上层数据,计算 I-CRC 并附加在 Payload 之后;随后对整个数据包(含 LRH 和 I-CRC)计算 V-CRC,并附加在包尾。
  2. 交换机转发流程:交换机收到完整数据包后,先校验 V-CRC。若通过,则解析 LRH 获取 DLID,查表确定输出端口;修改 LRH 中的 DLID(若需要),然后重新计算 V-CRC 并发送。整个过程不触碰 I-CRC。
  3. 接收端流程:HCA 端口先校验 V-CRC,确认物理传输无误;再校验 I-CRC,确认从 LRH 之后到 Payload 的数据在端到端传输中未被篡改。两层校验都通过后,才将数据包交给传输层处理。

设计精妙之处:I-CRC 覆盖范围从 GRH(或 BTH,若无 GRH)开始,到 Payload 结束,但不包括 LRH。这是因为 LRH 在每一跳都可能被修改(如 DLID 变化),而 I-CRC 需要保证端到端的数据完整性。V-CRC 则覆盖整个包,保证每一跳的物理链路传输正确。这种“分层校验”策略既保证了端到端数据一致性,又允许交换机高效转发。

4.4 典型场景:HCA 发送 RDMA 写请求的数据包

假设节点 A 的 HCA 要向节点 B 发起一个 RDMA Write 操作,写入 256 字节数据。此时数据包结构如下:

字节偏移  字段内容
0-7      LRH: VL=0, SL=0, DLID=0x0002, SLID=0x0001, LNH=01(BTH)
8-19     BTH: OpCode=RDMA_WRITE_FIRST, PSN=0x123456, LKey=0xABCD
20-27    RETH: 目标虚拟地址=0x1000, RKey=0x5678, DMA长度=256
28-283   Payload: 256 字节用户数据
284-287  I-CRC: 32位校验值
288-289  V-CRC: 16位校验值

交换机收到该包后,校验 V-CRC 通过,读取 DLID=0x0002,从转发表找到对应端口,将 DLID 改为下一跳 LID(若为直连则不变),重新计算 V-CRC 并转发。节点 B 的 HCA 收到后,先校验 V-CRC,再校验 I-CRC,确认数据完整后,将 Payload 写入 RETH 指定的虚拟地址 0x1000。

4.5 常见误区与排障复盘

误区一:混淆 I-CRC 与 V-CRC 的覆盖范围。不少初学者认为 I-CRC 覆盖整个包,导致在分析抓包文件时,看到交换机修改了 DLID 后 I-CRC 未变就误判为错误。实际上,交换机只重算 V-CRC,I-CRC 保持不变是正常行为。

误区二:忽略 LNH 字段的作用。LNH 指示了 LRH 之后跟随的是 GRH 还是 BTH。在子网内通信(无 GRH)时,LNH=01;跨子网通信(有 GRH)时,LNH=00 或 10。若 LNH 解析错误,接收端将无法正确解析后续头部,导致丢包。

排障复盘案例:某集群出现间歇性通信故障,抓包发现部分数据包的 V-CRC 校验失败。排查过程如下:

  • 检查物理层:信号完整性测试正常,排除线缆和光模块问题。
  • 检查交换机端口:统计发现故障集中在某一交换机端口,且该端口存在 CRC 错误计数增长。
  • 进一步检查发现该端口的 SerDes 参数配置有误,导致高速信号采样偏差,偶发比特翻转。
  • 重新配置 SerDes 参数后,CRC 错误计数停止增长,通信恢复正常。

该案例说明,V-CRC 是物理层信号质量的“哨兵”。当 V-CRC 错误持续出现时,应优先排查物理层和端口配置,而非上层协议逻辑。

4.6 数据包长度与 MTU 约束

InfiniBand 链路层对数据包长度有严格限制。MTU(Maximum Transmission Unit)决定了 Payload 的最大长度,常见 MTU 为 256、512、1024、2048 和 4096 字节。对于 RDMA 操作,若用户数据超过 MTU,则需分片为多个数据包,每个包携带部分 Payload,并通过 BTH 中的 OpCode 区分首包(FIRST)、中间包(MIDDLE)和尾包(LAST)。

链路层在组装数据包时,必须确保总长度不超过 MTU + LRH(8) + GRH(40,如有) + BTH(12) + 扩展头 + I-CRC(4) + V-CRC(2)。若超出,则需进行分片处理。分片逻辑由传输层负责,但链路层负责为每个分片独立计算 CRC,并在接收端按 PSN(包序列号)重组。

性能提示:在高速网络中,CRC 计算通常由硬件完成。HCA 和交换机芯片内部集成了并行 CRC 引擎,能够在每个时钟周期处理多个字节,从而保证线速转发。软件模拟 CRC 仅用于调试和测试环境,无法满足实际吞吐需求。