4. LRH(本地路由头):字段详解、功能、在数据包中的位置
4.1 LRH 在 IB 数据包中的位置与作用边界
InfiniBand 数据包在链路上传输时,并非裸奔的原始载荷,而是由一系列头部依次封装而成。其中,LRH(Local Routing Header,本地路由头)是所有 IB 数据包中第一个被发送的头部,也是交换机处理每个数据包时最先解析的 12 字节。它的核心职责是解决“数据包如何在当前子网内从一个端口走到另一个端口”的问题——注意,这里强调的是“本地”和“子网内”。一旦数据包需要跨越 IB 子网边界(通过路由器),LRH 的职责就结束,后续将由 GRH(全局路由头)接替。
下图展示了 LRH 在 IB 数据包封装中的精确位置,以及它与后续头部(GRH、BTH)和链路层 CRC(ICRC/VCRC)的关系:
从图中可以清晰看到:LRH 位于数据包最前端,紧邻物理层符号流。交换机收到一个数据包后,不需要解析 BTH 或 Payload,只需读取 LRH 中的 DLID 即可做出转发决策。这种设计使得 IB 交换机能够以极低的延迟(通常小于 100ns)完成线速转发。
4.2 LRH 各字段功能详解
LRH 共 12 字节(96 bit),其字段布局遵循 IB 规范《InfiniBand Architecture Specification Volume 1》第 5.2 章。下表列出了所有字段及其功能:
| 字段 | 位宽 | 位偏移 | 功能说明 |
|---|---|---|---|
| VL(Virtual Lane) | 4 bit | 0–3 | 指定数据包使用的虚拟通道编号(0–15)。VL 用于链路级流量隔离和 QoS 管理。注意:VL 值仅在链路上有效,每经过一条链路都可能被交换机重写。 |
| SL(Service Level) | 4 bit | 4–7 | 指定服务等级(0–15)。SL 是端到端的概念,在子网内保持不变。SL 通过 SL-to-VL 映射表决定数据包在每条链路上使用的 VL。 |
| LNH(Link Next Header) | 2 bit | 8–9 | 指示 LRH 之后的下一个头部类型: 00 = BTH(无 GRH) 01 = GRH + BTH 10 = 仅 BTH(用于 RAW 数据包) 11 = 保留 |
| DLID(Destination LID) | 16 bit | 16–31 | 目的端口的本地标识符。交换机根据 DLID 查找转发表,决定输出端口。DLID 可以是单播地址、组播地址或路由器端口地址。 |
| SLID(Source LID) | 16 bit | 32–47 | 源端口的本地标识符。接收端用于回复数据包(构造反向 LRH)以及进行路径验证。 |
| PKEY(Partition Key) | 16 bit | 48–63 | 分区密钥,用于 IB 分区机制。接收端检查 PKEY 是否与本地分区表匹配,不匹配则丢弃数据包。PKEY 的 bit 15 是 Membership 位(0 = full member,1 = limited member)。 |
| FECN(Forward Explicit Congestion Notification) | 1 bit | 64 | 前向拥塞通知位。由交换机在检测到拥塞时设置,传递给接收端。 |
| BECN(Backward Explicit Congestion Notification) | 1 bit | 65 | 反向拥塞通知位。由接收端在收到 FECN=1 的数据包后,在回复数据包中设置。 |
| CE(Congestion Experienced) | 1 bit | 66 | 拥塞经历位。用于基于时间的拥塞控制(比如 BECN 机制的补充)。 |
| Reserved | 29 bit | 67–95 | 保留位,必须为 0。接收端应忽略这些位。 |
SL 是端到端的服务等级标识,由发送端设置,在整个子网传输过程中保持不变。VL 是链路局部的虚拟通道编号,每条链路上的 VL 值可能不同。交换机根据 SL-to-VL 映射表(由 SM 配置)将数据包从入端口的某个 VL 映射到出端口的另一个 VL。例如:SL=2 的数据包在链路 A 上可能走 VL=4,在链路 B 上可能走 VL=7。
4.3 交换机处理 LRH 的流程与 DLID 转发机制
理解 LRH 的功能,最有效的方式是跟踪一个数据包经过交换机时 LRH 字段如何被读取和修改。以下是 IB 交换机对 LRH 的典型处理流程:
- 接收物理层符号:数据包从链路上到达交换机端口,物理层完成符号同步和去扰码。
- 解析 LRH 的 VL 字段:交换机确认数据包到达的 VL 是否正确(与链路级流控协商一致)。
- 提取 DLID:交换机读取 LRH 中的 DLID(16 bit),将其作为关键字查询线性转发表(LFT,Linear Forwarding Table)。
- 查表得到输出端口:LFT 由子网管理器(SM)预先配置,每个可能的 DLID 对应一个输出端口号。如果 DLID 是组播地址,则查询组播转发表(MFT),可能得到多个输出端口。
- SL-to-VL 映射:根据数据包的 SL 字段和输出端口的映射表,确定数据包在出链路上应该使用的 VL。
- 重写 LRH 的 VL 字段:将 LRH 中的 VL 字段更新为出链路的 VL 值。其他字段(SLID、DLID、SL、PKEY 等)保持不变。
- 转发数据包:将数据包从输出端口发送出去,同时可能设置 FECN 位(如果检测到拥塞)。
以下是一个具体的转发案例,展示了 LRH 字段在交换机前后的变化:
原始数据包(进入 Switch Port 3):
VL=2 SL=3 LNH=00 DLID=0x0021 SLID=0x0010 PKEY=0xFFFF
交换机处理:
1. 查 LFT:DLID=0x0021 → 输出端口 = Port 7
2. 查 SL-to-VL 映射表(Port 7):SL=3 → VL=5
3. 重写 VL 字段
转发后的数据包(从 Switch Port 7 发出):
VL=5 SL=3 LNH=00 DLID=0x0021 SLID=0x0010 PKEY=0xFFFF
注意:DLID 和 SLID 在整个子网内转发过程中保持不变。只有当数据包到达目的节点后,目的节点才根据 SLID 构造回复数据包(将 SLID 和 DLID 互换)。
4.4 常见误区与排障复盘
这是初学者最容易犯的错误。VL 是链路局部概念,每经过一条链路都可能被交换机重写。如果抓包工具显示某个数据包在链路 A 上 VL=3,在链路 B 上 VL=7,这并不代表异常,而是正常的 SL-to-VL 映射结果。
有些工程师在排查“数据包被静默丢弃”的问题时,只关注 DLID 是否正确,却忽略了 PKEY 不匹配也会导致接收端丢弃数据包。PKEY 的校验发生在接收端的 CQP(队列对)层,如果 PKEY 不匹配,数据包会被直接丢弃且不产生错误计数。
以下是一个典型的排障复盘案例:
现象:两台服务器通过 IB 交换机通信,A 端可以 ping 通 B 端,但 B 端无法 ping 通 A 端。
排查过程:
- 使用
ibping工具测试,发现单向通、单向不通。 - 在交换机上使用
perftest抓包,发现从 B 到 A 方向的数据包在交换机入口端口被丢弃。 - 检查 LRH 字段:发现 B 发出的数据包 DLID=0x0010(A 的 LID),SLID=0x0021(B 的 LID),看似正常。
- 进一步检查 PKEY:B 发出的数据包 PKEY=0x8001,而 A 所在分区的 PKEY=0x0001。PKEY 的 bit 15(Membership 位)不匹配,导致 A 端丢弃数据包。
- 根因:B 端的分区配置错误,使用了 limited member(0x8001)而 A 端要求 full member(0x0001)。
解决方案:重新配置 B 端的分区表,将 PKEY 改为 0x0001,问题解决。
4.5 LRH 与数据包长度的关系
LRH 本身不包含长度字段。IB 数据包的长度信息由物理层和链路层协议共同维护:物理层通过符号流控制帧边界,而 LRH 之后的 BTH 中的 PayloadLength 字段(32 bit)才真正指示数据载荷的长度。因此,交换机在转发时不需要知道数据包总长度,只需解析 LRH 即可完成转发决策,这进一步降低了处理延迟。
此外,LRH 中也没有校验和字段。LRH 的完整性由紧随其后的 ICRC(Invariant CRC) 和 VCRC(Variant CRC) 共同保障。其中 VCRC 覆盖 LRH 中所有可变字段(如 VL),而 ICRC 覆盖 LRH 中所有不变字段(如 DLID、SLID、PKEY)。这种设计允许交换机在重写 VL 字段后,无需重新计算整个数据包的 CRC,只需更新 VCRC 即可。
总结来说,LRH 是 IB 数据包中最关键的“路由信封”,它以极简的 12 字节结构,承载了子网内转发所需的全部信息。理解 LRH 的字段语义、交换机处理逻辑以及常见误区,是掌握 IB 网络运维和故障排查的基础。