Commit 73175c6d authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

nvme: process in-band authentication after connect



In-band authentication will now be processed after receiving appropriate
authreq flags in connect's response.  It's done as part of connecting a
qpair (i.e. under NVME_QPAIR_CONNECTING, w/o adding new states) to make
this process seamless to the transports.

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


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
parent fc8dece0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -90,6 +90,11 @@ nvme_fabric_qpair_authenticate_async(struct spdk_nvme_qpair *qpair)
		return -ENOKEY;
	}

	if (qpair->auth.flags & NVME_QPAIR_AUTH_FLAG_ASCR) {
		AUTH_ERRLOG(qpair, "secure channel concatentation is not supported\n");
		return -EINVAL;
	}

	status = calloc(1, sizeof(*qpair->poll_status));
	if (!status) {
		AUTH_ERRLOG(qpair, "failed to allocate poll status\n");
+54 −3
Original line number Diff line number Diff line
@@ -575,12 +575,14 @@ nvme_fabric_qpair_connect_async(struct spdk_nvme_qpair *qpair, uint32_t num_entr
				      spdk_get_ticks_hz() / SPDK_SEC_TO_USEC;
	}

	qpair->auth.flags = 0;
	qpair->connect_state = NVME_QPAIR_CONNECT_STATE_CONNECTING;
	qpair->poll_status = status;
	return 0;
}

int
nvme_fabric_qpair_connect_poll(struct spdk_nvme_qpair *qpair)
static int
_nvme_fabric_qpair_connect_poll(struct spdk_nvme_qpair *qpair)
{
	struct nvme_completion_poll_status *status;
	struct spdk_nvmf_fabric_connect_rsp *rsp;
@@ -614,11 +616,17 @@ nvme_fabric_qpair_connect_poll(struct spdk_nvme_qpair *qpair)
		goto finish;
	}

	if (nvme_qpair_is_admin_queue(qpair)) {
	rsp = (struct spdk_nvmf_fabric_connect_rsp *)&status->cpl;
	if (nvme_qpair_is_admin_queue(qpair)) {
		ctrlr->cntlid = rsp->status_code_specific.success.cntlid;
		SPDK_DEBUGLOG(nvme, "CNTLID 0x%04" PRIx16 "\n", ctrlr->cntlid);
	}
	if (rsp->status_code_specific.success.authreq.atr) {
		qpair->auth.flags |= NVME_QPAIR_AUTH_FLAG_ATR;
	}
	if (rsp->status_code_specific.success.authreq.ascr) {
		qpair->auth.flags |= NVME_QPAIR_AUTH_FLAG_ASCR;
	}
finish:
	qpair->poll_status = NULL;
	if (!status->timed_out) {
@@ -629,6 +637,49 @@ finish:
	return rc;
}

int
nvme_fabric_qpair_connect_poll(struct spdk_nvme_qpair *qpair)
{
	int rc;

	switch (qpair->connect_state) {
	case NVME_QPAIR_CONNECT_STATE_CONNECTING:
		rc = _nvme_fabric_qpair_connect_poll(qpair);
		if (rc != 0) {
			break;
		}
		if (qpair->auth.flags & (NVME_QPAIR_AUTH_FLAG_ATR | NVME_QPAIR_AUTH_FLAG_ASCR)) {
			rc = nvme_fabric_qpair_authenticate_async(qpair);
			if (rc == 0) {
				qpair->connect_state = NVME_QPAIR_CONNECT_STATE_AUTHENTICATING;
				rc = -EAGAIN;
			}
			break;
		}
		qpair->connect_state = NVME_QPAIR_CONNECT_STATE_CONNECTED;
		break;
	case NVME_QPAIR_CONNECT_STATE_AUTHENTICATING:
		rc = nvme_fabric_qpair_authenticate_poll(qpair);
		if (rc == 0) {
			qpair->connect_state = NVME_QPAIR_CONNECT_STATE_CONNECTED;
		}
		break;
	/* Once qpair is connected or a failure occurs, users mustn't call this function anymore */
	case NVME_QPAIR_CONNECT_STATE_CONNECTED:
	case NVME_QPAIR_CONNECT_STATE_FAILED:
	default:
		assert(0 && "invalid state");
		rc = -EINVAL;
		break;
	}

	if (rc != 0 && rc != -EAGAIN) {
		qpair->connect_state = NVME_QPAIR_CONNECT_STATE_FAILED;
	}

	return rc;
}

int
nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries)
{
+15 −0
Original line number Diff line number Diff line
@@ -410,6 +410,13 @@ enum nvme_qpair_state {
	NVME_QPAIR_DESTROYING,
};

enum nvme_qpair_connect_state {
	NVME_QPAIR_CONNECT_STATE_CONNECTING,
	NVME_QPAIR_CONNECT_STATE_AUTHENTICATING,
	NVME_QPAIR_CONNECT_STATE_CONNECTED,
	NVME_QPAIR_CONNECT_STATE_FAILED,
};

enum nvme_qpair_auth_state {
	NVME_QPAIR_AUTH_STATE_NEGOTIATE,
	NVME_QPAIR_AUTH_STATE_AWAIT_NEGOTIATE,
@@ -420,6 +427,11 @@ enum nvme_qpair_auth_state {
	NVME_QPAIR_AUTH_STATE_DONE,
};

/* Authentication transaction required (authreq.atr) */
#define NVME_QPAIR_AUTH_FLAG_ATR	(1 << 0)
/* Authentication and secure channel required (authreq.ascr) */
#define NVME_QPAIR_AUTH_FLAG_ASCR	(1 << 1)

struct nvme_auth {
	/* State of the authentication */
	enum nvme_qpair_auth_state	state;
@@ -427,6 +439,8 @@ struct nvme_auth {
	int				status;
	/* Transaction ID */
	uint16_t			tid;
	/* Flags */
	uint32_t			flags;
};

struct spdk_nvme_qpair {
@@ -494,6 +508,7 @@ struct spdk_nvme_qpair {
	/* Entries below here are not touched in the main I/O path. */

	struct nvme_completion_poll_status	*poll_status;
	enum nvme_qpair_connect_state		connect_state;

	/* List entry for spdk_nvme_ctrlr::active_io_qpairs */
	TAILQ_ENTRY(spdk_nvme_qpair)		tailq;
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ DEFINE_STUB(spdk_nvme_transport_id_adrfam_str, const char *,
	    (enum spdk_nvmf_adrfam adrfam), NULL);

DEFINE_STUB(nvme_ctrlr_process_init, int, (struct spdk_nvme_ctrlr *ctrlr), 0);
DEFINE_STUB(nvme_fabric_qpair_authenticate_async, int, (struct spdk_nvme_qpair *qpair), 0);
DEFINE_STUB(nvme_fabric_qpair_authenticate_poll, int, (struct spdk_nvme_qpair *qpair), 0);

static struct spdk_nvmf_fabric_connect_data g_nvmf_data;
static struct nvme_request *g_request;