From 5088a8930dc154f2267c6d1ebce4274af158d287 Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Tue, 31 May 2022 16:56:37 +0200 Subject: [PATCH] nvme/tcp: check PDU type before checking padding Not all PDUs that have can have data can also have padding - e.g. C2HTermReq has data, but cannot have padding and the PDO field should be reserved. Therefore, for these PDUs the data starts exactly at the end of the header (and its digest, if present) and we shouldn't be using PDO to calculate its offset. This fixes handling for the C2HTermReq PDUs, as it used to be broken and usually (if target set PDO=0) resulted in an overflow when calculating psh_len. Signed-off-by: Konrad Sztyber Change-Id: Ia2976517019469ba375eb32d22739372211eff35 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12846 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Aleksey Marchuk --- include/spdk_internal/nvme_tcp.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/include/spdk_internal/nvme_tcp.h b/include/spdk_internal/nvme_tcp.h index 80a458b02..c0e7b32ad 100644 --- a/include/spdk_internal/nvme_tcp.h +++ b/include/spdk_internal/nvme_tcp.h @@ -558,10 +558,19 @@ nvme_tcp_pdu_calc_psh_len(struct nvme_tcp_pdu *pdu, bool hdgst_enable) psh_len += SPDK_NVME_TCP_DIGEST_LEN; } if (pdu->hdr.common.plen > psh_len) { - pdo = pdu->hdr.common.pdo; - padding_len = pdo - psh_len; - if (padding_len > 0) { - psh_len = pdo; + switch (pdu->hdr.common.pdu_type) { + case SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD: + case SPDK_NVME_TCP_PDU_TYPE_H2C_DATA: + case SPDK_NVME_TCP_PDU_TYPE_C2H_DATA: + pdo = pdu->hdr.common.pdo; + padding_len = pdo - psh_len; + if (padding_len > 0) { + psh_len = pdo; + } + break; + default: + /* There is no padding for other PDU types */ + break; } }