aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2011-12-02 11:52:14 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-05 15:20:19 -0500
commit51d45974515c35cd401f6194a6e728a2d1c3e3c6 (patch)
treefba3f62f38214870f4cd5de6a0796dd72cf9fa67 /drivers/infiniband
parent2721745501a26d0dc3b88c0d2f3aa11471891388 (diff)
infiniband: addr: Consolidate code to fetch neighbour hardware address from dst.
IPV4 should do exactly what the IPV6 code does here, which is use the neighbour obtained via the dst entry. And now that the two code paths do the same thing, use a common helper function to perform the operation. Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Acked-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/addr.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 70154f7e0415..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)
178 mutex_unlock(&lock); 178 mutex_unlock(&lock);
179} 179}
180 180
181static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr)
182{
183 struct neighbour *n;
184 int ret;
185
186 rcu_read_lock();
187 n = dst_get_neighbour_noref(dst);
188 if (!n || !(n->nud_state & NUD_VALID)) {
189 if (n)
190 neigh_event_send(n, NULL);
191 ret = -ENODATA;
192 } else {
193 ret = rdma_copy_addr(addr, dst->dev, n->ha);
194 }
195 rcu_read_unlock();
196
197 return ret;
198}
199
181static int addr4_resolve(struct sockaddr_in *src_in, 200static int addr4_resolve(struct sockaddr_in *src_in,
182 struct sockaddr_in *dst_in, 201 struct sockaddr_in *dst_in,
183 struct rdma_dev_addr *addr) 202 struct rdma_dev_addr *addr)
@@ -185,7 +204,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,
185 __be32 src_ip = src_in->sin_addr.s_addr; 204 __be32 src_ip = src_in->sin_addr.s_addr;
186 __be32 dst_ip = dst_in->sin_addr.s_addr; 205 __be32 dst_ip = dst_in->sin_addr.s_addr;
187 struct rtable *rt; 206 struct rtable *rt;
188 struct neighbour *neigh;
189 struct flowi4 fl4; 207 struct flowi4 fl4;
190 int ret; 208 int ret;
191 209
@@ -214,20 +232,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
214 goto put; 232 goto put;
215 } 233 }
216 234
217 neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); 235 ret = dst_fetch_ha(&rt->dst, addr);
218 if (!neigh || !(neigh->nud_state & NUD_VALID)) {
219 rcu_read_lock();
220 neigh_event_send(dst_get_neighbour_noref(&rt->dst), NULL);
221 rcu_read_unlock();
222 ret = -ENODATA;
223 if (neigh)
224 goto release;
225 goto put;
226 }
227
228 ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
229release:
230 neigh_release(neigh);
231put: 236put:
232 ip_rt_put(rt); 237 ip_rt_put(rt);
233out: 238out:
@@ -240,7 +245,6 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
240 struct rdma_dev_addr *addr) 245 struct rdma_dev_addr *addr)
241{ 246{
242 struct flowi6 fl6; 247 struct flowi6 fl6;
243 struct neighbour *neigh;
244 struct dst_entry *dst; 248 struct dst_entry *dst;
245 int ret; 249 int ret;
246 250
@@ -276,16 +280,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
276 goto put; 280 goto put;
277 } 281 }
278 282
279 rcu_read_lock(); 283 ret = dst_fetch_ha(dst, addr);
280 neigh = dst_get_neighbour_noref(dst);
281 if (!neigh || !(neigh->nud_state & NUD_VALID)) {
282 if (neigh)
283 neigh_event_send(neigh, NULL);
284 ret = -ENODATA;
285 } else {
286 ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
287 }
288 rcu_read_unlock();
289put: 284put:
290 dst_release(dst); 285 dst_release(dst);
291 return ret; 286 return ret;