infiniband: addr: Consolidate code to fetch neighbour hardware address from dst.
[~shefty/rdma-dev.git] / drivers / infiniband / core / addr.c
index 70154f7..1612cfd 100644 (file)
@@ -178,6 +178,25 @@ static void queue_req(struct addr_req *req)
        mutex_unlock(&lock);
 }
 
+static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr)
+{
+       struct neighbour *n;
+       int ret;
+
+       rcu_read_lock();
+       n = dst_get_neighbour_noref(dst);
+       if (!n || !(n->nud_state & NUD_VALID)) {
+               if (n)
+                       neigh_event_send(n, NULL);
+               ret = -ENODATA;
+       } else {
+               ret = rdma_copy_addr(addr, dst->dev, n->ha);
+       }
+       rcu_read_unlock();
+
+       return ret;
+}
+
 static int addr4_resolve(struct sockaddr_in *src_in,
                         struct sockaddr_in *dst_in,
                         struct rdma_dev_addr *addr)
@@ -185,7 +204,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,
        __be32 src_ip = src_in->sin_addr.s_addr;
        __be32 dst_ip = dst_in->sin_addr.s_addr;
        struct rtable *rt;
-       struct neighbour *neigh;
        struct flowi4 fl4;
        int ret;
 
@@ -214,20 +232,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                goto put;
        }
 
-       neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
-       if (!neigh || !(neigh->nud_state & NUD_VALID)) {
-               rcu_read_lock();
-               neigh_event_send(dst_get_neighbour_noref(&rt->dst), NULL);
-               rcu_read_unlock();
-               ret = -ENODATA;
-               if (neigh)
-                       goto release;
-               goto put;
-       }
-
-       ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
-release:
-       neigh_release(neigh);
+       ret = dst_fetch_ha(&rt->dst, addr);
 put:
        ip_rt_put(rt);
 out:
@@ -240,7 +245,6 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                         struct rdma_dev_addr *addr)
 {
        struct flowi6 fl6;
-       struct neighbour *neigh;
        struct dst_entry *dst;
        int ret;
 
@@ -276,16 +280,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                goto put;
        }
 
-       rcu_read_lock();
-       neigh = dst_get_neighbour_noref(dst);
-       if (!neigh || !(neigh->nud_state & NUD_VALID)) {
-               if (neigh)
-                       neigh_event_send(neigh, NULL);
-               ret = -ENODATA;
-       } else {
-               ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
-       }
-       rcu_read_unlock();
+       ret = dst_fetch_ha(dst, addr);
 put:
        dst_release(dst);
        return ret;