]> 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>
Thu, 13 May 2010 01:02:07 +0000 (18:02 -0700)
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 6d777069d86d6add74325e970d31541e699e4647..2bed7799fc806efe361e3bde543863024119a499 100644 (file)
@@ -644,6 +644,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)
@@ -2016,13 +2031,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;
 
@@ -2034,15 +2049,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;
        }