From 6847a679ea588d94fc0eaeb5d9d9d71748b32c22 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 25 Aug 2017 15:05:01 -0700 Subject: [PATCH] nvme/rdma: add option to specify source address Allow the user to set the source address when connecting to a NVMe-oF controller. Change-Id: Ice3add4b2cd3b64fdb8d0d7807d2235f90fd86b1 Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/375837 Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- include/spdk/nvme.h | 14 ++++++++++++++ lib/nvme/nvme_ctrlr.c | 2 ++ lib/nvme/nvme_rdma.c | 31 ++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index c1d2a29ca..eb32b3e20 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -116,6 +116,20 @@ struct spdk_nvme_ctrlr_opts { * or driver-assisted striping. */ uint32_t io_queue_requests; + + /** + * Source address for NVMe-oF connections. + * Set src_addr and src_svcid to empty strings if no source address should be + * specified. + */ + char src_addr[SPDK_NVMF_TRADDR_MAX_LEN + 1]; + + /** + * Source service ID (port) for NVMe-oF connections. + * Set src_addr and src_svcid to empty strings if no source address should be + * specified. + */ + char src_svcid[SPDK_NVMF_TRSVCID_MAX_LEN + 1]; }; /** diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 6fab01c92..a8394f74b 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -85,6 +85,8 @@ spdk_nvme_ctrlr_opts_set_defaults(struct spdk_nvme_ctrlr_opts *opts) opts->io_queue_size = DEFAULT_IO_QUEUE_SIZE; strncpy(opts->hostnqn, DEFAULT_HOSTNQN, sizeof(opts->hostnqn)); opts->io_queue_requests = DEFAULT_IO_QUEUE_REQUESTS; + memset(opts->src_addr, 0, sizeof(opts->src_addr)); + memset(opts->src_svcid, 0, sizeof(opts->src_svcid)); } /** diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index f2d13c550..6fd455348 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -432,13 +432,14 @@ nvme_rdma_recv(struct nvme_rdma_qpair *rqpair, uint64_t rsp_idx) static int nvme_rdma_resolve_addr(struct nvme_rdma_qpair *rqpair, - struct sockaddr_storage *sin, + struct sockaddr *src_addr, + struct sockaddr *dst_addr, struct rdma_event_channel *cm_channel) { int ret; struct rdma_cm_event *event; - ret = rdma_resolve_addr(rqpair->cm_id, NULL, (struct sockaddr *) sin, + ret = rdma_resolve_addr(rqpair->cm_id, src_addr, dst_addr, NVME_RDMA_TIME_OUT_IN_MS); if (ret) { SPDK_ERRLOG("rdma_resolve_addr, %d\n", errno); @@ -699,7 +700,9 @@ nvme_rdma_unregister_mem(struct nvme_rdma_qpair *rqpair) static int nvme_rdma_qpair_connect(struct nvme_rdma_qpair *rqpair) { - struct sockaddr_storage sin; + struct sockaddr_storage dst_addr; + struct sockaddr_storage src_addr; + bool src_addr_specified; int rc; struct spdk_nvme_ctrlr *ctrlr; int family; @@ -726,22 +729,36 @@ nvme_rdma_qpair_connect(struct nvme_rdma_qpair *rqpair) SPDK_DEBUGLOG(SPDK_TRACE_NVME, "adrfam %d ai_family %d\n", ctrlr->trid.adrfam, family); - memset(&sin, 0, sizeof(struct sockaddr_storage)); + memset(&dst_addr, 0, sizeof(dst_addr)); SPDK_DEBUGLOG(SPDK_TRACE_NVME, "trsvcid is %s\n", ctrlr->trid.trsvcid); - rc = nvme_rdma_parse_addr(&sin, family, ctrlr->trid.traddr, ctrlr->trid.trsvcid); + rc = nvme_rdma_parse_addr(&dst_addr, family, ctrlr->trid.traddr, ctrlr->trid.trsvcid); if (rc != 0) { - SPDK_ERRLOG("nvme_rdma_parse_addr() failed\n"); + SPDK_ERRLOG("dst_addr nvme_rdma_parse_addr() failed\n"); return -1; } + if (ctrlr->opts.src_addr[0] || ctrlr->opts.src_svcid[0]) { + memset(&src_addr, 0, sizeof(src_addr)); + rc = nvme_rdma_parse_addr(&src_addr, family, ctrlr->opts.src_addr, ctrlr->opts.src_svcid); + if (rc != 0) { + SPDK_ERRLOG("src_addr nvme_rdma_parse_addr() failed\n"); + return -1; + } + src_addr_specified = true; + } else { + src_addr_specified = false; + } + rc = rdma_create_id(rqpair->cm_channel, &rqpair->cm_id, rqpair, RDMA_PS_TCP); if (rc < 0) { SPDK_ERRLOG("rdma_create_id() failed\n"); return -1; } - rc = nvme_rdma_resolve_addr(rqpair, &sin, rqpair->cm_channel); + rc = nvme_rdma_resolve_addr(rqpair, + src_addr_specified ? (struct sockaddr *)&src_addr : NULL, + (struct sockaddr *)&dst_addr, rqpair->cm_channel); if (rc < 0) { SPDK_ERRLOG("nvme_rdma_resolve_addr() failed\n"); return -1;