diff options
author | Paul Mundt <lethal@linux-sh.org> | 2012-01-09 11:12:55 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2012-01-09 11:12:55 +0900 |
commit | ca371d2854d48c0c22e7aa031df182f96dc85820 (patch) | |
tree | 1c62be8b4da0bfc82fa7ffa1ad5b0e958266cbd1 /drivers/infiniband/core/addr.c | |
parent | 0d376945d0bc0a8f8e00861d506b10e42e8af372 (diff) | |
parent | a0e86bd4252519321b0d102dc4ed90557aa7bee9 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into sh-latest
Conflicts:
arch/arm/mach-shmobile/clock-sh73a0.c
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/infiniband/core/addr.c')
-rw-r--r-- | drivers/infiniband/core/addr.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 691276bafd78..1612cfd50f39 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -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,18 +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)) { - neigh_event_send(dst_get_neighbour(&rt->dst), NULL); - 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: @@ -238,13 +245,12 @@ 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; memset(&fl6, 0, sizeof fl6); - ipv6_addr_copy(&fl6.daddr, &dst_in->sin6_addr); - ipv6_addr_copy(&fl6.saddr, &src_in->sin6_addr); + fl6.daddr = dst_in->sin6_addr; + fl6.saddr = src_in->sin6_addr; fl6.flowi6_oif = addr->bound_dev_if; dst = ip6_route_output(&init_net, NULL, &fl6); @@ -258,7 +264,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; src_in->sin6_family = AF_INET6; - ipv6_addr_copy(&src_in->sin6_addr, &fl6.saddr); + src_in->sin6_addr = fl6.saddr; } if (dst->dev->flags & IFF_LOOPBACK) { @@ -274,15 +280,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } - neigh = dst_get_neighbour(dst); - if (!neigh || !(neigh->nud_state & NUD_VALID)) { - if (neigh) - neigh_event_send(neigh, NULL); - ret = -ENODATA; - goto put; - } - - ret = rdma_copy_addr(addr, dst->dev, neigh->ha); + ret = dst_fetch_ha(dst, addr); put: dst_release(dst); return ret; |