Commit 67ab645c authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

nvmf/auth: send AUTH_failure1 message



This message is sent when an error is encountered during the
authentication.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ic6bb1277b61d393f3fb31c9e95afa98bef75e986
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/22662


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Community-CI: Mellanox Build Bot
parent c54a29d8
Loading
Loading
Loading
Loading
+45 −2
Original line number Diff line number Diff line
@@ -315,9 +315,45 @@ nvmf_auth_send_exec(struct spdk_nvmf_request *req)
	}
}

static void
nvmf_auth_recv_complete(struct spdk_nvmf_request *req, uint32_t length)
{
	assert(req->cmd->nvmf_cmd.fctype == SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV);
	req->length = length;
	nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
}

static void
nvmf_auth_recv_failure1(struct spdk_nvmf_request *req, int fail_reason)
{
	struct spdk_nvmf_qpair *qpair = req->qpair;
	struct spdk_nvmf_qpair_auth *auth = qpair->auth;
	struct spdk_nvmf_auth_failure *failure;

	failure = nvmf_auth_get_message(req, sizeof(*failure));
	if (failure == NULL) {
		nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
					   SPDK_NVME_SC_INVALID_FIELD, 1);
		nvmf_auth_disconnect_qpair(qpair);
		return;
	}

	failure->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
	failure->auth_id = SPDK_NVMF_AUTH_ID_FAILURE1;
	failure->t_id = auth->tid;
	failure->rc = SPDK_NVMF_AUTH_FAILURE;
	failure->rce = fail_reason;

	nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_FAILURE1);
	nvmf_auth_recv_complete(req, sizeof(*failure));
	nvmf_auth_disconnect_qpair(qpair);
}

static void
nvmf_auth_recv_exec(struct spdk_nvmf_request *req)
{
	struct spdk_nvmf_qpair *qpair = req->qpair;
	struct spdk_nvmf_qpair_auth *auth = qpair->auth;
	struct spdk_nvmf_fabric_auth_recv_cmd *cmd = &req->cmd->auth_recv_cmd;
	int rc;

@@ -328,8 +364,15 @@ nvmf_auth_recv_exec(struct spdk_nvmf_request *req)
		return;
	}

	nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
				   SPDK_NVME_SC_INVALID_OPCODE, 1);
	spdk_iov_memset(req->iov, req->iovcnt, 0);
	switch (auth->state) {
	case NVMF_QPAIR_AUTH_FAILURE1:
		nvmf_auth_recv_failure1(req, auth->fail_reason);
		break;
	default:
		nvmf_auth_recv_failure1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
		break;
	}
}

int
+81 −0
Original line number Diff line number Diff line
@@ -497,6 +497,86 @@ test_auth_timeout(void)
	MOCK_SET(spdk_get_ticks, 0);
}

static void
test_auth_failure1(void)
{
	union nvmf_c2h_msg rsp = {};
	struct spdk_nvmf_subsystem subsys = {};
	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
	struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
		.fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
	};
	struct spdk_nvme_cpl *cpl = &rsp.nvme_cpl;
	struct spdk_nvmf_qpair_auth *auth;
	struct spdk_nvmf_auth_failure *msg;
	uint8_t msgbuf[sizeof(*msg)];
	int rc;

	msg = (void *)msgbuf;
	rc = nvmf_qpair_auth_init(&qpair);
	SPDK_CU_ASSERT_FATAL(rc == 0);
	auth = qpair.auth;
	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;

	/* Check failure1 message fields */
	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
	g_req_completed = false;
	auth->state = NVMF_QPAIR_AUTH_FAILURE1;
	auth->fail_reason = SPDK_NVMF_AUTH_FAILED;
	auth->tid = 8;

	nvmf_auth_recv_exec(&req);
	CU_ASSERT(g_req_completed);
	CU_ASSERT_EQUAL(cpl->status.sct, 0);
	CU_ASSERT_EQUAL(cpl->status.sc, 0);
	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
	CU_ASSERT_EQUAL(msg->t_id, 8);
	CU_ASSERT_EQUAL(msg->rc, SPDK_NVMF_AUTH_FAILURE);
	CU_ASSERT_EQUAL(msg->rce, SPDK_NVMF_AUTH_FAILED);
	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;

	/* Do a receive while expecting an auth send command */
	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
	g_req_completed = false;
	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
	auth->fail_reason = 0;

	nvmf_auth_recv_exec(&req);
	CU_ASSERT(g_req_completed);
	CU_ASSERT_EQUAL(cpl->status.sct, 0);
	CU_ASSERT_EQUAL(cpl->status.sc, 0);
	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
	CU_ASSERT_EQUAL(msg->t_id, 8);
	CU_ASSERT_EQUAL(msg->rc, SPDK_NVMF_AUTH_FAILURE);
	CU_ASSERT_EQUAL(msg->rce, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;

	/* Do a receive but specify a buffer that's too small */
	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
	g_req_completed = false;
	auth->state = NVMF_QPAIR_AUTH_FAILURE1;
	auth->fail_reason = SPDK_NVMF_AUTH_FAILED;
	req.iov[0].iov_len = cmd.al = req.length = sizeof(*msg) - 1;

	nvmf_auth_recv_exec(&req);
	CU_ASSERT(g_req_completed);
	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
	req.iov[0].iov_len = cmd.al = req.length = sizeof(*msg);

	nvmf_qpair_auth_destroy(&qpair);
}

int
main(int argc, char **argv)
{
@@ -508,6 +588,7 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, test_auth_send_recv_error);
	CU_ADD_TEST(suite, test_auth_negotiate);
	CU_ADD_TEST(suite, test_auth_timeout);
	CU_ADD_TEST(suite, test_auth_failure1);

	allocate_threads(1);
	set_thread(0);