* [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper
2017-02-16 17:43 [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address Sagi Grimberg
@ 2017-02-16 17:43 ` Sagi Grimberg
2017-02-16 21:34 ` kbuild test robot
2017-02-19 17:15 ` [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper Christoph Hellwig
[not found] ` <1487267017-29904-1-git-send-email-sagi-NQWnxTmZq1alnMjI0IkVqw@public.gmane.org>
` (3 subsequent siblings)
4 siblings, 2 replies; 18+ messages in thread
From: Sagi Grimberg @ 2017-02-16 17:43 UTC (permalink / raw)
To: linux-nvme, linux-rdma, target-devel, netdev
Several locations in the stack need to handle ipv4/ipv6
(with scope) and port strings conversion to sockaddr.
Add a helper that takes either AF_INET, AF_INET6 or
AF_UNSPEC (for wildcard) to centralize this handling.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
---
include/linux/inet.h | 6 ++++
net/core/utils.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
diff --git a/include/linux/inet.h b/include/linux/inet.h
index 4cca05c9678e..636ebe87e6f8 100644
--- a/include/linux/inet.h
+++ b/include/linux/inet.h
@@ -43,6 +43,8 @@
#define _LINUX_INET_H
#include <linux/types.h>
+#include <net/net_namespace.h>
+#include <linux/socket.h>
/*
* These mimic similar macros defined in user-space for inet_ntop(3).
@@ -54,4 +56,8 @@
extern __be32 in_aton(const char *str);
extern int in4_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
extern int in6_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
+
+extern int inet_pton_with_scope(struct net *net, unsigned short af,
+ const char *src, const char *port, struct sockaddr_storage *addr);
+
#endif /* _LINUX_INET_H */
diff --git a/net/core/utils.c b/net/core/utils.c
index 6592d7bbed39..8f15d016c64a 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -26,9 +26,11 @@
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/ratelimit.h>
+#include <linux/socket.h>
#include <net/sock.h>
#include <net/net_ratelimit.h>
+#include <net/ipv6.h>
#include <asm/byteorder.h>
#include <linux/uaccess.h>
@@ -300,6 +302,95 @@ int in6_pton(const char *src, int srclen,
}
EXPORT_SYMBOL(in6_pton);
+/**
+ * inet_pton_with_scope - convert an IPv4/IPv6 and port to socket address
+ * @net: net namespace (used for scope handling)
+ * @af: address family, AF_INET, AF_INET6 or AF_UNSPEC for either
+ * @src: the start of the address string
+ * @port: the start of the port string (or NULL for none)
+ * @addr: output socket address
+ *
+ * Return zero on success, return errno when any error occurs.
+ */
+int inet_pton_with_scope(struct net *net, __kernel_sa_family_t af,
+ const char *src, const char *port, struct sockaddr_storage *addr)
+{
+ struct sockaddr_in *addr4;
+ struct sockaddr_in6 *addr6;
+ const char *scope_delim;
+ bool unspec = false;
+ int srclen = strlen(src);
+ u16 port_num;
+
+ if (port) {
+ if (kstrtou16(port, 0, &port_num)) {
+ pr_err("failed port_num %s\n", port);
+ return -EINVAL;
+ }
+ } else {
+ port_num = 0;
+ }
+
+ switch (af) {
+ case AF_UNSPEC:
+ unspec = true;
+ /* FALLTHRU */
+ case AF_INET:
+ if (srclen <= INET_ADDRSTRLEN) {
+ addr4 = (struct sockaddr_in *)addr;
+ if (in4_pton(src, srclen, (u8 *) &addr4->sin_addr.s_addr,
+ '\n', NULL) > 0) {
+ addr4->sin_family = AF_INET;
+ addr4->sin_port = htons(port_num);
+ return 0;
+ }
+ pr_err("failed in4_pton %s\n", src);
+ }
+ if (!unspec)
+ break;
+ case AF_INET6:
+ if (srclen <= INET6_ADDRSTRLEN) {
+ addr6 = (struct sockaddr_in6 *)addr;
+ if (in6_pton(src, srclen, (u8 *) &addr6->sin6_addr.s6_addr,
+ '%', &scope_delim) == 0) {
+ pr_err("failed in6_pton %s\n", src);
+ return -EINVAL;
+ }
+
+ if (ipv6_addr_type(&addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL &&
+ src + srclen != scope_delim && *scope_delim == '%') {
+ struct net_device *dev;
+ char scope_id[16];
+ size_t scope_len = min_t(size_t, sizeof scope_id,
+ src + srclen - scope_delim - 1);
+
+ memcpy(scope_id, scope_delim + 1, scope_len);
+ scope_id[scope_len] = '\0';
+
+ dev = dev_get_by_name(net, scope_id);
+ if (dev) {
+ addr6->sin6_scope_id = dev->ifindex;
+ dev_put(dev);
+ } else if (kstrtouint(scope_id, 0, &addr6->sin6_scope_id)) {
+ pr_err("failed dev_get_by_name %s\n", scope_id);
+ return -EINVAL;
+ }
+ }
+
+ addr6->sin6_family = AF_INET6;
+ addr6->sin6_port = htons(port_num);
+
+ return 0;
+ }
+ break;
+ default:
+ pr_err("unexpected address family %d\n", af);
+ };
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(inet_pton_with_scope);
+
void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
__be32 from, __be32 to, bool pseudohdr)
{
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper
2017-02-16 17:43 ` [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper Sagi Grimberg
@ 2017-02-16 21:34 ` kbuild test robot
[not found] ` <1487267017-29904-2-git-send-email-sagi-NQWnxTmZq1alnMjI0IkVqw@public.gmane.org>
2017-02-19 17:15 ` [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper Christoph Hellwig
1 sibling, 1 reply; 18+ messages in thread
From: kbuild test robot @ 2017-02-16 21:34 UTC (permalink / raw)
To: Sagi Grimberg; +Cc: kbuild-all, linux-nvme, linux-rdma, target-devel, netdev
Hi Sagi,
[auto build test WARNING on linus/master]
[also build test WARNING on v4.10-rc8 next-20170216]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Sagi-Grimberg/Introduce-a-new-helper-for-parsing-ipv-4-6-port-to-socket-address/20170217-015537
coccinelle warnings: (new ones prefixed by >>)
>> net/core/utils.c:388:2-3: Unneeded semicolon
Please review and possibly fold the followup patch.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper
2017-02-16 17:43 ` [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper Sagi Grimberg
2017-02-16 21:34 ` kbuild test robot
@ 2017-02-19 17:15 ` Christoph Hellwig
[not found] ` <20170219171523.GC10310-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
1 sibling, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2017-02-19 17:15 UTC (permalink / raw)
To: Sagi Grimberg; +Cc: linux-nvme, linux-rdma, target-devel, netdev
On Thu, Feb 16, 2017 at 07:43:34PM +0200, Sagi Grimberg wrote:
> Several locations in the stack need to handle ipv4/ipv6
> (with scope) and port strings conversion to sockaddr.
> Add a helper that takes either AF_INET, AF_INET6 or
> AF_UNSPEC (for wildcard) to centralize this handling.
>
> Suggested-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
> ---
> include/linux/inet.h | 6 ++++
> net/core/utils.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 97 insertions(+)
>
> diff --git a/include/linux/inet.h b/include/linux/inet.h
> index 4cca05c9678e..636ebe87e6f8 100644
> --- a/include/linux/inet.h
> +++ b/include/linux/inet.h
> @@ -43,6 +43,8 @@
> #define _LINUX_INET_H
>
> #include <linux/types.h>
> +#include <net/net_namespace.h>
> +#include <linux/socket.h>
>
> /*
> * These mimic similar macros defined in user-space for inet_ntop(3).
> @@ -54,4 +56,8 @@
> extern __be32 in_aton(const char *str);
> extern int in4_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
> extern int in6_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
> +
> +extern int inet_pton_with_scope(struct net *net, unsigned short af,
> + const char *src, const char *port, struct sockaddr_storage *addr);
> +
> #endif /* _LINUX_INET_H */
> diff --git a/net/core/utils.c b/net/core/utils.c
> index 6592d7bbed39..8f15d016c64a 100644
> --- a/net/core/utils.c
> +++ b/net/core/utils.c
> @@ -26,9 +26,11 @@
> #include <linux/percpu.h>
> #include <linux/init.h>
> #include <linux/ratelimit.h>
> +#include <linux/socket.h>
>
> #include <net/sock.h>
> #include <net/net_ratelimit.h>
> +#include <net/ipv6.h>
>
> #include <asm/byteorder.h>
> #include <linux/uaccess.h>
> @@ -300,6 +302,95 @@ int in6_pton(const char *src, int srclen,
> }
> EXPORT_SYMBOL(in6_pton);
>
> +/**
> + * inet_pton_with_scope - convert an IPv4/IPv6 and port to socket address
> + * @net: net namespace (used for scope handling)
> + * @af: address family, AF_INET, AF_INET6 or AF_UNSPEC for either
> + * @src: the start of the address string
> + * @port: the start of the port string (or NULL for none)
> + * @addr: output socket address
> + *
> + * Return zero on success, return errno when any error occurs.
> + */
> +int inet_pton_with_scope(struct net *net, __kernel_sa_family_t af,
> + const char *src, const char *port, struct sockaddr_storage *addr)
> +{
> + struct sockaddr_in *addr4;
> + struct sockaddr_in6 *addr6;
> + const char *scope_delim;
> + bool unspec = false;
> + int srclen = strlen(src);
> + u16 port_num;
> +
> + if (port) {
> + if (kstrtou16(port, 0, &port_num)) {
> + pr_err("failed port_num %s\n", port);
> + return -EINVAL;
> + }
> + } else {
> + port_num = 0;
> + }
> +
> + switch (af) {
> + case AF_UNSPEC:
> + unspec = true;
> + /* FALLTHRU */
> + case AF_INET:
> + if (srclen <= INET_ADDRSTRLEN) {
> + addr4 = (struct sockaddr_in *)addr;
> + if (in4_pton(src, srclen, (u8 *) &addr4->sin_addr.s_addr,
> + '\n', NULL) > 0) {
> + addr4->sin_family = AF_INET;
> + addr4->sin_port = htons(port_num);
> + return 0;
> + }
> + pr_err("failed in4_pton %s\n", src);
> + }
I would probably factor this and the IPv6 equivalent below into helpers
to keep the code a little more self-contained so that we could avoid the
fallthrough magic.
Except for that and the semicolon warnings this looks fine to me.
^ permalink raw reply [flat|nested] 18+ messages in thread
[parent not found: <1487267017-29904-1-git-send-email-sagi-NQWnxTmZq1alnMjI0IkVqw@public.gmane.org>]
* [PATCH rfc 2/4] nvmet-rdma: use generic inet_pton_with_scope
[not found] ` <1487267017-29904-1-git-send-email-sagi-NQWnxTmZq1alnMjI0IkVqw@public.gmane.org>
@ 2017-02-16 17:43 ` Sagi Grimberg
0 siblings, 0 replies; 18+ messages in thread
From: Sagi Grimberg @ 2017-02-16 17:43 UTC (permalink / raw)
To: linux-nvme-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
target-devel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Sagi Grimberg <sagi-NQWnxTmZq1alnMjI0IkVqw@public.gmane.org>
---
drivers/nvme/target/rdma.c | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 8c3760a78ac0..298db68f2db9 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -1411,12 +1411,16 @@ static void nvmet_rdma_delete_ctrl(struct nvmet_ctrl *ctrl)
static int nvmet_rdma_add_port(struct nvmet_port *port)
{
struct rdma_cm_id *cm_id;
- struct sockaddr_in addr_in;
- u16 port_in;
+ struct sockaddr_storage addr = { };
+ __kernel_sa_family_t af;
int ret;
switch (port->disc_addr.adrfam) {
case NVMF_ADDR_FAMILY_IP4:
+ af = AF_INET;
+ break;
+ case NVMF_ADDR_FAMILY_IP6:
+ af = AF_INET6;
break;
default:
pr_err("address family %d not supported\n",
@@ -1424,13 +1428,13 @@ static int nvmet_rdma_add_port(struct nvmet_port *port)
return -EINVAL;
}
- ret = kstrtou16(port->disc_addr.trsvcid, 0, &port_in);
- if (ret)
+ ret = inet_pton_with_scope(&init_net, af, port->disc_addr.traddr,
+ port->disc_addr.trsvcid, &addr);
+ if (ret) {
+ pr_err("malformed ip/port passed: %s:%s\n",
+ port->disc_addr.traddr, port->disc_addr.trsvcid);
return ret;
-
- addr_in.sin_family = AF_INET;
- addr_in.sin_addr.s_addr = in_aton(port->disc_addr.traddr);
- addr_in.sin_port = htons(port_in);
+ }
cm_id = rdma_create_id(&init_net, nvmet_rdma_cm_handler, port,
RDMA_PS_TCP, IB_QPT_RC);
@@ -1439,20 +1443,32 @@ static int nvmet_rdma_add_port(struct nvmet_port *port)
return PTR_ERR(cm_id);
}
- ret = rdma_bind_addr(cm_id, (struct sockaddr *)&addr_in);
+ /*
+ * Allow both IPv4 and IPv6 sockets to bind a single port
+ * at the same time.
+ */
+ ret = rdma_set_afonly(cm_id, 1);
+ if (ret) {
+ pr_err("rdma_set_afonly failed (%d)\n", ret);
+ goto out_destroy_id;
+ }
+
+ ret = rdma_bind_addr(cm_id, (struct sockaddr *)&addr);
if (ret) {
- pr_err("binding CM ID to %pISpc failed (%d)\n", &addr_in, ret);
+ pr_err("binding CM ID to %pISpcs failed (%d)\n",
+ (struct sockaddr *)&addr, ret);
goto out_destroy_id;
}
ret = rdma_listen(cm_id, 128);
if (ret) {
- pr_err("listening to %pISpc failed (%d)\n", &addr_in, ret);
+ pr_err("listening to %pISpcs failed (%d)\n",
+ (struct sockaddr *)&addr, ret);
goto out_destroy_id;
}
- pr_info("enabling port %d (%pISpc)\n",
- le16_to_cpu(port->disc_addr.portid), &addr_in);
+ pr_info("enabling port %d (%pISpcs)\n",
+ le16_to_cpu(port->disc_addr.portid), (struct sockaddr *)&addr);
port->priv = cm_id;
return 0;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH rfc 3/4] nvme-rdma: use inet_pton_with_scope helper
2017-02-16 17:43 [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address Sagi Grimberg
2017-02-16 17:43 ` [PATCH rfc 1/4] net/utils: generic inet_pton_with_scope helper Sagi Grimberg
[not found] ` <1487267017-29904-1-git-send-email-sagi-NQWnxTmZq1alnMjI0IkVqw@public.gmane.org>
@ 2017-02-16 17:43 ` Sagi Grimberg
2017-02-16 17:43 ` [PATCH rfc 4/4] iscsi-target: use generic inet_pton_with_scope Sagi Grimberg
2017-02-16 17:50 ` [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address Chuck Lever
4 siblings, 0 replies; 18+ messages in thread
From: Sagi Grimberg @ 2017-02-16 17:43 UTC (permalink / raw)
To: linux-nvme, linux-rdma, target-devel, netdev
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/nvme/host/rdma.c | 48 +++++++++++++-----------------------------------
1 file changed, 13 insertions(+), 35 deletions(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 890e7e4b1c15..bf02acbb4af8 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -151,10 +151,7 @@ struct nvme_rdma_ctrl {
u64 cap;
u32 max_fr_pages;
- union {
- struct sockaddr addr;
- struct sockaddr_in addr_in;
- };
+ struct sockaddr_storage addr;
struct nvme_ctrl ctrl;
};
@@ -589,7 +586,8 @@ static int nvme_rdma_init_queue(struct nvme_rdma_ctrl *ctrl,
}
queue->cm_error = -ETIMEDOUT;
- ret = rdma_resolve_addr(queue->cm_id, NULL, &ctrl->addr,
+ ret = rdma_resolve_addr(queue->cm_id, NULL,
+ (struct sockaddr *)&ctrl->addr,
NVME_RDMA_CONNECT_TIMEOUT_MS);
if (ret) {
dev_info(ctrl->ctrl.device,
@@ -1874,27 +1872,13 @@ static int nvme_rdma_create_io_queues(struct nvme_rdma_ctrl *ctrl)
return ret;
}
-static int nvme_rdma_parse_ipaddr(struct sockaddr_in *in_addr, char *p)
-{
- u8 *addr = (u8 *)&in_addr->sin_addr.s_addr;
- size_t buflen = strlen(p);
-
- /* XXX: handle IPv6 addresses */
-
- if (buflen > INET_ADDRSTRLEN)
- return -EINVAL;
- if (in4_pton(p, buflen, addr, '\0', NULL) == 0)
- return -EINVAL;
- in_addr->sin_family = AF_INET;
- return 0;
-}
-
static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
struct nvmf_ctrl_options *opts)
{
struct nvme_rdma_ctrl *ctrl;
int ret;
bool changed;
+ char *port;
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
@@ -1902,24 +1886,18 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
ctrl->ctrl.opts = opts;
INIT_LIST_HEAD(&ctrl->list);
- ret = nvme_rdma_parse_ipaddr(&ctrl->addr_in, opts->traddr);
+ if (opts->mask & NVMF_OPT_TRSVCID)
+ port = opts->trsvcid;
+ else
+ port = __stringify(NVME_RDMA_IP_PORT);
+
+ ret = inet_pton_with_scope(&init_net, AF_UNSPEC, opts->traddr,
+ port, &ctrl->addr);
if (ret) {
- pr_err("malformed IP address passed: %s\n", opts->traddr);
+ pr_err("malformed ip/port passed: %s:%s\n", opts->traddr, port);
goto out_free_ctrl;
}
- if (opts->mask & NVMF_OPT_TRSVCID) {
- u16 port;
-
- ret = kstrtou16(opts->trsvcid, 0, &port);
- if (ret)
- goto out_free_ctrl;
-
- ctrl->addr_in.sin_port = cpu_to_be16(port);
- } else {
- ctrl->addr_in.sin_port = cpu_to_be16(NVME_RDMA_IP_PORT);
- }
-
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_rdma_ctrl_ops,
0 /* no quirks, we're perfect! */);
if (ret)
@@ -1984,7 +1962,7 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
WARN_ON_ONCE(!changed);
- dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISp\n",
+ dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISpcs\n",
ctrl->ctrl.opts->subsysnqn, &ctrl->addr);
kref_get(&ctrl->ctrl.kref);
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH rfc 4/4] iscsi-target: use generic inet_pton_with_scope
2017-02-16 17:43 [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address Sagi Grimberg
` (2 preceding siblings ...)
2017-02-16 17:43 ` [PATCH rfc 3/4] nvme-rdma: use inet_pton_with_scope helper Sagi Grimberg
@ 2017-02-16 17:43 ` Sagi Grimberg
2017-02-19 5:54 ` Nicholas A. Bellinger
2017-02-16 17:50 ` [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address Chuck Lever
4 siblings, 1 reply; 18+ messages in thread
From: Sagi Grimberg @ 2017-02-16 17:43 UTC (permalink / raw)
To: linux-nvme, linux-rdma, target-devel, netdev
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/target/iscsi/iscsi_target_configfs.c | 46 ++++++++--------------------
1 file changed, 12 insertions(+), 34 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index bf40f03755dd..f30c27b83c5e 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -167,10 +167,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
struct iscsi_portal_group *tpg;
struct iscsi_tpg_np *tpg_np;
char *str, *str2, *ip_str, *port_str;
- struct sockaddr_storage sockaddr;
- struct sockaddr_in *sock_in;
- struct sockaddr_in6 *sock_in6;
- unsigned long port;
+ struct sockaddr_storage sockaddr = { };
int ret;
char buf[MAX_PORTAL_LEN + 1];
@@ -182,21 +179,19 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
memset(buf, 0, MAX_PORTAL_LEN + 1);
snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name);
- memset(&sockaddr, 0, sizeof(struct sockaddr_storage));
-
str = strstr(buf, "[");
if (str) {
- const char *end;
-
str2 = strstr(str, "]");
if (!str2) {
pr_err("Unable to locate trailing \"]\""
" in IPv6 iSCSI network portal address\n");
return ERR_PTR(-EINVAL);
}
- str++; /* Skip over leading "[" */
+
+ ip_str = str + 1; /* Skip over leading "[" */
*str2 = '\0'; /* Terminate the unbracketed IPv6 address */
str2++; /* Skip over the \0 */
+
port_str = strstr(str2, ":");
if (!port_str) {
pr_err("Unable to locate \":port\""
@@ -205,23 +200,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
}
*port_str = '\0'; /* Terminate string for IP */
port_str++; /* Skip over ":" */
-
- ret = kstrtoul(port_str, 0, &port);
- if (ret < 0) {
- pr_err("kstrtoul() failed for port_str: %d\n", ret);
- return ERR_PTR(ret);
- }
- sock_in6 = (struct sockaddr_in6 *)&sockaddr;
- sock_in6->sin6_family = AF_INET6;
- sock_in6->sin6_port = htons((unsigned short)port);
- ret = in6_pton(str, -1,
- (void *)&sock_in6->sin6_addr.in6_u, -1, &end);
- if (ret <= 0) {
- pr_err("in6_pton returned: %d\n", ret);
- return ERR_PTR(-EINVAL);
- }
} else {
- str = ip_str = &buf[0];
+ ip_str = &buf[0];
port_str = strstr(ip_str, ":");
if (!port_str) {
pr_err("Unable to locate \":port\""
@@ -230,17 +210,15 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
}
*port_str = '\0'; /* Terminate string for IP */
port_str++; /* Skip over ":" */
+ }
- ret = kstrtoul(port_str, 0, &port);
- if (ret < 0) {
- pr_err("kstrtoul() failed for port_str: %d\n", ret);
- return ERR_PTR(ret);
- }
- sock_in = (struct sockaddr_in *)&sockaddr;
- sock_in->sin_family = AF_INET;
- sock_in->sin_port = htons((unsigned short)port);
- sock_in->sin_addr.s_addr = in_aton(ip_str);
+ ret = inet_pton_with_scope(&init_net, AF_UNSPEC, ip_str,
+ port_str, &sockaddr);
+ if (ret) {
+ pr_err("malformed ip/port passed: %s\n", name);
+ return ERR_PTR(ret);
}
+
tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
ret = iscsit_get_tpg(tpg);
if (ret < 0)
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH rfc 4/4] iscsi-target: use generic inet_pton_with_scope
2017-02-16 17:43 ` [PATCH rfc 4/4] iscsi-target: use generic inet_pton_with_scope Sagi Grimberg
@ 2017-02-19 5:54 ` Nicholas A. Bellinger
0 siblings, 0 replies; 18+ messages in thread
From: Nicholas A. Bellinger @ 2017-02-19 5:54 UTC (permalink / raw)
To: Sagi Grimberg; +Cc: linux-nvme, linux-rdma, target-devel, netdev
On Thu, 2017-02-16 at 19:43 +0200, Sagi Grimberg wrote:
> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
> ---
> drivers/target/iscsi/iscsi_target_configfs.c | 46 ++++++++--------------------
> 1 file changed, 12 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
> index bf40f03755dd..f30c27b83c5e 100644
> --- a/drivers/target/iscsi/iscsi_target_configfs.c
> +++ b/drivers/target/iscsi/iscsi_target_configfs.c
> @@ -167,10 +167,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
> struct iscsi_portal_group *tpg;
> struct iscsi_tpg_np *tpg_np;
> char *str, *str2, *ip_str, *port_str;
> - struct sockaddr_storage sockaddr;
> - struct sockaddr_in *sock_in;
> - struct sockaddr_in6 *sock_in6;
> - unsigned long port;
> + struct sockaddr_storage sockaddr = { };
> int ret;
> char buf[MAX_PORTAL_LEN + 1];
>
> @@ -182,21 +179,19 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
> memset(buf, 0, MAX_PORTAL_LEN + 1);
> snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name);
>
> - memset(&sockaddr, 0, sizeof(struct sockaddr_storage));
> -
> str = strstr(buf, "[");
> if (str) {
> - const char *end;
> -
> str2 = strstr(str, "]");
> if (!str2) {
> pr_err("Unable to locate trailing \"]\""
> " in IPv6 iSCSI network portal address\n");
> return ERR_PTR(-EINVAL);
> }
> - str++; /* Skip over leading "[" */
> +
> + ip_str = str + 1; /* Skip over leading "[" */
> *str2 = '\0'; /* Terminate the unbracketed IPv6 address */
> str2++; /* Skip over the \0 */
> +
> port_str = strstr(str2, ":");
> if (!port_str) {
> pr_err("Unable to locate \":port\""
> @@ -205,23 +200,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
> }
> *port_str = '\0'; /* Terminate string for IP */
> port_str++; /* Skip over ":" */
> -
> - ret = kstrtoul(port_str, 0, &port);
> - if (ret < 0) {
> - pr_err("kstrtoul() failed for port_str: %d\n", ret);
> - return ERR_PTR(ret);
> - }
> - sock_in6 = (struct sockaddr_in6 *)&sockaddr;
> - sock_in6->sin6_family = AF_INET6;
> - sock_in6->sin6_port = htons((unsigned short)port);
> - ret = in6_pton(str, -1,
> - (void *)&sock_in6->sin6_addr.in6_u, -1, &end);
> - if (ret <= 0) {
> - pr_err("in6_pton returned: %d\n", ret);
> - return ERR_PTR(-EINVAL);
> - }
> } else {
> - str = ip_str = &buf[0];
> + ip_str = &buf[0];
> port_str = strstr(ip_str, ":");
> if (!port_str) {
> pr_err("Unable to locate \":port\""
> @@ -230,17 +210,15 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
> }
> *port_str = '\0'; /* Terminate string for IP */
> port_str++; /* Skip over ":" */
> + }
>
> - ret = kstrtoul(port_str, 0, &port);
> - if (ret < 0) {
> - pr_err("kstrtoul() failed for port_str: %d\n", ret);
> - return ERR_PTR(ret);
> - }
> - sock_in = (struct sockaddr_in *)&sockaddr;
> - sock_in->sin_family = AF_INET;
> - sock_in->sin_port = htons((unsigned short)port);
> - sock_in->sin_addr.s_addr = in_aton(ip_str);
> + ret = inet_pton_with_scope(&init_net, AF_UNSPEC, ip_str,
> + port_str, &sockaddr);
> + if (ret) {
> + pr_err("malformed ip/port passed: %s\n", name);
> + return ERR_PTR(ret);
> }
> +
> tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
> ret = iscsit_get_tpg(tpg);
> if (ret < 0)
A nice cleanup.
Acked-by: Nicholas Bellinger <nab@linux-iscsi.org>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address
2017-02-16 17:43 [PATCH rfc 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address Sagi Grimberg
` (3 preceding siblings ...)
2017-02-16 17:43 ` [PATCH rfc 4/4] iscsi-target: use generic inet_pton_with_scope Sagi Grimberg
@ 2017-02-16 17:50 ` Chuck Lever
2017-02-16 17:53 ` Sagi Grimberg
4 siblings, 1 reply; 18+ messages in thread
From: Chuck Lever @ 2017-02-16 17:50 UTC (permalink / raw)
To: Sagi Grimberg; +Cc: linux-nvme, List Linux RDMA Mailing, target-devel, netdev
> On Feb 16, 2017, at 12:43 PM, Sagi Grimberg <sagi@grimberg.me> wrote:
>
> We have some places in the stack that support ipv4 and ipv6. In
> some cases the user configuration does not reveal which
> address family is given and needs to be parsed from the input string.
>
> Given that the user-input varies between subsystems, some processing
> is required from the call-site to separate address and port strings.
>
> As a side-effect, this set adds ipv6 support for nvme over fabrics.
> I also converted iscsi target and plan to convert nfs/cifs next but
> wanted to get some feedback before doing that.
At least NFS/RDMA already supports IPv6. You might not need many
changes there, but I'll hold off on further comments.
> patch #1 is based off roland's patch:
> http://lists.infradead.org/pipermail/linux-nvme/2016-August/005600.html
>
> Sagi Grimberg (4):
> net/utils: generic inet_pton_with_scope helper
> nvmet-rdma: use generic inet_pton_with_scope
> nvme-rdma: use inet_pton_with_scope helper
> iscsi-target: use generic inet_pton_with_scope
>
> drivers/nvme/host/rdma.c | 48 ++++-----------
> drivers/nvme/target/rdma.c | 42 +++++++++----
> drivers/target/iscsi/iscsi_target_configfs.c | 46 ++++----------
> include/linux/inet.h | 6 ++
> net/core/utils.c | 91 ++++++++++++++++++++++++++++
> 5 files changed, 151 insertions(+), 82 deletions(-)
>
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Chuck Lever
^ permalink raw reply [flat|nested] 18+ messages in thread