]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
rdma/cm: fix handling of ipv6 addressing in cma_use_port
authorSean Hefty <sean.hefty@intel.com>
Wed, 17 Mar 2010 18:09:03 +0000 (10:09 -0800)
committerSean Hefty <sean.hefty@intel.com>
Wed, 17 Mar 2010 18:09:03 +0000 (10:09 -0800)
cma_use_port is coded assuming that the sockaddr is an ipv4 address.
Since ipv6 addressing is supported, and also to support other address
families, make the code more generic in its address handling.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
drivers/infiniband/core/cma.c

index 875e34e0b235d93a68b44290fbc7f1417104773c..9041a2b3b12e3f58c76272c13b93ccbc8af9551d 100644 (file)
@@ -643,6 +643,21 @@ static inline int cma_any_addr(struct sockaddr *addr)
        return cma_zero_addr(addr) || cma_loopback_addr(addr);
 }
 
+static int cma_addr_cmp(struct sockaddr *src, struct sockaddr *dst)
+{
+       if (src->sa_family != dst->sa_family)
+               return -1;
+
+       switch (src->sa_family) {
+       case AF_INET:
+               return ((struct sockaddr_in *) src)->sin_addr.s_addr !=
+                      ((struct sockaddr_in *) dst)->sin_addr.s_addr;
+       default:
+               return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr,
+                                    &((struct sockaddr_in6 *) dst)->sin6_addr);
+       }
+}
+
 static inline __be16 cma_port(struct sockaddr *addr)
 {
        if (addr->sa_family == AF_INET)
@@ -2014,13 +2029,13 @@ err1:
 static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
 {
        struct rdma_id_private *cur_id;
-       struct sockaddr_in *sin, *cur_sin;
+       struct sockaddr *addr, *cur_addr;
        struct rdma_bind_list *bind_list;
        struct hlist_node *node;
        unsigned short snum;
 
-       sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
-       snum = ntohs(sin->sin_port);
+       addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+       snum = ntohs(cma_port(addr));
        if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
                return -EACCES;
 
@@ -2032,15 +2047,15 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
         * We don't support binding to any address if anyone is bound to
         * a specific address on the same port.
         */
-       if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr))
+       if (cma_any_addr(addr))
                return -EADDRNOTAVAIL;
 
        hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
-               if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr))
+               cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr;
+               if (cma_any_addr(cur_addr))
                        return -EADDRNOTAVAIL;
 
-               cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr;
-               if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr)
+               if (!cma_addr_cmp(addr, cur_addr))
                        return -EADDRINUSE;
        }