In order to support loopback rdma device, support resolving loopback addresses to their respective rdma device. Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> --- drivers/infiniband/core/cma.c | 134 ++++-------------------------------------- 1 file changed, 12 insertions(+), 122 deletions(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 68c997b..01913aa 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -621,7 +621,8 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port)) return ERR_PTR(-ENODEV); - if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) { + if ((dev_type == ARPHRD_ETHER || dev_type == ARPHRD_LOOPBACK) && + rdma_protocol_roce(device, port)) { ndev = dev_get_by_index(dev_addr->net, bound_if_index); if (!ndev) return ERR_PTR(-ENODEV); @@ -1401,8 +1402,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev, if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || ipv4_is_lbcast(daddr) || ipv4_is_zeronet(saddr) || - ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr) || - ipv4_is_loopback(saddr)) + ipv4_is_zeronet(daddr)) return false; memset(&fl4, 0, sizeof(fl4)); @@ -2022,7 +2022,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND; rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); - } else if (!cma_any_addr(cma_src_addr(id_priv))) { + } else if (!cma_zero_addr(cma_src_addr(id_priv))) { ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr); if (ret) goto err; @@ -2920,81 +2920,6 @@ int rdma_resolve_route(struct rdma_cm_id *id, unsigned long timeout_ms) } EXPORT_SYMBOL(rdma_resolve_route); -static void cma_set_loopback(struct sockaddr *addr) -{ - switch (addr->sa_family) { - case AF_INET: - ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - break; - case AF_INET6: - ipv6_addr_set(&((struct sockaddr_in6 *) addr)->sin6_addr, - 0, 0, 0, htonl(1)); - break; - default: - ib_addr_set(&((struct sockaddr_ib *) addr)->sib_addr, - 0, 0, 0, htonl(1)); - break; - } -} - -static int cma_bind_loopback(struct rdma_id_private *id_priv) -{ - struct cma_device *cma_dev, *cur_dev; - union ib_gid gid; - enum ib_port_state port_state; - u16 pkey; - int ret; - u8 p; - - cma_dev = NULL; - mutex_lock(&lock); - list_for_each_entry(cur_dev, &dev_list, list) { - if (cma_family(id_priv) == AF_IB && - !rdma_cap_ib_cm(cur_dev->device, 1)) - continue; - - if (!cma_dev) - cma_dev = cur_dev; - - for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) { - if (!ib_get_cached_port_state(cur_dev->device, p, &port_state) && - port_state == IB_PORT_ACTIVE) { - cma_dev = cur_dev; - goto port_found; - } - } - } - - if (!cma_dev) { - ret = -ENODEV; - goto out; - } - - p = 1; - -port_found: - ret = rdma_query_gid(cma_dev->device, p, 0, &gid); - if (ret) - goto out; - - ret = ib_get_cached_pkey(cma_dev->device, p, 0, &pkey); - if (ret) - goto out; - - id_priv->id.route.addr.dev_addr.dev_type = - (rdma_protocol_ib(cma_dev->device, p)) ? - ARPHRD_INFINIBAND : ARPHRD_ETHER; - - rdma_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid); - ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); - id_priv->id.port_num = p; - cma_attach_to_dev(id_priv, cma_dev); - cma_set_loopback(cma_src_addr(id_priv)); -out: - mutex_unlock(&lock); - return ret; -} - static void addr_handler(int status, struct sockaddr *src_addr, struct rdma_dev_addr *dev_addr, void *context) { @@ -3046,33 +2971,6 @@ static void addr_handler(int status, struct sockaddr *src_addr, mutex_unlock(&id_priv->handler_mutex); } -static int cma_resolve_loopback(struct rdma_id_private *id_priv) -{ - struct cma_work *work; - union ib_gid gid; - int ret; - - work = kzalloc(sizeof *work, GFP_KERNEL); - if (!work) - return -ENOMEM; - - if (!id_priv->cma_dev) { - ret = cma_bind_loopback(id_priv); - if (ret) - goto err; - } - - rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); - rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); - - cma_init_resolve_addr_work(work, id_priv); - queue_work(cma_wq, &work->work); - return 0; -err: - kfree(work); - return ret; -} - static int cma_resolve_ib_addr(struct rdma_id_private *id_priv) { struct cma_work *work; @@ -3140,24 +3038,16 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, return -EINVAL; memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); - if (cma_any_addr(dst_addr)) { - ret = cma_resolve_loopback(id_priv); + if (dst_addr->sa_family == AF_IB) { + ret = cma_resolve_ib_addr(id_priv); } else { - if (dst_addr->sa_family == AF_IB) { - ret = cma_resolve_ib_addr(id_priv); - } else { - ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, - &id->route.addr.dev_addr, - timeout_ms, addr_handler, - false, id_priv); - } + ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, + &id->route.addr.dev_addr, + timeout_ms, addr_handler, + false, id_priv); } if (ret) - goto err; - - return 0; -err: - cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); + cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); return ret; } EXPORT_SYMBOL(rdma_resolve_addr); @@ -3563,7 +3453,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) goto err1; memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr)); - if (!cma_any_addr(addr)) { + if (!cma_zero_addr(addr)) { ret = cma_translate_addr(addr, &id->route.addr.dev_addr); if (ret) goto err1; -- 1.8.3.1