Commit 4ddd77b2 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

nvme: add methods for forcing (re)authentication



These two functions can be used to force IO and admin qpairs to
authenticate.  They can be called at any time while a qpair is active.
If it has already been connected and authenticated, it'll be forced to
reauthenticate.  If the connection is still being established, these
functions will only register the callback and let the regular
authentication flow proceed.

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


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 ffd098cf
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -2107,6 +2107,41 @@ void spdk_nvme_qpair_set_abort_dnr(struct spdk_nvme_qpair *qpair, bool dnr);
 */
bool spdk_nvme_qpair_is_connected(struct spdk_nvme_qpair *qpair);

typedef void (*spdk_nvme_authenticate_cb)(void *ctx, int status);

/**
 * Force a qpair to authenticate.  As part of initialization, qpairs are authenticated automatically
 * if the controller is configured with DH-HMAC-CHAP keys.  However, this function can be used to
 * force authentication after a connection has already been established.
 *
 * This function doesn't disconnect the qpair if the authentication is successful.
 *
 * \param qpair The qpair to authenticate.
 * \param cb_fn Callback to be executed after the authentication is done.
 * \param cb_ctx Context passed to `cb_fn`.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_nvme_qpair_authenticate(struct spdk_nvme_qpair *qpair,
				 spdk_nvme_authenticate_cb cb_fn, void *cb_ctx);

/**
 * Force authentication on the admin qpair of a controller.  As part of initialization, the admin
 * qpair is authenticated automatically if the controller is configured with DH-HMAC-CHAP keys.
 * However, this function can be used to force authentication after a connection has already been
 * established.
 *
 * This function doesn't disconnect the admin qpair if the authentication is successful.
 *
 * \param ctrlr Controller to authenticate.
 * \param cb_fn Callback to be executed after the authentication is done.
 * \param cb_ctx Context passed to `cb_fn`.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_nvme_ctrlr_authenticate(struct spdk_nvme_ctrlr *ctrlr,
				 spdk_nvme_authenticate_cb cb_fn, void *cb_ctx);

/**
 * Send the given admin command to the NVMe controller.
 *
@@ -4459,6 +4494,8 @@ struct spdk_nvme_transport_ops {

	int (*qpair_submit_request)(struct spdk_nvme_qpair *qpair, struct nvme_request *req);

	int (*qpair_authenticate)(struct spdk_nvme_qpair *qpair);

	int32_t (*qpair_process_completions)(struct spdk_nvme_qpair *qpair, uint32_t max_completions);

	int (*qpair_iterate_requests)(struct spdk_nvme_qpair *qpair,
+2 −2
Original line number Diff line number Diff line
@@ -6,8 +6,8 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 13
SO_MINOR := 1
SO_VER := 14
SO_MINOR := 0

C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_fabric.c nvme_ns_cmd.c \
	nvme_ns.c nvme_pcie_common.c nvme_pcie.c nvme_qpair.c nvme.c \
+30 −0
Original line number Diff line number Diff line
@@ -1192,6 +1192,10 @@ nvme_fabric_qpair_authenticate_poll(struct spdk_nvme_qpair *qpair)
				spdk_free(status->dma_data);
				free(status);
			}
			if (auth->cb_fn != NULL) {
				auth->cb_fn(auth->cb_ctx, auth->status);
				auth->cb_fn = NULL;
			}
			return auth->status;
		default:
			assert(0 && "invalid state");
@@ -1247,6 +1251,32 @@ nvme_fabric_qpair_authenticate_async(struct spdk_nvme_qpair *qpair)
	rc = nvme_fabric_qpair_authenticate_poll(qpair);
	return rc != -EAGAIN ? rc : 0;
}

int
spdk_nvme_qpair_authenticate(struct spdk_nvme_qpair *qpair,
			     spdk_nvme_authenticate_cb cb_fn, void *cb_ctx)
{
	struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;
	int rc;

	if (qpair->auth.cb_fn != NULL) {
		SPDK_ERRLOG("authentication already in-progress\n");
		return -EALREADY;
	}

	if (ctrlr->opts.dhchap_key == NULL) {
		SPDK_ERRLOG("missing DH-HMAC-CHAP key\n");
		return -ENOKEY;
	}

	rc = nvme_transport_qpair_authenticate(qpair);
	if (rc == 0) {
		qpair->auth.cb_fn = cb_fn;
		qpair->auth.cb_ctx = cb_ctx;
	}

	return rc;
}
#endif /* SPDK_CONFIG_EVP_MAC */

SPDK_LOG_REGISTER_COMPONENT(nvme_auth)
+12 −0
Original line number Diff line number Diff line
@@ -604,6 +604,11 @@ spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair)
		return 0;
	}

	if (qpair->auth.cb_fn != NULL) {
		qpair->auth.cb_fn(qpair->auth.cb_ctx, -ECANCELED);
		qpair->auth.cb_fn = NULL;
	}

	qpair->destroy_in_progress = 1;

	nvme_transport_ctrlr_disconnect_qpair(ctrlr, qpair);
@@ -5506,3 +5511,10 @@ spdk_nvme_ctrlr_get_memory_domains(const struct spdk_nvme_ctrlr *ctrlr,
{
	return nvme_transport_ctrlr_get_memory_domains(ctrlr, domains, array_size);
}

int
spdk_nvme_ctrlr_authenticate(struct spdk_nvme_ctrlr *ctrlr,
			     spdk_nvme_authenticate_cb cb_fn, void *cb_ctx)
{
	return spdk_nvme_qpair_authenticate(ctrlr->adminq, cb_fn, cb_ctx);
}
+1 −1
Original line number Diff line number Diff line
@@ -642,7 +642,7 @@ nvme_fabric_qpair_auth_required(struct spdk_nvme_qpair *qpair)
	struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;

	return qpair->auth.flags & (NVME_QPAIR_AUTH_FLAG_ATR | NVME_QPAIR_AUTH_FLAG_ASCR) ||
	       ctrlr->opts.dhchap_ctrlr_key != NULL;
	       ctrlr->opts.dhchap_ctrlr_key != NULL || qpair->auth.cb_fn != NULL;
}

int
Loading