From b0e128db3dd0cd862693edc228e9bb5305bd84ab Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Wed, 28 Jun 2017 13:13:11 -0700 Subject: [PATCH] nvmf/rpc: add adrfam to listen address This allows the user to optionally specify the address family for construct_nvmf_subsystem (default is IPv4). Note that the RDMA transport still only supports IPv4 because of the way it binds to the listen address; this will be fixed in a separate patch. Change-Id: I534ed75f6f81e53559d1bebcd2f34f1a2b210a97 Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/367429 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker --- app/nvmf_tgt/conf.c | 17 +++++++++++++++-- app/nvmf_tgt/nvmf_rpc.c | 10 ++++++++++ app/nvmf_tgt/nvmf_tgt.h | 1 + include/spdk/nvmf.h | 5 +++-- lib/nvmf/nvmf.c | 5 ++++- lib/nvmf/nvmf_internal.h | 4 ++-- lib/nvmf/rdma.c | 2 +- lib/nvmf/subsystem.c | 6 ++++-- test/unit/lib/nvmf/discovery.c/discovery_ut.c | 7 +++++-- test/unit/lib/nvmf/subsystem.c/subsystem_ut.c | 11 ++++++++--- 10 files changed, 53 insertions(+), 15 deletions(-) diff --git a/app/nvmf_tgt/conf.c b/app/nvmf_tgt/conf.c index 908972d2f..0bb63e434 100644 --- a/app/nvmf_tgt/conf.c +++ b/app/nvmf_tgt/conf.c @@ -496,6 +496,8 @@ spdk_nvmf_construct_subsystem(const char *name, for (i = 0; i < num_listen_addresses; i++) { int nic_numa_node = spdk_get_ifaddr_numa_node(addresses[i].traddr); unsigned subsys_numa_node = spdk_env_get_socket_id(app_subsys->lcore); + const char *adrfam_str; + enum spdk_nvmf_adrfam adrfam; if (nic_numa_node >= 0) { if (subsys_numa_node != (unsigned)nic_numa_node) { @@ -514,11 +516,22 @@ spdk_nvmf_construct_subsystem(const char *name, goto error; } - listen_addr = spdk_nvmf_tgt_listen(addresses[i].transport, + adrfam_str = addresses[i].adrfam; + if (adrfam_str == NULL) { + adrfam_str = "IPv4"; + } + + if (spdk_nvme_transport_id_parse_adrfam(&adrfam, adrfam_str)) { + SPDK_ERRLOG("Unknown address family '%s'\n", adrfam_str); + goto error; + } + + listen_addr = spdk_nvmf_tgt_listen(addresses[i].transport, adrfam, addresses[i].traddr, addresses[i].trsvcid); if (listen_addr == NULL) { - SPDK_ERRLOG("Failed to listen on transport %s, traddr %s, trsvcid %s\n", + SPDK_ERRLOG("Failed to listen on transport %s, adrfam %s, traddr %s, trsvcid %s\n", addresses[i].transport, + adrfam_str, addresses[i].traddr, addresses[i].trsvcid); goto error; diff --git a/app/nvmf_tgt/nvmf_rpc.c b/app/nvmf_tgt/nvmf_rpc.c index a9ce71ae7..0421a4d89 100644 --- a/app/nvmf_tgt/nvmf_rpc.c +++ b/app/nvmf_tgt/nvmf_rpc.c @@ -78,12 +78,20 @@ dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct nvmf_tgt_subsystem *tg TAILQ_FOREACH(allowed_listener, &subsystem->allowed_listeners, link) { listen_addr = allowed_listener->listen_addr; + const char *adrfam = spdk_nvme_transport_id_adrfam_str(listen_addr->adrfam); + spdk_json_write_object_begin(w); /* NOTE: "transport" is kept for compatibility; new code should use "trtype" */ spdk_json_write_name(w, "transport"); spdk_json_write_string(w, listen_addr->trname); spdk_json_write_name(w, "trtype"); spdk_json_write_string(w, listen_addr->trname); + + if (adrfam) { + spdk_json_write_name(w, "adrfam"); + spdk_json_write_string(w, adrfam); + } + spdk_json_write_name(w, "traddr"); spdk_json_write_string(w, listen_addr->traddr); spdk_json_write_name(w, "trsvcid"); @@ -180,6 +188,7 @@ static const struct spdk_json_object_decoder rpc_listen_address_decoders[] = { /* NOTE: "transport" is kept for compatibility; new code should use "trtype" */ {"transport", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true}, {"trtype", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true}, + {"adrfam", offsetof(struct rpc_listen_address, adrfam), spdk_json_decode_string, true}, {"traddr", offsetof(struct rpc_listen_address, traddr), spdk_json_decode_string}, {"trsvcid", offsetof(struct rpc_listen_address, trsvcid), spdk_json_decode_string}, }; @@ -254,6 +263,7 @@ free_rpc_listen_addresses(struct rpc_listen_addresses *r) for (i = 0; i < r->num_listen_address; i++) { free(r->addresses[i].transport); + free(r->addresses[i].adrfam); free(r->addresses[i].traddr); free(r->addresses[i].trsvcid); } diff --git a/app/nvmf_tgt/nvmf_tgt.h b/app/nvmf_tgt/nvmf_tgt.h index 62f0c6803..2291d4aa5 100644 --- a/app/nvmf_tgt/nvmf_tgt.h +++ b/app/nvmf_tgt/nvmf_tgt.h @@ -42,6 +42,7 @@ struct rpc_listen_address { char *transport; + char *adrfam; char *traddr; char *trsvcid; }; diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 309db2c61..548f9e585 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -76,6 +76,7 @@ struct spdk_nvmf_listen_addr { char *traddr; char *trsvcid; char *trname; + enum spdk_nvmf_adrfam adrfam; TAILQ_ENTRY(spdk_nvmf_listen_addr) link; }; @@ -152,8 +153,8 @@ struct spdk_nvmf_subsystem *spdk_nvmf_find_subsystem(const char *subnqn); bool spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn); -struct spdk_nvmf_listen_addr *spdk_nvmf_tgt_listen(const char *trname, const char *traddr, - const char *trsvcid); +struct spdk_nvmf_listen_addr *spdk_nvmf_tgt_listen(const char *trname, enum spdk_nvmf_adrfam adrfam, + const char *traddr, const char *trsvcid); int spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_listen_addr *listen_addr); diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index d40790d3e..d4db36f94 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -97,7 +97,8 @@ spdk_nvmf_tgt_fini(void) } struct spdk_nvmf_listen_addr * -spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, const char *trsvcid) +spdk_nvmf_listen_addr_create(const char *trname, enum spdk_nvmf_adrfam adrfam, const char *traddr, + const char *trsvcid) { struct spdk_nvmf_listen_addr *listen_addr; const struct spdk_nvmf_transport *transport; @@ -112,6 +113,8 @@ spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, const char return NULL; } + listen_addr->adrfam = adrfam; + listen_addr->traddr = strdup(traddr); if (!listen_addr->traddr) { free(listen_addr); diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index ce79a1775..a870b220c 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -91,8 +91,8 @@ struct spdk_nvmf_tgt { extern struct spdk_nvmf_tgt g_nvmf_tgt; -struct spdk_nvmf_listen_addr *spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, - const char *trsvcid); +struct spdk_nvmf_listen_addr *spdk_nvmf_listen_addr_create(const char *trname, + enum spdk_nvmf_adrfam adrfam, const char *traddr, const char *trsvcid); void spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr); void spdk_nvmf_listen_addr_cleanup(struct spdk_nvmf_listen_addr *addr); diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 69a133cd8..396ca3f1f 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -1197,7 +1197,7 @@ 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; - entry->adrfam = SPDK_NVMF_ADRFAM_IPV4; + entry->adrfam = listen_addr->adrfam; entry->treq.secure_channel = SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED; spdk_strcpy_pad(entry->trsvcid, listen_addr->trsvcid, sizeof(entry->trsvcid), ' '); diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 5d8deb3ad..03b30763e 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -264,7 +264,8 @@ spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) } struct spdk_nvmf_listen_addr * -spdk_nvmf_tgt_listen(const char *trname, const char *traddr, const char *trsvcid) +spdk_nvmf_tgt_listen(const char *trname, enum spdk_nvmf_adrfam adrfam, const char *traddr, + const char *trsvcid) { struct spdk_nvmf_listen_addr *listen_addr; const struct spdk_nvmf_transport *transport; @@ -272,6 +273,7 @@ spdk_nvmf_tgt_listen(const char *trname, const char *traddr, const char *trsvcid TAILQ_FOREACH(listen_addr, &g_nvmf_tgt.listen_addrs, link) { if ((strcmp(listen_addr->trname, trname) == 0) && + (listen_addr->adrfam == adrfam) && (strcmp(listen_addr->traddr, traddr) == 0) && (strcmp(listen_addr->trsvcid, trsvcid) == 0)) { return listen_addr; @@ -284,7 +286,7 @@ spdk_nvmf_tgt_listen(const char *trname, const char *traddr, const char *trsvcid return NULL; } - listen_addr = spdk_nvmf_listen_addr_create(trname, traddr, trsvcid); + listen_addr = spdk_nvmf_listen_addr_create(trname, adrfam, traddr, trsvcid); if (!listen_addr) { return NULL; } diff --git a/test/unit/lib/nvmf/discovery.c/discovery_ut.c b/test/unit/lib/nvmf/discovery.c/discovery_ut.c index 2a567ec94..cdd379399 100644 --- a/test/unit/lib/nvmf/discovery.c/discovery_ut.c +++ b/test/unit/lib/nvmf/discovery.c/discovery_ut.c @@ -47,7 +47,8 @@ struct spdk_nvmf_tgt g_nvmf_tgt = { }; struct spdk_nvmf_listen_addr * -spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, const char *trsvcid) +spdk_nvmf_listen_addr_create(const char *trname, enum spdk_nvmf_adrfam adrfam, + const char *traddr, const char *trsvcid) { struct spdk_nvmf_listen_addr *listen_addr; @@ -77,6 +78,8 @@ spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, const char return NULL; } + listen_addr->adrfam = adrfam; + return listen_addr; } @@ -225,7 +228,7 @@ test_discovery_log(void) NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL); SPDK_CU_ASSERT_FATAL(subsystem != NULL); - listen_addr = spdk_nvmf_tgt_listen("test_transport1", "1234", "5678"); + listen_addr = spdk_nvmf_tgt_listen("test_transport1", SPDK_NVMF_ADRFAM_IPV4, "1234", "5678"); SPDK_CU_ASSERT_FATAL(listen_addr != NULL); SPDK_CU_ASSERT_FATAL(spdk_nvmf_subsystem_add_listener(subsystem, listen_addr) == 0); diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index 045f401c8..ee6685b94 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -47,7 +47,8 @@ SPDK_LOG_REGISTER_TRACE_FLAG("nvmf", SPDK_TRACE_NVMF) struct spdk_nvmf_tgt g_nvmf_tgt; struct spdk_nvmf_listen_addr * -spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, const char *trsvcid) +spdk_nvmf_listen_addr_create(const char *trname, enum spdk_nvmf_adrfam adrfam, const char *traddr, + const char *trsvcid) { struct spdk_nvmf_listen_addr *listen_addr; @@ -77,6 +78,8 @@ spdk_nvmf_listen_addr_create(const char *trname, const char *traddr, const char return NULL; } + listen_addr->adrfam = adrfam; + return listen_addr; } @@ -172,15 +175,17 @@ test_spdk_nvmf_tgt_listen(void) /* Invalid trname */ const char *trname = "test_invalid_trname"; + enum spdk_nvmf_adrfam adrfam = SPDK_NVMF_ADRFAM_IPV4; const char *traddr = "192.168.100.1"; const char *trsvcid = "4420"; - CU_ASSERT(spdk_nvmf_tgt_listen(trname, traddr, trsvcid) == NULL); + CU_ASSERT(spdk_nvmf_tgt_listen(trname, adrfam, traddr, trsvcid) == NULL); /* Listen addr is not create and create valid listen addr */ trname = "test_transport1"; + adrfam = SPDK_NVMF_ADRFAM_IPV4; traddr = "192.168.3.11"; trsvcid = "3320"; - listen_addr = spdk_nvmf_tgt_listen(trname, traddr, trsvcid); + listen_addr = spdk_nvmf_tgt_listen(trname, adrfam, traddr, trsvcid); SPDK_CU_ASSERT_FATAL(listen_addr != NULL); CU_ASSERT(listen_addr->traddr != NULL); CU_ASSERT(listen_addr->trsvcid != NULL);