Skip to content

Commit 2030abd

Browse files
larrystevenwisedledford
authored andcommitted
rxe: correctly calculate iCRC for unaligned payloads
If RoCE PDUs being sent or received contain pad bytes, then the iCRC is miscalculated, resulting in PDUs being emitted by RXE with an incorrect iCRC, as well as ingress PDUs being dropped due to erroneously detecting a bad iCRC in the PDU. The fix is to include the pad bytes, if any, in iCRC computations. Note: This bug has caused broken on-the-wire compatibility with actual hardware RoCE devices since the soft-RoCE driver was first put into the mainstream kernel. Fixing it will create an incompatibility with the original soft-RoCE devices, but is necessary to be compatible with real hardware devices. Fixes: 8700e3e ("Soft RoCE driver") Signed-off-by: Steve Wise <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Doug Ledford <[email protected]>
1 parent 71bbac6 commit 2030abd

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

drivers/infiniband/sw/rxe/rxe_recv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ void rxe_rcv(struct sk_buff *skb)
389389

390390
calc_icrc = rxe_icrc_hdr(pkt, skb);
391391
calc_icrc = rxe_crc32(rxe, calc_icrc, (u8 *)payload_addr(pkt),
392-
payload_size(pkt));
392+
payload_size(pkt) + bth_pad(pkt));
393393
calc_icrc = (__force u32)cpu_to_be32(~calc_icrc);
394394
if (unlikely(calc_icrc != pack_icrc)) {
395395
if (skb->protocol == htons(ETH_P_IPV6))

drivers/infiniband/sw/rxe/rxe_req.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,12 @@ static int fill_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
500500
if (err)
501501
return err;
502502
}
503+
if (bth_pad(pkt)) {
504+
u8 *pad = payload_addr(pkt) + paylen;
505+
506+
memset(pad, 0, bth_pad(pkt));
507+
crc = rxe_crc32(rxe, crc, pad, bth_pad(pkt));
508+
}
503509
}
504510
p = payload_addr(pkt) + paylen + bth_pad(pkt);
505511

drivers/infiniband/sw/rxe/rxe_resp.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,13 @@ static enum resp_states read_reply(struct rxe_qp *qp,
732732
if (err)
733733
pr_err("Failed copying memory\n");
734734

735+
if (bth_pad(&ack_pkt)) {
736+
struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
737+
u8 *pad = payload_addr(&ack_pkt) + payload;
738+
739+
memset(pad, 0, bth_pad(&ack_pkt));
740+
icrc = rxe_crc32(rxe, icrc, pad, bth_pad(&ack_pkt));
741+
}
735742
p = payload_addr(&ack_pkt) + payload + bth_pad(&ack_pkt);
736743
*p = ~icrc;
737744

0 commit comments

Comments
 (0)