格式如下:
wireshark抓包,soft-roce(基于rocev2实现的)格式如下:
其实这里看着有点奇怪,ICRC是跟在Payload头后面的,不知道为什么抓包看到的却是在BTH头后面的,还有就是看不到FCS??
其中BTH头的格式有以下字段:
BTH长度是12B。
opcode(1B):0-4bit表示操作方式,比如上面是RDMA WRITE,5-7表示qp的类型,比如上面是rc类型,根据opcode的组合,可能还会有一些额外的头部跟在BTH后面,比如上面跟了一个RETH头部。
Solicited Event(1bit):参考SE描述
MigReq(1bit):
Pad Count(2bit):数据包增加的额外长度,比如发送的包长度是3,那么为了4字节对齐,pad count的值就是1.
Header Version(4bit):该包的头部版本号?
Partition Key(2B):参考P_Key描述
Reserved(1B):预留
Destination Queue Pair(3B):目的端的qp num
Acknowledge Request:(1b)表示对端是否需要回复一个ack包
Reserved(7b):预留
Packet Sequence Number(3B):该包的序列号
在soft-roce里。对bth赋值的函数在
rxe_req.c
init_req_packet函数里,
init_req_packet -> bth_init
pad = (-payload) & 0x3;
rxe_hdr.h
static inline void bth_init(struct rxe_pkt_info *pkt, u8 opcode, int se,
int mig, int pad, u16 pkey, u32 qpn, int ack_req,
u32 psn)
{
struct rxe_bth *bth = (struct rxe_bth *)(pkt->hdr + pkt->offset);
bth->opcode = opcode;
bth->flags = (pad << 4) & BTH_PAD_MASK;
if (se)
bth->flags |= BTH_SE_MASK;
if (mig)
bth->flags |= BTH_MIG_MASK;
bth->pkey = cpu_to_be16(pkey);
bth->qpn = cpu_to_be32(qpn & BTH_QPN_MASK);
psn &= BTH_PSN_MASK;
if (ack_req)
psn |= BTH_ACK_MASK;
bth->apsn = cpu_to_be32(psn);
}
ICRC(4B)
计算方式如下:
crc的计算可以先了解此贴:https://blog.csdn.net/qq_38158479/article/details/102859774
待完善。。
其余的一些额外扩展头部总结:
比如存在于rdma write方式中的RETH头部,格式如下:
RETH(16B):
VA(8B):表明数据包要存放的虚拟起始地址
r_key(4B):表明该虚拟地址的访问权限
dma length(4B):该包的长度
还有的像ack包的AETH,格式如下:
AETH(4B):
Syndrome(1B)
由Reserved+OpCode+Credit Count组成。
MSN(3B)
等等。。。根据BTH头部的opcode值还会有其它的额外开展头部,先不一一列举了,后续见到时再进行总结。
参考:https://blog.csdn.net/u014114310/article/details/118074628