[PATCH v2] nvme-tcp: Print actual source IP address in address attribute
Belanger, Martin
Martin.Belanger at dell.com
Thu Sep 1 05:49:19 PDT 2022
> -----Original Message-----
> From: Sagi Grimberg <sagi at grimberg.me>
> Sent: Thursday, September 1, 2022 7:03 AM
> To: Martin Belanger; linux-nvme at lists.infradead.org
> Cc: kbusch at kernel.org; hare at suse.de; axboe at fb.com; hch at lst.de; Belanger,
> Martin
> Subject: Re: [PATCH v2] nvme-tcp: Print actual source IP address in address
> attribute
>
>
> [EXTERNAL EMAIL]
>
>
>
> On 8/31/22 22:38, Martin Belanger wrote:
> > From: Martin Belanger <martin.belanger at dell.com>
> >
> > TCP transport relies on the routing table to determine which source
> > address and interface to use when making a connection.
> > Currently, there is no way to tell from userspace where a connection
> > was made. This patch allows exposing the actual source address using
> > the host_traddr field of the address attribute.
> >
> > This is needed to diagnose and identify connectivity issues since it
> > will allow us to tell which interface and source address is associated
> > with each connection.
> >
> > Signed-off-by: Martin Belanger <martin.belanger at dell.com>
> > ---
> > drivers/nvme/host/tcp.c | 34 +++++++++++++++++++++++++++++++++-
> > 1 file changed, 33 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index
> > 044da18c06f5..adbb76483a74 100644
> > --- a/drivers/nvme/host/tcp.c
> > +++ b/drivers/nvme/host/tcp.c
> > @@ -165,6 +165,7 @@ struct nvme_tcp_ctrl {
> > struct blk_mq_tag_set admin_tag_set;
> > struct sockaddr_storage addr;
> > struct sockaddr_storage src_addr;
> > + struct sockaddr_storage sock_addr;
> > struct nvme_ctrl ctrl;
> >
> > struct work_struct err_work;
> > @@ -1597,6 +1598,12 @@ static int nvme_tcp_alloc_queue(struct
> nvme_ctrl *nctrl,
> > goto err_rcv_pdu;
> > }
> >
> > + /* Retrieve the actual source address from the socket */
> > + ret = kernel_getsockname(queue->sock,
> > + (struct sockaddr *)&ctrl->sock_addr);
> > + if (ret < 0)
> > + memset(&ctrl->sock_addr, 0, sizeof(ctrl->sock_addr));
> > +
>
> For every queue?
Hi Sagi. Thanks for reviewing this.
I see the error of my ways. I will remove this and instead invoke kernel_getsockname() from nvme_tcp_get_address() below. And it will only apply to queue[0].
>
> > ret = nvme_tcp_init_connection(queue);
> > if (ret)
> > goto err_init_connect;
> > @@ -2532,6 +2539,31 @@ static int nvme_tcp_poll(struct blk_mq_hw_ctx
> *hctx, struct io_comp_batch *iob)
> > return queue->nr_cqe;
> > }
> >
> > +static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf,
> > +int size) {
> > + int len = 0;
> > + struct sockaddr_storage *sa = &to_tcp_ctrl(ctrl)->sock_addr;
>
> You can just retrieve the sock_addr from the admin queue here locally. I don't
> think we need a struct member for it.
Got it. Will do.
>
> > +
> > + if (ctrl->opts->mask & NVMF_OPT_TRADDR)
> > + len += scnprintf(buf, size, "traddr=%s", ctrl->opts->traddr);
> > + if (ctrl->opts->mask & NVMF_OPT_TRSVCID)
> > + len += scnprintf(buf + len, size - len, "%strsvcid=%s",
> > + (len) ? "," : "", ctrl->opts->trsvcid);
> > + if ((sa->ss_family == AF_INET) || (sa->ss_family == AF_INET6)) {
> > + len += scnprintf(buf + len, size - len, "%shost_traddr=%pISc",
> > + (len) ? "," : "", sa);
>
> It is confusing to expose that if it was not specified, that is creating a different
> behavior from the existing behavior and from other transports.
I asked Hannes first. He recommended using the host_traddr key because it is already recognized by nvme-cli. If you think we should define a new key, e.g. "src_addr", I can do that too.
On the other hand, if you think that exposing the source address through the "address" attribute is not the best approach, we could introduce a new attribute instead (e.g. "src_address"). However, this is a TCP-only attribute, and there is currently no framework to expose attributes directly from the tcp.c module. This will require a lot of new code and I was looking for a solution that requires the least amount of changes.
Let me know what you prefer.
Thanks,
Martin
>
> > + } else if (ctrl->opts->mask & NVMF_OPT_HOST_TRADDR) {
> > + len += scnprintf(buf + len, size - len, "%shost_traddr=%s",
> > + (len) ? "," : "", ctrl->opts->host_traddr);
> > + }
> > + if (ctrl->opts->mask & NVMF_OPT_HOST_IFACE)
> > + len += scnprintf(buf + len, size - len, "%shost_iface=%s",
> > + (len) ? "," : "", ctrl->opts->host_iface);
> > + len += scnprintf(buf + len, size - len, "\n");
> > +
> > + return len;
> > +}
> > +
> > static const struct blk_mq_ops nvme_tcp_mq_ops = {
> > .queue_rq = nvme_tcp_queue_rq,
> > .commit_rqs = nvme_tcp_commit_rqs,
> > @@ -2563,7 +2595,7 @@ static const struct nvme_ctrl_ops
> nvme_tcp_ctrl_ops = {
> > .free_ctrl = nvme_tcp_free_ctrl,
> > .submit_async_event = nvme_tcp_submit_async_event,
> > .delete_ctrl = nvme_tcp_delete_ctrl,
> > - .get_address = nvmf_get_address,
> > + .get_address = nvme_tcp_get_address,
> > .stop_ctrl = nvme_tcp_stop_ctrl,
> > };
> >
More information about the Linux-nvme
mailing list