3. RoCE v2协议深度解析:UDP封装格式、GID与MAC地址映射、RoCE v2报文结构、RoCE v2与RoCE v1差异、RoCE v2路由特性

好,咱们进入RoCE v2的核心部分。说实话,v2版本才是真正让RDMA走出数据中心机房、走向大规模组网的关键。我记得2015年我第一次在跨机柜场景里用RoCE v1,那个痛苦啊——二层网络一跨三层就歇菜。后来v2一出来,我立马就切过去了。

3.1 RoCE v2的UDP封装格式

RoCE v2最大的变化,就是把v1用的InfiniBand网络层封装,换成了UDP封装。你想想看,UDP是什么?是IP网络里的“万能胶水”。

具体来说,RoCE v2的报文长这样:

+------------------+------------------+------------------+------------------+
|   Ethernet Header |   IP Header      |   UDP Header     |   BTH + Payload  |
|   (14 bytes)      |   (20 bytes)     |   (8 bytes)      |   (可变长度)      |
+------------------+------------------+------------------+------------------+

UDP头的关键字段:

  • 源端口:由RDMA网卡动态分配,用于流哈希和负载均衡
  • 目的端口:固定为4791(IANA分配的RoCE端口号)
  • UDP长度:包含UDP头和数据的总长度
  • 校验和:建议启用,但很多高性能场景会关闭以节省CPU

核心要点:UDP封装让RoCE v2可以穿越三层网络。说白了,只要IP能到的地方,RoCE v2就能到。

我的经验:UDP源端口一定要随机化。我曾经遇到过一个案例,所有流都用同一个源端口,结果在Leaf交换机上哈希不均,一条链路跑满,另一条空着。后来改成随机端口,流量瞬间均衡了。

3.2 GID与MAC地址映射

GID(Global Identifier)是RoCE网络里每个端口的“身份证”。在RoCE v2里,GID其实就是IPv6地址。嗯,这里要注意,不是IPv4,是IPv6。

GID的构成:

GID = 64位前缀 + 64位接口标识符
前缀:通常是fe80::/10(链路本地)或2001::/16(全局单播)
接口标识符:基于MAC地址生成(EUI-64格式)

MAC地址到GID的映射规则:

  • 取MAC地址的前24位(OUI部分)
  • 插入FF:FE(EUI-64的固定模式)
  • 取MAC地址的后24位
  • 翻转第7位(U/L位)

举个例子:

MAC地址:00:1a:2b:3c:4d:5e
GID接口标识符:021a:2bff:fe3c:4d5e

避坑指南:我曾经在配置RoCE v2时,发现两台服务器死活ping不通RDMA。查了半天,原来是GID的接口标识符算错了。MAC地址的U/L位翻转这个细节,很多人会忽略。记住:第7位要翻转!

3.3 RoCE v2报文结构

RoCE v2的报文结构,从外到内分四层:

  1. L2层(以太网头):源MAC、目的MAC、VLAN(可选)、EtherType(0x0800 for IPv4 或 0x86DD for IPv6)
  2. L3层(IP头):源IP、目的IP、协议号(17 for UDP)、DSCP(用于PFC优先级标记)
  3. L4层(UDP头):源端口、目的端口(4791)、长度、校验和
  4. RoCE载荷:BTH(Base Transport Header)+ 其他传输头 + 数据

BTH的结构:

+--------+--------+--------+--------+
| OpCode |  SE    |  M     | PadCnt |
| (8bit) | (1bit) | (1bit) | (6bit) |
+--------+--------+--------+--------+
|          PSN (24bit)              |
+-----------------------------------+
|          LKey (32bit)             |
+-----------------------------------+
|          DMA地址 (64bit)           |
+-----------------------------------+
|         数据 (可变长度)            |
+-----------------------------------+

OpCode定义了操作类型:

  • 0x00:Send(发送)
  • 0x01:Write(写)
  • 0x02:Read(读)
  • 0x03:Atomic(原子操作)
  • 0x04-0x07:ACK(确认)

关键点:PSN(Packet Sequence Number)是RoCE的可靠性基础。每个报文都有唯一的PSN,接收端靠它来检测丢包和乱序。

3.4 RoCE v2与RoCE v1差异

我直接列个表,对比一目了然:

特性 RoCE v1 RoCE v2
网络层封装 InfiniBand GRH(40字节) UDP/IP(28字节)
路由能力 仅限二层(MAC层) 三层路由(IP层)
GID格式 128位InfiniBand GID IPv6地址
拥塞控制 无原生支持 支持ECN(显式拥塞通知)
多路径 不支持 支持(基于UDP源端口哈希)
兼容性 仅InfiniBand交换机 标准以太网交换机

说白了,v1是InfiniBand的“私生子”,只能在IB网络里玩。v2才是真正的“以太网亲儿子”,能跑在任何标准IP网络上。

我的建议:新项目直接上RoCE v2。v1已经基本被淘汰了,除非你还在维护老旧的InfiniBand设备。我2018年之后就没再见过新部署的v1网络了。

3.5 RoCE v2路由特性

RoCE v2的路由特性,是它最大的卖点。为什么?因为有了IP路由,RDMA就能跨子网、跨数据中心了。

核心路由机制:

  • 基于IP路由:RoCE v2报文携带源/目的IP地址,标准IP路由器可以直接转发
  • ECMP负载均衡:路由器根据UDP源端口做哈希,实现多路径负载分担
  • PFC优先级映射:DSCP字段标记优先级,配合PFC实现无损传输
  • ECN拥塞标记:交换机在拥塞时标记ECN,发送端主动降速

路由场景举例:

场景1:同子网通信
Server A (10.0.1.1) → 交换机 → Server B (10.0.1.2)
不需要路由,直接二层转发

场景2:跨子网通信
Server A (10.0.1.1) → 路由器 → Server B (10.0.2.1)
需要三层路由,UDP报文被正常转发

避坑指南:跨子网RoCE v2一定要确认中间路由器支持ECN和PFC。我曾经遇到一个项目,路由器不支持ECN,结果跨子网时拥塞控制失效,性能直接掉到原来的三分之一。后来换了支持DCB(数据中心桥接)的路由器才解决。

还有一个容易被忽略的点:MTU。RoCE v2的UDP封装增加了28字节开销(IP头20字节+UDP头8字节)。如果你的网络MTU是1500,那RoCE v2的有效载荷最大只有1472字节。我建议把MTU设成9000(巨型帧),这样RoCE v2能发挥最大性能。

总结一下:RoCE v2通过UDP封装,把RDMA从二层网络解放到了三层网络。GID就是IPv6地址,MAC到GID的映射有固定规则。报文结构分四层,BTH是核心。相比v1,v2支持路由、ECN、多路径,是真正的数据中心级方案。

RoCE v2协议核心逻辑图 应用层(RDMA Verbs) 传输层(BTH + 其他传输头) UDP封装(源端口随机 + 目的端口4791) IP层(IPv4/IPv6 + DSCP标记) 以太网层(MAC地址 + VLAN + PFC) 关键特性 • GID = IPv6地址 • MAC → GID映射规则 • PSN序列号 • ECMP负载均衡 • ECN拥塞控制 • 三层路由能力 • 源端口随机化

最后说一句:RoCE v2的UDP封装看似简单,但每个字段都有它的设计意图。源端口随机化是为了负载均衡,DSCP标记是为了QoS,ECN是为了拥塞控制。这些细节,在实际部署中一个都不能少。

专注资料整理