diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index a54db68f5..6187afda2 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -206,6 +206,18 @@ typedef void (*nvmf_qpair_disconnect_cb)(void *ctx); int spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx); +/** + * Get the peer's transport ID for this queue pair. + * + * \param qpair The NVMe-oF qpair + * \param trid Output parameter that will contain the transport id. + * + * \return 0 for success. + * \return -EINVAL if the qpair is not connected. + */ +int spdk_nvmf_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid); + /** * Create an NVMe-oF subsystem. * diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index 4e133f64b..bf4e30d33 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -753,6 +753,13 @@ spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_ return 0; } +int +spdk_nvmf_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + return spdk_nvmf_transport_qpair_get_peer_trid(qpair, trid); +} + int spdk_nvmf_poll_group_add_transport(struct spdk_nvmf_poll_group *group, struct spdk_nvmf_transport *transport) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index b0cb2849a..c59e5b8de 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -2693,6 +2693,44 @@ spdk_nvmf_rdma_poll_group_poll(struct spdk_nvmf_transport_poll_group *group) return count; } +static int +spdk_nvmf_rdma_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + struct spdk_nvmf_rdma_qpair *rqpair; + struct sockaddr *saddr; + + rqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair); + + trid->trtype = SPDK_NVME_TRANSPORT_RDMA; + + saddr = rdma_get_peer_addr(rqpair->cm_id); + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *saddr_in = (struct sockaddr_in *)saddr; + + trid->adrfam = SPDK_NVMF_ADRFAM_IPV4; + inet_ntop(AF_INET, &saddr_in->sin_addr, + trid->traddr, sizeof(trid->traddr)); + snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%u", saddr_in->sin_port); + break; + } + case AF_INET6: { + struct sockaddr_in6 *saddr_in = (struct sockaddr_in6 *)saddr; + trid->adrfam = SPDK_NVMF_ADRFAM_IPV6; + inet_ntop(AF_INET6, &saddr_in->sin6_addr, + trid->traddr, sizeof(trid->traddr)); + snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%u", saddr_in->sin6_port); + break; + } + default: + return -1; + + } + + return 0; +} + const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = { .type = SPDK_NVME_TRANSPORT_RDMA, .create = spdk_nvmf_rdma_create, @@ -2714,6 +2752,7 @@ const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = { .qpair_fini = spdk_nvmf_rdma_close_qpair, .qpair_is_idle = spdk_nvmf_rdma_qpair_is_idle, + .qpair_get_peer_trid = spdk_nvmf_rdma_qpair_get_peer_trid, }; diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index 746a0427f..b0ca0e817 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -209,3 +209,10 @@ spdk_nvmf_transport_qpair_is_idle(struct spdk_nvmf_qpair *qpair) { return qpair->transport->ops->qpair_is_idle(qpair); } + +int +spdk_nvmf_transport_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + return qpair->transport->ops->qpair_get_peer_trid(qpair, trid); +} diff --git a/lib/nvmf/transport.h b/lib/nvmf/transport.h index 4e5d4a7db..ac5b40467 100644 --- a/lib/nvmf/transport.h +++ b/lib/nvmf/transport.h @@ -130,6 +130,12 @@ struct spdk_nvmf_transport_ops { * True if the qpair has no pending IO. */ bool (*qpair_is_idle)(struct spdk_nvmf_qpair *qpair); + + /* + * Get the remote transport ID for the queue pair + */ + int (*qpair_get_peer_trid)(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid); }; struct spdk_nvmf_transport *spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt, @@ -168,6 +174,9 @@ void spdk_nvmf_transport_qpair_fini(struct spdk_nvmf_qpair *qpair); bool spdk_nvmf_transport_qpair_is_idle(struct spdk_nvmf_qpair *qpair); +int spdk_nvmf_transport_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid); + extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma; #endif /* SPDK_NVMF_TRANSPORT_H */