Commit 686ce435 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

nvmf/auth: register timeout poller



The spec says that the authentication should time out if subsequent
command in an authentication transaction is not received within a
certain period of time.  The length of that period is defined as either
the keep alive timeout if keep alive timer is enabled or 2min if it
isn't.

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


Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
parent 7b0bd881
Loading
Loading
Loading
Loading
+64 −3
Original line number Diff line number Diff line
@@ -4,9 +4,13 @@

#include "spdk/log.h"
#include "spdk/stdinc.h"
#include "spdk/string.h"
#include "spdk/thread.h"

#include "nvmf_internal.h"

#define NVMF_AUTH_DEFAULT_KATO_US (120ull * 1000 * 1000)

#define AUTH_ERRLOG(q, fmt, ...) \
	SPDK_ERRLOG("[%s:%s:%u] " fmt, (q)->ctrlr->subsys->subnqn, (q)->ctrlr->hostnqn, \
		    (q)->qid, ## __VA_ARGS__)
@@ -16,10 +20,12 @@

enum nvmf_qpair_auth_state {
	NVMF_QPAIR_AUTH_NEGOTIATE,
	NVMF_QPAIR_AUTH_ERROR,
};

struct spdk_nvmf_qpair_auth {
	enum nvmf_qpair_auth_state	state;
	struct spdk_poller		*poller;
};

static void
@@ -39,6 +45,7 @@ nvmf_auth_get_state_name(enum nvmf_qpair_auth_state state)
{
	static const char *state_names[] = {
		[NVMF_QPAIR_AUTH_NEGOTIATE] = "negotiate",
		[NVMF_QPAIR_AUTH_ERROR] = "error",
	};

	return state_names[state];
@@ -57,6 +64,47 @@ nvmf_auth_set_state(struct spdk_nvmf_qpair *qpair, enum nvmf_qpair_auth_state st
	auth->state = state;
}

static void
nvmf_auth_disconnect_qpair(struct spdk_nvmf_qpair *qpair)
{
	nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_ERROR);
	spdk_nvmf_qpair_disconnect(qpair);
}

static int
nvmf_auth_timeout_poller(void *ctx)
{
	struct spdk_nvmf_qpair *qpair = ctx;
	struct spdk_nvmf_qpair_auth *auth = qpair->auth;

	AUTH_ERRLOG(qpair, "authentication timed out\n");

	spdk_poller_unregister(&auth->poller);
	nvmf_auth_disconnect_qpair(qpair);

	return SPDK_POLLER_BUSY;
}

static int
nvmf_auth_rearm_poller(struct spdk_nvmf_qpair *qpair)
{
	struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
	struct spdk_nvmf_qpair_auth *auth = qpair->auth;
	uint64_t timeout;

	timeout = ctrlr->feat.keep_alive_timer.bits.kato > 0 ?
		  ctrlr->feat.keep_alive_timer.bits.kato * 1000 :
		  NVMF_AUTH_DEFAULT_KATO_US;

	spdk_poller_unregister(&auth->poller);
	auth->poller = SPDK_POLLER_REGISTER(nvmf_auth_timeout_poller, qpair, timeout);
	if (auth->poller == NULL) {
		return -ENOMEM;
	}

	return 0;
}

static int
nvmf_auth_check_command(struct spdk_nvmf_request *req, uint8_t secp,
			uint8_t spsp0, uint8_t spsp1, uint32_t len)
@@ -148,6 +196,7 @@ int
nvmf_qpair_auth_init(struct spdk_nvmf_qpair *qpair)
{
	struct spdk_nvmf_qpair_auth *auth;
	int rc;

	assert(qpair->auth == NULL);
	auth = calloc(1, sizeof(*qpair->auth));
@@ -158,15 +207,27 @@ nvmf_qpair_auth_init(struct spdk_nvmf_qpair *qpair)
	qpair->auth = auth;
	nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_NEGOTIATE);

	rc = nvmf_auth_rearm_poller(qpair);
	if (rc != 0) {
		AUTH_ERRLOG(qpair, "failed to arm timeout poller: %s\n", spdk_strerror(-rc));
		nvmf_qpair_auth_destroy(qpair);
		return rc;
	}

	return 0;
}

void
nvmf_qpair_auth_destroy(struct spdk_nvmf_qpair *qpair)
{
	struct spdk_nvmf_qpair_auth *auth = qpair->auth;

	if (auth != NULL) {
		spdk_poller_unregister(&auth->poller);
		free(qpair->auth);
		qpair->auth = NULL;
	}
}

bool
nvmf_auth_is_supported(void)