没有真实RDMA网卡也能学本文手把手教你用两台VMware Ubuntu虚拟机搭建Soft-RoCE模拟RoCEv2环境完整运行ib_send_bw带宽测试并基于Wireshark抓包深入拆解RDMA报文交互全过程。从ARP广播、TCP控制面建连到RC Send大消息拆包First→Middle→Last、ACK确认机制再到AETH流控信用值、PSN序列号、QP状态机——一文讲透RDMA可靠连接RC的数据面与控制面交互原理。适合网络工程师、存储开发、AI基础设施从业者入门RDMA技术栈。关键词RDMA、RoCEv2、Soft-RoCE、ib_send_bw、perftest、Wireshark抓包、RC可靠连接、QP状态机、BTH、AETH、VMware Ubuntu、RDMA原理、零拷贝网络1、RDMA测试环境准备1两台 VMNode-A192.168.95.128网卡 ens33主机名 node-aNode-B192.168.95.130网卡 ens33主机名 node-b已加载rdma_rxe已用rdma link add rxe_0 type rxe netdev ens33绑定业务网卡已装rdma-core / ibverbs-utils / perftest等 RDMA 软件栈普通 IP 已互 ping 通UDP 4791 未屏蔽2验收三条命令# 两端rdma link show# 期望link rxe_0/1 state ACTIVE physical_state LINK_UP netdev ens33ibv_devinfo -d rxe_0# 期望 port 1 state PORT_ACTIVElink_layer EthernetSoft-RoCE 常 active_mtu1024 防火墙放 RoCEv2 数据面 sudo ufw allow 4791/udp2、ib_send_bw测试结果1服务端 Node-Aib_send_bw -d rxe_0 -x 2 --report_gbits客户端 Node-Bib_send_bw -d rxe_0 -x 2 --report_gbits 192.168.95.1282测试结果分析从测试结果可以看到服务端只起监听、post recv收不主动发业务数据ib_send_bw -d rxe_0 -x 2 ...客户端连服务端、post send发测“客户端→服务端”的 Send 带宽ib_send_bw -d rxe_0 -x 2 ... 服务端IPperftest 官方对 send_bw 的描述就是 server 收、client 发算吞吐RC 模式下服务端也要 poll CQ 收完成但业务数据方向默认是客户端→服务端。 默认 RC、默认单向要双向加 -bbidirectional。3ib_send_bw是否需要CPU参与Send 不像 Write/Read 那样只靠 RKey 写远端内存它要求客户端 SQ 里 post send WQE服务端 RQ 里提前 post recv WQE数据到对端后匹配 recv buffer再出 CQE。两端 CPU 都要参与发端发、收端收poll所以叫双边但“双边”不等于“双向”默认仍只发一个方向。4、测试参数解读关键字段深度解读1. local address / remote address中的 GID格式254:128:00:00:00:00:00:00:XX:XX:XX:XX:XX:XX:XX:XX这是IPv6格式的 RoCEv2 GID前 8 字节固定为 fe80::链路本地地址前缀后 8 字节由 MAC 地址或 IPv4 地址转换而来。虽然你用的是 IPv4 地址192.168.95.128但 RoCEv2 的 GID 仍以 IPv6 格式呈现Wireshark 中也会显示为 fe80::...。-x 2 指定使用 IPv4 类型的 GID index 2所以实际通信基于 IPv4但 GID 本身是 IPv6 格式。2. LID 0000LIDLocal Identifier是 InfiniBand 子网内的 16 位地址用于 IB 模式寻址。Soft-RoCE 运行在以太网上没有 IB 子网管理器因此 LID 始终为 0。真机 IB 网络中 LID 非零RoCE 环境下 LID 也为 0。3. QPN 0x0011QP 编号范围 0x0001~0xFFFF。两端 QPN 恰好相同0x0011这是巧合不影响通信。每个 QP 唯一标识一条连接。4. PSNPacket Sequence Number初始 PSN 随机生成之后每发送一个包递增。服务端 PSN0x1d9c33客户端 PSN0xf6a92d两者独立。RC 模式下接收端通过 PSN 检测丢包和乱序并触发重传。5、抓包深入分析RDMA通信原理和交互过程1Ib_send总共发送1000次数据每次数据量64KB由于MTU是1024B所以64KB的数据块会拆分成64个RDMA报文进行发送。2以下是报文交互抓包截图共52849个RDMA报文1~6ARP广播报文7~37RDMA控制面报文TCP建链报文38~52837RDMA数据发送报文RDMA报文52838~52849RDMA控制面报文TCP断链报文1.前 6个 ARP广播报文原因虚拟机网卡MAC 地址为 VMware_c0:00:08在发起通信前需要知道目标 IP192.168.95.27通常是网关或同网段测试对端的 MAC 地址。作用通过广播 ARP RequestWho has 192.168.95.27 Tell 192.168.95.1进行地址解析这是以太网通信的标准前置动作。2.第 7到 37个 TCP报文原因perftest 工具包含 ib_send_bw在默认情况下不使用RDMA CM除非加了 -R 参数而是自己开一条普通的TCP Socket控制连接来进行带外握手。作用RDMA 的可靠连接RC在真正发数据前两端必须交换核心连接参数包括双方的QP号QPN、起始包序列号PSN、全局标识符GID、内存密钥RKey和缓冲区地址等。TCP 连接图中使用端口 18515就是用来完成这个“建连协商”的。细节图中 7-9 是 TCP 三次握手10-37 是双方通过 TCP 发送协商参数包含 PSH 数据标志最后通过 TCP 四次挥手或测试结束后的断开关闭控制连接。3.第 38个报文开始是 RC Send报文原因当 TCP 控制面完成参数交换并将 QP队列对状态机切换到RTSReady To Send就绪发送态​ 后真正的 RDMA 数据面传输才开始。特征此时数据完全绕过内核 TCP/IP 协议栈由网卡硬件直接封装成RoCEv2报文UDP 端口 4791。图中显示为 RC Send First 和 RC Send Middle这就是客户端向服务端单向发送的 RDMA 业务测试数据。4.大消息拆包First Middle... Last现象第38个是 RC Send First第39-100个是 RC Send Middle第101个是 RC Send Last。原因ib_send_bw 默认会发送一条较大的测试消息例如你之前提到的 64KB。而以太网有 MTU最大传输单元限制例如 1024 或 4096 字节。网卡硬件会自动将这条大消息拆分成多个小包进行发送。字段含义First拆分的第一个包。它除了携带数据载荷外还包含关键的 RETHRDMA 扩展传输头里面记录了远程内存地址、RKey 等信息如果是 Write 操作。Middle拆分的中间数据分片。只携带纯数据载荷没有 RETH 头。Last拆分的最后一个包标志着这条大消息传输结束。PSN递增在这个过程中每个包的 BTH 头部里都有一个PSN包序列号​ 在严格递增模 2^24用于保证收发顺序和丢包检测。5.可靠确认RC Acknowledge现象第102个是 RC Acknowledge 报文。原因RC可靠连接模式类似于 TCP需要接收端给发送端回确认信。接收端网卡服务端在成功按序收到这一整条消息从 First 到 LastPSN 连续无缺失后会向发送端网卡客户端回复一个 ACK 报文。机制这个 ACK 报文里包含了 AETH确认扩展传输头告诉发送端“我已经成功收到了截止到某个 PSN 的所有数据”。如果中间丢了包接收端会回 NAK触发发送端的 Go-Back-N 重传机制。6.触发确认AckReq标志细节你可能在 Wireshark 里展开第101个 RC Send Last 包会发现 BTH 头部里有一个AckReq请求确认​ 标志位被置 1。作用发送端在发送关键包通常是消息的最后一个包或者按一定窗口间隔时会要求接收端必须立刻回复 ACK。这就是为什么 ACK 紧跟在 Last 包之后立刻出现的原因。7.下一条消息的传输循环现象第103个开始又是 RC Send First。原因ib_send_bw 是一个带宽测试工具它会连续不断地发送多条测试消息。当第一条消息完成传输并确认后网卡立刻开始拆包并发送第二条测试消息周而复始。8.第 52038~52045个报文TCP控制连接断开背景正如之前提到的ib_send_bw 在测试前会通过 TCP 端口如 18515建立一条控制连接用来交换 QP 号、PSN、RKey 等核心参数。交互过程当 RDMA 数据测试完成第 52037 个报文是最后一条消息的 ACK后测试工具perftest正常退出TCP 控制连接也随之关闭52038-52040.130客户端向 .128服务端发送带有 [FIN, PSH, ACK] 的报文。其中 FIN 表示发送方数据已发送完毕请求关闭连接PSH 提示将剩余数据立刻交给应用层ACK 确认收到之前的数据。52041-52042.128服务端回复 [ACK] 确认客户端的断开请求并也发送了自己的 [FIN, PSH, ACK] 请求关闭反向连接。52043.130 回复 [ACK] 确认服务端的 FIN。52044-52045.130 又发送了 [RST, ACK]。RST 表示强制重置/断开连接。在 TCP 中当程序快速退出、端口关闭或连接异常时常会发送 RST 来立即释放连接资源跳过标准的 TIME_WAIT 等待状态。6、RDMA报文解析1RC Send First报文重点看一下UDP头和BTH头aUDP头端口源端口 57236随机高位端口目的端口 4791。4791是 IANA分配给 RoCEv2的官方固定端口Wireshark 借此识别出其上层协议为 InfiniBand/RDMA。bBTH头BTH 是 RDMA 报文必须携带的 12 字节基础头部核心字段如下Opcode: Reliable Connection (RC) - SEND First (0)RC可靠连接表示这条连接是点对点、保序且可靠的需要接收端回 ACK 确认。SEND First表示这是双边Send操作大消息拆分之后的第一个分片包。它携带了消息的初始数据后续会跟随 SEND Middle 和 SEND Last 包。Destination Queue Pair (QP): 0x000011目的端队列对号。RDMA 通信通过 QP 进行数据被投递到对端的这个特定 QP 中。Packet Sequence Number (PSN): 858106包序列号。RC 服务用 PSN 来严格保证包的顺序交付和丢包检测重传。Partition Key (PKey): 65535分区键默认全权限分区。Acknowledge Request: False当前首包未强制请求立即确认通常会在最后的 SEND Last 包中将该位置为 True要求对端回复 ACK。RC Send Middle报文除了PSN编号增长其他字段与RC Send First相同RC Send Last的Acknowledge Request字段为true。2RC Acknowledge报文aBTH头Opcode: Reliable Connection (RC) - Acknowledge (17)明确标识这是 RC 服务的 ACK 报文。Destination Queue Pair: 0x000011确认报文发往发送端的 QP 11。Packet Sequence Number (PSN): 858169核心字段。这个 PSN 对应发送端最后发出的那个包的序列号。接收端通过此字段告知发送端“截止到 858169 号包的数据我已全部按序收到”。b确认扩展头AETHAETH 是 ACK 报文特有的扩展头用于传达确认状态和流控信息Syndrome: 31, Ack确认状态码。31 表示正常的正确认ACK。如果是丢包或错误这里会显示 NAK 及相关错误码。Credit Count: 31流控信用值。相当于接收端告诉发送端“我的接收缓冲区还剩 31 个包的容量你可以继续发”。这是 RC 可靠传输和流控机制的关键部分。Message Sequence Number: 1消息序列号用于标记确认的是第几条消息。