Re: [PATCH for-next V2 07/11] IB/core: Validate route in ib_init_ah_from_wc and ib_init_ah_from_path

2015-12-10 Thread Matan Barak
On Mon, Dec 7, 2015 at 3:42 PM, Haggai Eran  wrote:
> On 12/03/2015 03:47 PM, Matan Barak wrote:
>> +static int addr_resolve_neigh(struct dst_entry *dst,
>> +   const struct sockaddr *dst_in,
>> +   struct rdma_dev_addr *addr)
>> +{
>> + if (dst->dev->flags & IFF_LOOPBACK) {
>> + int ret;
>> +
>> + ret = rdma_translate_ip(dst_in, addr, NULL);
>> + if (!ret)
>> + memcpy(addr->dst_dev_addr, addr->src_dev_addr,
>> +MAX_ADDR_LEN);
>> +
>> + return ret;
>> + }
>> +
>> + /* If the device does ARP internally */
> You mean "doesn't do ARP internally" right?
>

Correct, nice catch :)

>> + if (!(dst->dev->flags & IFF_NOARP)) {
>> + const struct sockaddr_in *dst_in4 =
>> + (const struct sockaddr_in *)dst_in;
>> + const struct sockaddr_in6 *dst_in6 =
>> + (const struct sockaddr_in6 *)dst_in;
>> +
>> + return dst_fetch_ha(dst, addr,
>> + dst_in->sa_family == AF_INET ?
>> + (const void *)_in4->sin_addr.s_addr :
>> + (const void *)_in6->sin6_addr);
>> + }
>> +
>> + return rdma_copy_addr(addr, dst->dev, NULL);
>> +}
>
>> +int rdma_resolve_ip_route(struct sockaddr *src_addr,
>> +   const struct sockaddr *dst_addr,
>> +   struct rdma_dev_addr *addr)
>> +{
>> + struct sockaddr_storage ssrc_addr;
>> + struct sockaddr *src_in = (struct sockaddr *)_addr;
>> +
>> + if (src_addr->sa_family != dst_addr->sa_family)
>> + return -EINVAL;
>> +
>> + if (src_addr)
>> + memcpy(src_in, src_addr, rdma_addr_size(src_addr));
>> + else
>> + src_in->sa_family = dst_addr->sa_family;
> Don't you need to clear the rest of src_in? I believe you pass
> uninitialized memory to it.
>

Correct, I'll fix that.

>> +
>> + return addr_resolve(src_in, dst_addr, addr, false);
>> +}
>> +EXPORT_SYMBOL(rdma_resolve_ip_route);
>
> Haggai

Thanks for taking a look.

Matan

> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH for-next V2 07/11] IB/core: Validate route in ib_init_ah_from_wc and ib_init_ah_from_path

2015-12-07 Thread Haggai Eran
On 12/03/2015 03:47 PM, Matan Barak wrote:
> +static int addr_resolve_neigh(struct dst_entry *dst,
> +   const struct sockaddr *dst_in,
> +   struct rdma_dev_addr *addr)
> +{
> + if (dst->dev->flags & IFF_LOOPBACK) {
> + int ret;
> +
> + ret = rdma_translate_ip(dst_in, addr, NULL);
> + if (!ret)
> + memcpy(addr->dst_dev_addr, addr->src_dev_addr,
> +MAX_ADDR_LEN);
> +
> + return ret;
> + }
> +
> + /* If the device does ARP internally */
You mean "doesn't do ARP internally" right?

> + if (!(dst->dev->flags & IFF_NOARP)) {
> + const struct sockaddr_in *dst_in4 =
> + (const struct sockaddr_in *)dst_in;
> + const struct sockaddr_in6 *dst_in6 =
> + (const struct sockaddr_in6 *)dst_in;
> +
> + return dst_fetch_ha(dst, addr,
> + dst_in->sa_family == AF_INET ?
> + (const void *)_in4->sin_addr.s_addr :
> + (const void *)_in6->sin6_addr);
> + }
> +
> + return rdma_copy_addr(addr, dst->dev, NULL);
> +}

> +int rdma_resolve_ip_route(struct sockaddr *src_addr,
> +   const struct sockaddr *dst_addr,
> +   struct rdma_dev_addr *addr)
> +{
> + struct sockaddr_storage ssrc_addr;
> + struct sockaddr *src_in = (struct sockaddr *)_addr;
> +
> + if (src_addr->sa_family != dst_addr->sa_family)
> + return -EINVAL;
> +
> + if (src_addr)
> + memcpy(src_in, src_addr, rdma_addr_size(src_addr));
> + else
> + src_in->sa_family = dst_addr->sa_family;
Don't you need to clear the rest of src_in? I believe you pass
uninitialized memory to it.

> +
> + return addr_resolve(src_in, dst_addr, addr, false);
> +}
> +EXPORT_SYMBOL(rdma_resolve_ip_route);

Haggai
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH for-next V2 07/11] IB/core: Validate route in ib_init_ah_from_wc and ib_init_ah_from_path

2015-12-03 Thread Matan Barak
In order to make sure API users don't try to use SGIDs which don't
conform to the routing table, validate the route before searching
the RoCE GID table.

Signed-off-by: Matan Barak 
---
 drivers/infiniband/core/addr.c   | 175 ++-
 drivers/infiniband/core/cm.c |  10 +-
 drivers/infiniband/core/cma.c|  30 +-
 drivers/infiniband/core/sa_query.c   |  75 +++--
 drivers/infiniband/core/verbs.c  |  48 ++---
 drivers/infiniband/hw/ocrdma/ocrdma_ah.c |   2 +-
 include/rdma/ib_addr.h   |  10 +-
 7 files changed, 270 insertions(+), 80 deletions(-)

diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 6e35299..57eda11 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -121,7 +121,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct 
net_device *dev,
 }
 EXPORT_SYMBOL(rdma_copy_addr);
 
-int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
+int rdma_translate_ip(const struct sockaddr *addr,
+ struct rdma_dev_addr *dev_addr,
  u16 *vlan_id)
 {
struct net_device *dev;
@@ -139,7 +140,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct 
rdma_dev_addr *dev_addr,
switch (addr->sa_family) {
case AF_INET:
dev = ip_dev_find(dev_addr->net,
-   ((struct sockaddr_in *) addr)->sin_addr.s_addr);
+   ((const struct sockaddr_in *)addr)->sin_addr.s_addr);
 
if (!dev)
return ret;
@@ -154,7 +155,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct 
rdma_dev_addr *dev_addr,
rcu_read_lock();
for_each_netdev_rcu(dev_addr->net, dev) {
if (ipv6_chk_addr(dev_addr->net,
- &((struct sockaddr_in6 *) 
addr)->sin6_addr,
+ &((const struct sockaddr_in6 
*)addr)->sin6_addr,
  dev, 1)) {
ret = rdma_copy_addr(dev_addr, dev, NULL);
if (vlan_id)
@@ -198,7 +199,8 @@ static void queue_req(struct addr_req *req)
mutex_unlock();
 }
 
-static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, 
void *daddr)
+static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
+   const void *daddr)
 {
struct neighbour *n;
int ret;
@@ -222,8 +224,9 @@ static int dst_fetch_ha(struct dst_entry *dst, struct 
rdma_dev_addr *dev_addr, v
 }
 
 static int addr4_resolve(struct sockaddr_in *src_in,
-struct sockaddr_in *dst_in,
-struct rdma_dev_addr *addr)
+const struct sockaddr_in *dst_in,
+struct rdma_dev_addr *addr,
+struct rtable **prt)
 {
__be32 src_ip = src_in->sin_addr.s_addr;
__be32 dst_ip = dst_in->sin_addr.s_addr;
@@ -243,36 +246,23 @@ static int addr4_resolve(struct sockaddr_in *src_in,
src_in->sin_family = AF_INET;
src_in->sin_addr.s_addr = fl4.saddr;
 
-   if (rt->dst.dev->flags & IFF_LOOPBACK) {
-   ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
-   if (!ret)
-   memcpy(addr->dst_dev_addr, addr->src_dev_addr, 
MAX_ADDR_LEN);
-   goto put;
-   }
-
-   /* If the device does ARP internally, return 'done' */
-   if (rt->dst.dev->flags & IFF_NOARP) {
-   ret = rdma_copy_addr(addr, rt->dst.dev, NULL);
-   goto put;
-   }
-
/* If there's a gateway, we're definitely in RoCE v2 (as RoCE v1 isn't
 * routable) and we could set the network type accordingly.
 */
if (rt->rt_uses_gateway)
addr->network = RDMA_NETWORK_IPV4;
 
-   ret = dst_fetch_ha(>dst, addr, );
-put:
-   ip_rt_put(rt);
+   *prt = rt;
+   return 0;
 out:
return ret;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
 static int addr6_resolve(struct sockaddr_in6 *src_in,
-struct sockaddr_in6 *dst_in,
-struct rdma_dev_addr *addr)
+const struct sockaddr_in6 *dst_in,
+struct rdma_dev_addr *addr,
+struct dst_entry **pdst)
 {
struct flowi6 fl6;
struct dst_entry *dst;
@@ -299,49 +289,109 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
src_in->sin6_addr = fl6.saddr;
}
 
-   if (dst->dev->flags & IFF_LOOPBACK) {
-   ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
-   if (!ret)
-   memcpy(addr->dst_dev_addr, addr->src_dev_addr, 
MAX_ADDR_LEN);
-   goto put;
-   

[PATCH for-next V2 07/11] IB/core: Validate route in ib_init_ah_from_wc and ib_init_ah_from_path

2015-12-03 Thread Matan Barak
In order to make sure API users don't try to use SGIDs which don't
conform to the routing table, validate the route before searching
the RoCE GID table.

Signed-off-by: Matan Barak 
---
 drivers/infiniband/core/addr.c   | 175 ++-
 drivers/infiniband/core/cm.c |  10 +-
 drivers/infiniband/core/cma.c|  30 +-
 drivers/infiniband/core/sa_query.c   |  75 +++--
 drivers/infiniband/core/verbs.c  |  48 ++---
 drivers/infiniband/hw/ocrdma/ocrdma_ah.c |   2 +-
 include/rdma/ib_addr.h   |  10 +-
 7 files changed, 270 insertions(+), 80 deletions(-)

diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 6e35299..57eda11 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -121,7 +121,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct 
net_device *dev,
 }
 EXPORT_SYMBOL(rdma_copy_addr);
 
-int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
+int rdma_translate_ip(const struct sockaddr *addr,
+ struct rdma_dev_addr *dev_addr,
  u16 *vlan_id)
 {
struct net_device *dev;
@@ -139,7 +140,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct 
rdma_dev_addr *dev_addr,
switch (addr->sa_family) {
case AF_INET:
dev = ip_dev_find(dev_addr->net,
-   ((struct sockaddr_in *) addr)->sin_addr.s_addr);
+   ((const struct sockaddr_in *)addr)->sin_addr.s_addr);
 
if (!dev)
return ret;
@@ -154,7 +155,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct 
rdma_dev_addr *dev_addr,
rcu_read_lock();
for_each_netdev_rcu(dev_addr->net, dev) {
if (ipv6_chk_addr(dev_addr->net,
- &((struct sockaddr_in6 *) 
addr)->sin6_addr,
+ &((const struct sockaddr_in6 
*)addr)->sin6_addr,
  dev, 1)) {
ret = rdma_copy_addr(dev_addr, dev, NULL);
if (vlan_id)
@@ -198,7 +199,8 @@ static void queue_req(struct addr_req *req)
mutex_unlock();
 }
 
-static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, 
void *daddr)
+static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
+   const void *daddr)
 {
struct neighbour *n;
int ret;
@@ -222,8 +224,9 @@ static int dst_fetch_ha(struct dst_entry *dst, struct 
rdma_dev_addr *dev_addr, v
 }
 
 static int addr4_resolve(struct sockaddr_in *src_in,
-struct sockaddr_in *dst_in,
-struct rdma_dev_addr *addr)
+const struct sockaddr_in *dst_in,
+struct rdma_dev_addr *addr,
+struct rtable **prt)
 {
__be32 src_ip = src_in->sin_addr.s_addr;
__be32 dst_ip = dst_in->sin_addr.s_addr;
@@ -243,36 +246,23 @@ static int addr4_resolve(struct sockaddr_in *src_in,
src_in->sin_family = AF_INET;
src_in->sin_addr.s_addr = fl4.saddr;
 
-   if (rt->dst.dev->flags & IFF_LOOPBACK) {
-   ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
-   if (!ret)
-   memcpy(addr->dst_dev_addr, addr->src_dev_addr, 
MAX_ADDR_LEN);
-   goto put;
-   }
-
-   /* If the device does ARP internally, return 'done' */
-   if (rt->dst.dev->flags & IFF_NOARP) {
-   ret = rdma_copy_addr(addr, rt->dst.dev, NULL);
-   goto put;
-   }
-
/* If there's a gateway, we're definitely in RoCE v2 (as RoCE v1 isn't
 * routable) and we could set the network type accordingly.
 */
if (rt->rt_uses_gateway)
addr->network = RDMA_NETWORK_IPV4;
 
-   ret = dst_fetch_ha(>dst, addr, );
-put:
-   ip_rt_put(rt);
+   *prt = rt;
+   return 0;
 out:
return ret;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
 static int addr6_resolve(struct sockaddr_in6 *src_in,
-struct sockaddr_in6 *dst_in,
-struct rdma_dev_addr *addr)
+const struct sockaddr_in6 *dst_in,
+struct rdma_dev_addr *addr,
+struct dst_entry **pdst)
 {
struct flowi6 fl6;
struct dst_entry *dst;
@@ -299,49 +289,109 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
src_in->sin6_addr = fl6.saddr;
}
 
-   if (dst->dev->flags & IFF_LOOPBACK) {
-   ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
-   if (!ret)
-   memcpy(addr->dst_dev_addr, addr->src_dev_addr, 
MAX_ADDR_LEN);
-   goto put;
-