Commit 2641c31a authored by Changpeng Liu's avatar Changpeng Liu Committed by Ben Walker
Browse files

nvmf: Listen for incoming connections only on addresses specified



Currently the NVMf target listens for new connections on any address.
Instead, listen only on the addresses specified by the user.

Change-Id: Idb6d37c422e442fc70a8673bd3fcfb9c27b57828
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent f36f4a79
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -130,11 +130,6 @@ nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_queues_per_sess,
	SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max In Capsule Data: %d bytes\n", in_capsule_data_size);
	SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max I/O Size: %d bytes\n", max_io_size);

	/* init nvmf specific config options */
	if (!g_nvmf_tgt.sin_port) {
		g_nvmf_tgt.sin_port = htons(SPDK_NVMF_DEFAULT_SIN_PORT);
	}

	rc = spdk_nvmf_initialize_pools();
	if (rc != 0) {
		SPDK_ERRLOG("spdk_nvmf_initialize_pools() failed\n");
+0 −2
Original line number Diff line number Diff line
@@ -68,8 +68,6 @@ struct spdk_nvmf_globals {

	uint32_t in_capsule_data_size;
	uint32_t max_io_size;

	uint16_t	   sin_port;
};

int nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_conn_per_sess,
+93 −29
Original line number Diff line number Diff line
@@ -136,17 +136,29 @@ struct spdk_nvmf_rdma_session {
	struct ibv_mr				*buf_mr;
};

struct spdk_nvmf_rdma_listen_addr {
	char					*traddr;
	char					*trsvc;
	struct rdma_cm_id			*id;
	TAILQ_ENTRY(spdk_nvmf_rdma_listen_addr)	link;
};

struct spdk_nvmf_rdma {
	struct rdma_event_channel			*acceptor_event_channel;
	struct rdma_cm_id		*acceptor_listen_id;

	uint16_t max_queue_depth;
	uint32_t max_io_size;
	uint32_t in_capsule_data_size;
	uint32_t num_devices_found;

	pthread_mutex_t lock;
	TAILQ_HEAD(, spdk_nvmf_rdma_listen_addr)	listen_addrs;
};

static struct spdk_nvmf_rdma g_rdma = { };
static struct spdk_nvmf_rdma g_rdma = {
	.lock = PTHREAD_MUTEX_INITIALIZER,
	.listen_addrs = TAILQ_HEAD_INITIALIZER(g_rdma.listen_addrs),
};

static inline struct spdk_nvmf_rdma_conn *
get_rdma_conn(struct spdk_nvmf_conn *conn)
@@ -975,17 +987,13 @@ static int
spdk_nvmf_rdma_acceptor_init(void)
{
	struct sockaddr_in	addr;
	uint16_t		sin_port;
	int			rc;
	struct spdk_nvmf_rdma_listen_addr *listen_addr, *tmp;

	if (g_rdma.num_devices_found == 0) {
		return 0;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = g_nvmf_tgt.sin_port;

	/* create an event channel with rdmacm to receive
	   connection oriented requests and notifications */
	g_rdma.acceptor_event_channel = rdma_create_event_channel();
@@ -999,30 +1007,46 @@ spdk_nvmf_rdma_acceptor_init(void)
		goto create_id_error;
	}

	rc = rdma_create_id(g_rdma.acceptor_event_channel, &g_rdma.acceptor_listen_id, NULL, RDMA_PS_TCP);
	pthread_mutex_lock(&g_rdma.lock);
	TAILQ_FOREACH_SAFE(listen_addr, &g_rdma.listen_addrs, link, tmp) {
		memset(&addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = inet_addr(listen_addr->traddr);
		addr.sin_port = htons((uint16_t)strtoul(listen_addr->trsvc, NULL, 10));

		rc = rdma_create_id(g_rdma.acceptor_event_channel, &listen_addr->id, NULL,
				    RDMA_PS_TCP);
		if (rc < 0) {
			SPDK_ERRLOG("rdma_create_id() failed\n");
		goto create_id_error;
			goto listen_error;
		}

	rc = rdma_bind_addr(g_rdma.acceptor_listen_id, (struct sockaddr *)&addr);
		rc = rdma_bind_addr(listen_addr->id, (struct sockaddr *)&addr);
		if (rc < 0) {
			SPDK_ERRLOG("rdma_bind_addr() failed\n");
			goto listen_error;
		}

	rc = rdma_listen(g_rdma.acceptor_listen_id, 10); /* 10 = backlog */
		rc = rdma_listen(listen_addr->id, 10); /* 10 = backlog */
		if (rc < 0) {
			SPDK_ERRLOG("rdma_listen() failed\n");
			goto listen_error;
		}
	sin_port = ntohs(rdma_get_src_port(g_rdma.acceptor_listen_id));
	SPDK_NOTICELOG("*** NVMf Target Listening on port %d ***\n", sin_port);
		SPDK_NOTICELOG("*** NVMf Target Listening on %s port %d ***\n",
			       listen_addr->traddr, ntohs(rdma_get_src_port(listen_addr->id)));
	}

	return rc;
	pthread_mutex_unlock(&g_rdma.lock);
	return 0;

listen_error:
	rdma_destroy_id(g_rdma.acceptor_listen_id);
	TAILQ_FOREACH_SAFE(listen_addr, &g_rdma.listen_addrs, link, tmp) {
		if (listen_addr->id) {
			rdma_destroy_id(listen_addr->id);
		}
	}
	pthread_mutex_unlock(&g_rdma.lock);

create_id_error:
	rdma_destroy_event_channel(g_rdma.acceptor_event_channel);
	return -1;
@@ -1031,6 +1055,14 @@ create_id_error:
static void
spdk_nvmf_rdma_acceptor_fini(void)
{
	struct spdk_nvmf_rdma_listen_addr *listen_addr, *tmp;

	pthread_mutex_lock(&g_rdma.lock);
	TAILQ_FOREACH_SAFE(listen_addr, &g_rdma.listen_addrs, link, tmp) {
		TAILQ_REMOVE(&g_rdma.listen_addrs, listen_addr, link);
		free(listen_addr);
	}
	pthread_mutex_unlock(&g_rdma.lock);
}

static int
@@ -1430,7 +1462,7 @@ spdk_nvmf_rdma_poll(struct spdk_nvmf_conn *conn)
}

static void
nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr,
spdk_nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr,
			struct spdk_nvmf_discovery_log_page_entry *entry)
{
	entry->trtype = SPDK_NVMF_TRTYPE_RDMA;
@@ -1445,6 +1477,35 @@ nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr,
	entry->tsas.rdma.rdma_cms = SPDK_NVMF_RDMA_CMS_RDMA_CM;
}

static int
spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr)
{
	struct spdk_nvmf_rdma_listen_addr *addr, *tmp;

	pthread_mutex_lock(&g_rdma.lock);
	TAILQ_FOREACH_SAFE(addr, &g_rdma.listen_addrs, link, tmp) {
		if ((!strcasecmp(addr->traddr, listen_addr->traddr)) &&
		    (!strcasecmp(addr->trsvc, listen_addr->trsvc))) {
			pthread_mutex_unlock(&g_rdma.lock);
			return 0;
		}
	}

	addr = calloc(1, sizeof(*addr));
	if (!addr) {
		pthread_mutex_unlock(&g_rdma.lock);
		return -1;
	}

	addr->traddr = listen_addr->traddr;
	addr->trsvc = listen_addr->trsvc;

	TAILQ_INSERT_TAIL(&g_rdma.listen_addrs, addr, link);
	pthread_mutex_unlock(&g_rdma.lock);

	return 0;
}

const struct spdk_nvmf_transport spdk_nvmf_transport_rdma = {
	.name = "rdma",
	.transport_init = spdk_nvmf_rdma_init,
@@ -1454,6 +1515,9 @@ const struct spdk_nvmf_transport spdk_nvmf_transport_rdma = {
	.acceptor_poll = spdk_nvmf_rdma_acceptor_poll,
	.acceptor_fini = spdk_nvmf_rdma_acceptor_fini,

	.listen_addr_add = spdk_nvmf_rdma_listen,
	.listen_addr_discover = spdk_nvmf_rdma_discover,

	.session_init = spdk_nvmf_rdma_session_init,
	.session_fini = spdk_nvmf_rdma_session_fini,

@@ -1463,7 +1527,7 @@ const struct spdk_nvmf_transport spdk_nvmf_transport_rdma = {
	.conn_fini = spdk_nvmf_rdma_close_conn,
	.conn_poll = spdk_nvmf_rdma_poll,

	.listen_addr_discover = nvmf_rdma_discover,

};

SPDK_LOG_REGISTER_TRACE_FLAG("rdma", SPDK_TRACE_RDMA)
+7 −0
Original line number Diff line number Diff line
@@ -175,6 +175,7 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
				 char *traddr, char *trsvc)
{
	struct spdk_nvmf_listen_addr *listen_addr;
	int rc;

	listen_addr = calloc(1, sizeof(*listen_addr));
	if (!listen_addr) {
@@ -199,6 +200,12 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
	TAILQ_INSERT_HEAD(&subsystem->listen_addrs, listen_addr, link);
	subsystem->num_listen_addrs++;

	rc = transport->listen_addr_add(listen_addr);
	if (rc < 0) {
		SPDK_ERRLOG("Unable to listen on address '%s'\n", traddr);
		return -1;
	}

	return 0;
}

+12 −6
Original line number Diff line number Diff line
@@ -75,6 +75,18 @@ struct spdk_nvmf_transport {
	 */
	void (*acceptor_fini)(void);

	/**
	  * Instruct the acceptor to listen on the address provided. This
	  * may be called multiple times.
	  */
	int (*listen_addr_add)(struct spdk_nvmf_listen_addr *listen_addr);

	/**
	 * Fill out a discovery log entry for a specific listen address.
	 */
	void (*listen_addr_discover)(struct spdk_nvmf_listen_addr *listen_addr,
				     struct spdk_nvmf_discovery_log_page_entry *entry);

	/**
	 * Initialize the transport for the given session
	 */
@@ -108,12 +120,6 @@ struct spdk_nvmf_transport {
	 * Poll a connection for events.
	 */
	int (*conn_poll)(struct spdk_nvmf_conn *conn);

	/**
	 * Fill out a discovery log entry for a specific listen address.
	 */
	void (*listen_addr_discover)(struct spdk_nvmf_listen_addr *listen_addr,
				     struct spdk_nvmf_discovery_log_page_entry *entry);
};

int spdk_nvmf_transport_init(void);