4、RoCE协议栈:报文封装格式与版本演进
大家好,我是老张。今天我们来聊聊RoCE协议栈的核心——报文封装。说实话,很多刚接触RDMA的朋友,一看到报文格式就头大。其实没那么复杂,咱们一层层剥开来看。
4.1 RoCE的两种版本:v1和v2
RoCE从诞生到现在,主要有两个版本。我个人习惯把它们比作「两条不同的路」——都能到达目的地,但走法不一样。
| 特性 | RoCE v1 | RoCE v2 |
|---|---|---|
| 封装层 | 直接基于以太网类型 | 基于UDP封装 |
| 网络层 | 无(二层网络) | 有IP头(三层路由) |
| 适用场景 | 同一广播域内 | 跨网段、跨数据中心 |
| GRH支持 | 可选 | 可选 |
嗯,这里要注意:RoCE v1只能在同一个二层网络里跑。什么意思呢?就是你的服务器和存储设备必须在同一个VLAN里,不能跨路由器。我在项目里遇到过,有人把v1的流量硬要往三层交换机上送,结果丢包丢到怀疑人生。
4.2 RoCE v1报文封装格式
RoCE v1的封装,说白了就是在标准以太网帧里直接塞了个IB(InfiniBand)的报文。它的格式长这样:
+------------------+------------------+------------------+
| 以太网头 (14B) | GRH (40B) | IB Payload |
| (DMAC+SMAC+Type)| (全局路由头) | (数据段) |
+------------------+------------------+------------------+
| EtherType = 0x8915 | |
+-----------------------------------------+-----------------+
关键点在于以太网头里的EtherType字段,它被设置为0x8915。这个值就是RoCE v1的身份证。交换机看到这个值,就知道「哦,这是RDMA流量」。
GRH(Global Routing Header)是40字节的全局路由头,它包含了源和目标GID(全局标识符)。
避坑指南:我曾经在配置RoCE v1时,忘了检查交换机的EtherType过滤规则。结果流量全被当成未知协议丢弃了。后来排查了整整两天才发现——交换机默认不转发0x8915的帧。所以,记得在交换机上放行这个EtherType。
4.3 RoCE v2报文封装格式
RoCE v2就灵活多了。它把IB报文封装在UDP里,这样就能走三层网络了。格式如下:
+------------------+------------------+------------------+------------------+
| 以太网头 (14B) | IP头 (20B) | UDP头 (8B) | IB Payload |
| (DMAC+SMAC+Type)| (源/目标IP) | (端口: 4791) | (数据段) |
+------------------+------------------+------------------+------------------+
| EtherType = 0x0800 (IPv4) 或 0x86DD (IPv6) | |
+-------------------------------------------------------+-----------------+
你想想看,RoCE v2最大的变化是什么?
对,就是多了UDP头。UDP的目标端口固定为4791。这个端口号是IANA分配给RoCE v2的专用端口。有了UDP封装,路由器就能识别并转发这些报文了。
小技巧:我在实际部署中,习惯用tcpdump -i eth0 udp port 4791来抓取RoCE v2流量。这样能快速确认RDMA报文是否正常发出。如果抓不到包,先检查UDP端口是否被防火墙拦截了。
4.4 GRH(全局路由头)详解
GRH是RoCE协议里一个比较特殊的存在。它其实是从InfiniBand协议里继承过来的。说白了,GRH就是IB世界的「IP头」——它负责在InfiniBand网络中做路由寻址。
GRH的结构如下:
+--------+--------+--------+--------+
| 版本(4b)| 流量类(8b)| 流标签(20b) |
+--------+--------+--------+--------+
| 载荷长度(16b) | 下一头(8b) | 跳数限制(8b) |
+------------------+--------+--------+
| 源GID (128位) |
+------------------------------------+
| 目标GID (128位) |
+------------------------------------+
这里有个容易混淆的点:GRH在RoCE v1和v2中都是可选的。为什么?因为RoCE本身是跑在以太网上的,以太网有自己的MAC地址做二层寻址。GRH更多是为了兼容InfiniBand的生态。
注意:如果你的RoCE网络需要跨子网通信,或者使用了多路径路由,那么GRH就是必须的。我见过有人图省事,在跨网段场景下省略了GRH,结果RDMA连接死活建立不起来。后来加上GRH,问题立刻解决。
4.5 报文封装对比总结
为了让你看得更清楚,我画了一张对比图:
从这张图可以看得很清楚:
RoCE v1的报文结构更简单,但局限在二层网络。
RoCE v2虽然多了IP头和UDP头,但换来了跨网段通信的能力。说白了,这就是用「多一层封装」换「更大的灵活性」。
我的建议:新项目直接上RoCE v2。为什么?因为现在数据中心都在往Spine-Leaf架构演进,v1的二层限制太死。而且v2的UDP封装对ECMP(等价多路径)更友好,能充分利用带宽。我在最近三个数据中心项目里,全部用的RoCE v2,效果很好。
好了,关于RoCE的报文封装,今天就聊到这里。记住一句话:v1是二层直连,v2是三层路由。搞清楚了这一点,后面的PFC、ECN这些流控机制,理解起来就顺了。