nvmf/tcp: Check if In-capsule Data length and sgl data length are equal
In-capsule data length should be the same with the SGL data length. Signed-off-by: MengjinWu <mengjin.wu@intel.com> Change-Id: I7eefecb8baebb76850a48689907aff27a8946f98 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14602 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
8ed53eee32
commit
8d1c4f74d4
@ -2277,15 +2277,17 @@ nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req,
|
|||||||
struct spdk_nvme_sgl_descriptor *sgl;
|
struct spdk_nvme_sgl_descriptor *sgl;
|
||||||
struct spdk_nvmf_tcp_poll_group *tgroup;
|
struct spdk_nvmf_tcp_poll_group *tgroup;
|
||||||
enum spdk_nvme_tcp_term_req_fes fes;
|
enum spdk_nvme_tcp_term_req_fes fes;
|
||||||
|
struct nvme_tcp_pdu *pdu;
|
||||||
|
struct spdk_nvmf_tcp_qpair *tqpair;
|
||||||
uint32_t length, error_offset = 0;
|
uint32_t length, error_offset = 0;
|
||||||
|
|
||||||
cmd = &req->cmd->nvme_cmd;
|
cmd = &req->cmd->nvme_cmd;
|
||||||
sgl = &cmd->dptr.sgl1;
|
sgl = &cmd->dptr.sgl1;
|
||||||
|
|
||||||
length = sgl->unkeyed.length;
|
|
||||||
|
|
||||||
if (sgl->generic.type == SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK &&
|
if (sgl->generic.type == SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK &&
|
||||||
sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_TRANSPORT) {
|
sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_TRANSPORT) {
|
||||||
|
/* get request length from sgl */
|
||||||
|
length = sgl->unkeyed.length;
|
||||||
if (spdk_unlikely(length > transport->opts.max_io_size)) {
|
if (spdk_unlikely(length > transport->opts.max_io_size)) {
|
||||||
SPDK_ERRLOG("SGL length 0x%x exceeds max io size 0x%x\n",
|
SPDK_ERRLOG("SGL length 0x%x exceeds max io size 0x%x\n",
|
||||||
length, transport->opts.max_io_size);
|
length, transport->opts.max_io_size);
|
||||||
@ -2328,7 +2330,24 @@ nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req,
|
|||||||
sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET) {
|
sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET) {
|
||||||
uint64_t offset = sgl->address;
|
uint64_t offset = sgl->address;
|
||||||
uint32_t max_len = transport->opts.in_capsule_data_size;
|
uint32_t max_len = transport->opts.in_capsule_data_size;
|
||||||
|
|
||||||
assert(tcp_req->has_in_capsule_data);
|
assert(tcp_req->has_in_capsule_data);
|
||||||
|
/* Capsule Cmd with In-capsule Data should get data length from pdu header */
|
||||||
|
tqpair = tcp_req->pdu->qpair;
|
||||||
|
/* receiving pdu is not same with the pdu in tcp_req */
|
||||||
|
pdu = tqpair->pdu_in_progress;
|
||||||
|
length = pdu->hdr.common.plen - pdu->psh_len - sizeof(struct spdk_nvme_tcp_common_pdu_hdr);
|
||||||
|
if (tqpair->host_ddgst_enable) {
|
||||||
|
length -= SPDK_NVME_TCP_DIGEST_LEN;
|
||||||
|
}
|
||||||
|
/* This error is not defined in NVMe/TCP spec, take this error as fatal error */
|
||||||
|
if (spdk_unlikely(length != sgl->unkeyed.length)) {
|
||||||
|
SPDK_ERRLOG("In-Capsule Data length 0x%x is not equal to SGL data length 0x%x\n",
|
||||||
|
length, sgl->unkeyed.length);
|
||||||
|
fes = SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
|
||||||
|
error_offset = offsetof(struct spdk_nvme_tcp_common_pdu_hdr, plen);
|
||||||
|
goto fatal_err;
|
||||||
|
}
|
||||||
|
|
||||||
SPDK_DEBUGLOG(nvmf_tcp, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n",
|
SPDK_DEBUGLOG(nvmf_tcp, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n",
|
||||||
offset, length);
|
offset, length);
|
||||||
|
Loading…
Reference in New Issue
Block a user