aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2013-05-29 13:09:13 -0400
committerRoland Dreier <roland@purestorage.com>2013-06-20 16:08:03 -0400
commit6a3e362d3ce60d6a9f634572486c2c21a4ccfe69 (patch)
tree0f8e6287d59ae0a25b4b3d03d6467ef6355a72a6 /drivers/infiniband/core
parent680f920a2e24725e694d9958a08226384750217b (diff)
RDMA/cma: Do not modify sa_family when setting loopback address
cma_resolve_loopback is called after an rdma_cm_id has been bound to a specific sa_family and port. Once the source sa_family for the id has been set, do not modify it. Only the actual IP address portion of the source address needs to be set. As part of this fix, we can simplify setting the source address by moving the loopback address assignment from cma_resolve_loopback to cma_bind_loopback. cma_bind_loopback is only invoked when the source address is the loopback address. Finally, add loopback support for AF_IB as part of the change. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/cma.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 1e9f3115ee91..316ddc38aa13 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1952,6 +1952,23 @@ err:
1952} 1952}
1953EXPORT_SYMBOL(rdma_resolve_route); 1953EXPORT_SYMBOL(rdma_resolve_route);
1954 1954
1955static void cma_set_loopback(struct sockaddr *addr)
1956{
1957 switch (addr->sa_family) {
1958 case AF_INET:
1959 ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1960 break;
1961 case AF_INET6:
1962 ipv6_addr_set(&((struct sockaddr_in6 *) addr)->sin6_addr,
1963 0, 0, 0, htonl(1));
1964 break;
1965 default:
1966 ib_addr_set(&((struct sockaddr_ib *) addr)->sib_addr,
1967 0, 0, 0, htonl(1));
1968 break;
1969 }
1970}
1971
1955static int cma_bind_loopback(struct rdma_id_private *id_priv) 1972static int cma_bind_loopback(struct rdma_id_private *id_priv)
1956{ 1973{
1957 struct cma_device *cma_dev; 1974 struct cma_device *cma_dev;
@@ -1992,6 +2009,7 @@ port_found:
1992 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); 2009 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
1993 id_priv->id.port_num = p; 2010 id_priv->id.port_num = p;
1994 cma_attach_to_dev(id_priv, cma_dev); 2011 cma_attach_to_dev(id_priv, cma_dev);
2012 cma_set_loopback((struct sockaddr *) &id_priv->id.route.addr.src_addr);
1995out: 2013out:
1996 mutex_unlock(&lock); 2014 mutex_unlock(&lock);
1997 return ret; 2015 return ret;
@@ -2039,7 +2057,6 @@ out:
2039static int cma_resolve_loopback(struct rdma_id_private *id_priv) 2057static int cma_resolve_loopback(struct rdma_id_private *id_priv)
2040{ 2058{
2041 struct cma_work *work; 2059 struct cma_work *work;
2042 struct sockaddr *src, *dst;
2043 union ib_gid gid; 2060 union ib_gid gid;
2044 int ret; 2061 int ret;
2045 2062
@@ -2056,18 +2073,6 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
2056 rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); 2073 rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
2057 rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); 2074 rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
2058 2075
2059 src = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
2060 if (cma_zero_addr(src)) {
2061 dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr;
2062 if ((src->sa_family = dst->sa_family) == AF_INET) {
2063 ((struct sockaddr_in *)src)->sin_addr =
2064 ((struct sockaddr_in *)dst)->sin_addr;
2065 } else {
2066 ((struct sockaddr_in6 *)src)->sin6_addr =
2067 ((struct sockaddr_in6 *)dst)->sin6_addr;
2068 }
2069 }
2070
2071 work->id = id_priv; 2076 work->id = id_priv;
2072 INIT_WORK(&work->work, cma_work_handler); 2077 INIT_WORK(&work->work, cma_work_handler);
2073 work->old_state = RDMA_CM_ADDR_QUERY; 2078 work->old_state = RDMA_CM_ADDR_QUERY;