1 /*
2  * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
3  * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
4  * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved.
5  * Copyright (c) 2005 Intel Corporation.  All rights reserved.
6  *
7  * This software is available to you under a choice of one of two
8  * licenses.  You may choose to be licensed under the terms of the GNU
9  * General Public License (GPL) Version 2, available from the file
10  * COPYING in the main directory of this source tree, or the
11  * OpenIB.org BSD license below:
12  *
13  *     Redistribution and use in source and binary forms, with or
14  *     without modification, are permitted provided that the following
15  *     conditions are met:
16  *
17  *      - Redistributions of source code must retain the above
18  *        copyright notice, this list of conditions and the following
19  *        disclaimer.
20  *
21  *      - Redistributions in binary form must reproduce the above
22  *        copyright notice, this list of conditions and the following
23  *        disclaimer in the documentation and/or other materials
24  *        provided with the distribution.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33  * SOFTWARE.
34  */
35 
36 #include <linux/mutex.h>
37 #include <linux/inetdevice.h>
38 #include <linux/slab.h>
39 #include <linux/workqueue.h>
40 #include <linux/module.h>
41 #include <net/route.h>
42 #include <net/netevent.h>
43 #include <rdma/ib_addr.h>
44 #include <rdma/ib.h>
45 
46 #include <netinet/if_ether.h>
47 #include <netinet/ip_var.h>
48 #include <netinet6/scope6_var.h>
49 #include <netinet6/in6_pcb.h>
50 
51 #include "core_priv.h"
52 
53 struct addr_req {
54 	struct list_head list;
55 	struct sockaddr_storage src_addr;
56 	struct sockaddr_storage dst_addr;
57 	struct rdma_dev_addr *addr;
58 	struct rdma_addr_client *client;
59 	void *context;
60 	void (*callback)(int status, struct sockaddr *src_addr,
61 			 struct rdma_dev_addr *addr, void *context);
62 	unsigned long timeout;
63 	int status;
64 };
65 
66 static void process_req(struct work_struct *work);
67 
68 static DEFINE_MUTEX(lock);
69 static LIST_HEAD(req_list);
70 static DECLARE_DELAYED_WORK(work, process_req);
71 static struct workqueue_struct *addr_wq;
72 
73 int rdma_addr_size(struct sockaddr *addr)
74 {
75 	switch (addr->sa_family) {
76 	case AF_INET:
77 		return sizeof(struct sockaddr_in);
78 	case AF_INET6:
79 		return sizeof(struct sockaddr_in6);
80 	case AF_IB:
81 		return sizeof(struct sockaddr_ib);
82 	default:
83 		return 0;
84 	}
85 }
86 EXPORT_SYMBOL(rdma_addr_size);
87 
88 static struct rdma_addr_client self;
89 
90 void rdma_addr_register_client(struct rdma_addr_client *client)
91 {
92 	atomic_set(&client->refcount, 1);
93 	init_completion(&client->comp);
94 }
95 EXPORT_SYMBOL(rdma_addr_register_client);
96 
97 static inline void put_client(struct rdma_addr_client *client)
98 {
99 	if (atomic_dec_and_test(&client->refcount))
100 		complete(&client->comp);
101 }
102 
103 void rdma_addr_unregister_client(struct rdma_addr_client *client)
104 {
105 	put_client(client);
106 	wait_for_completion(&client->comp);
107 }
108 EXPORT_SYMBOL(rdma_addr_unregister_client);
109 
110 static inline void
111 rdma_copy_addr_sub(u8 *dst, const u8 *src, unsigned min, unsigned max)
112 {
113 	if (min > max)
114 		min = max;
115 	memcpy(dst, src, min);
116 	memset(dst + min, 0, max - min);
117 }
118 
119 int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
120 		     const unsigned char *dst_dev_addr)
121 {
122 	if (dev->if_type == IFT_INFINIBAND)
123 		dev_addr->dev_type = ARPHRD_INFINIBAND;
124 	else if (dev->if_type == IFT_ETHER)
125 		dev_addr->dev_type = ARPHRD_ETHER;
126 	else
127 		dev_addr->dev_type = 0;
128 	rdma_copy_addr_sub(dev_addr->src_dev_addr, IF_LLADDR(dev),
129 			   dev->if_addrlen, MAX_ADDR_LEN);
130 	rdma_copy_addr_sub(dev_addr->broadcast, dev->if_broadcastaddr,
131 			   dev->if_addrlen, MAX_ADDR_LEN);
132 	if (dst_dev_addr != NULL) {
133 		rdma_copy_addr_sub(dev_addr->dst_dev_addr, dst_dev_addr,
134 				   dev->if_addrlen, MAX_ADDR_LEN);
135 	}
136 	dev_addr->bound_dev_if = dev->if_index;
137 	return 0;
138 }
139 EXPORT_SYMBOL(rdma_copy_addr);
140 
141 int rdma_translate_ip(const struct sockaddr *addr,
142 		      struct rdma_dev_addr *dev_addr,
143 		      u16 *vlan_id)
144 {
145 	struct net_device *dev = NULL;
146 	int ret = -EADDRNOTAVAIL;
147 
148 	if (dev_addr->bound_dev_if) {
149 		dev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if);
150 		if (!dev)
151 			return -ENODEV;
152 		ret = rdma_copy_addr(dev_addr, dev, NULL);
153 		dev_put(dev);
154 		return ret;
155 	}
156 
157 	switch (addr->sa_family) {
158 #ifdef INET
159 	case AF_INET:
160 		dev = ip_dev_find(dev_addr->net,
161 			((const struct sockaddr_in *)addr)->sin_addr.s_addr);
162 		break;
163 #endif
164 #ifdef INET6
165 	case AF_INET6: {
166 		struct in6_addr in6_addr = ((const struct sockaddr_in6 *)addr)->sin6_addr;
167 
168 		/* embed scope ID */
169 		in6_addr.s6_addr[3] = ((const struct sockaddr_in6 *)addr)->sin6_scope_id;
170 
171 		dev = ip6_dev_find(dev_addr->net, in6_addr);
172 		break;
173 	}
174 #endif
175 	default:
176 		break;
177 	}
178 
179 	if (dev != NULL) {
180 		ret = rdma_copy_addr(dev_addr, dev, NULL);
181 		if (vlan_id)
182 			*vlan_id = rdma_vlan_dev_vlan_id(dev);
183 		dev_put(dev);
184 	}
185 	return ret;
186 }
187 EXPORT_SYMBOL(rdma_translate_ip);
188 
189 static void set_timeout(unsigned long time)
190 {
191 	int delay;	/* under FreeBSD ticks are 32-bit */
192 
193 	delay = time - jiffies;
194 	if (delay <= 0)
195 		delay = 1;
196 
197 	mod_delayed_work(addr_wq, &work, delay);
198 }
199 
200 static void queue_req(struct addr_req *req)
201 {
202 	struct addr_req *temp_req;
203 
204 	mutex_lock(&lock);
205 	list_for_each_entry_reverse(temp_req, &req_list, list) {
206 		if (time_after_eq(req->timeout, temp_req->timeout))
207 			break;
208 	}
209 
210 	list_add(&req->list, &temp_req->list);
211 
212 	if (req_list.next == &req->list)
213 		set_timeout(req->timeout);
214 	mutex_unlock(&lock);
215 }
216 
217 #if defined(INET) || defined(INET6)
218 static int addr_resolve_multi(u8 *edst, struct ifnet *ifp, struct sockaddr *dst_in)
219 {
220 	struct sockaddr *llsa;
221 	struct sockaddr_dl sdl;
222 	int error;
223 
224 	sdl.sdl_len = sizeof(sdl);
225 	llsa = (struct sockaddr *)&sdl;
226 
227 	if (ifp->if_resolvemulti == NULL) {
228 		error = EOPNOTSUPP;
229 	} else {
230 		error = ifp->if_resolvemulti(ifp, &llsa, dst_in);
231 		if (error == 0) {
232 			rdma_copy_addr_sub(edst, LLADDR((struct sockaddr_dl *)llsa),
233 			    ifp->if_addrlen, MAX_ADDR_LEN);
234 		}
235 	}
236 	return (error);
237 }
238 #endif
239 
240 #ifdef INET
241 static int addr4_resolve(struct sockaddr_in *src_in,
242 			 const struct sockaddr_in *dst_in,
243 			 struct rdma_dev_addr *addr,
244 			 struct ifnet **ifpp)
245 {
246 	struct sockaddr_in dst_tmp = *dst_in;
247 	u8 edst[MAX_ADDR_LEN];
248 	struct rtentry *rte;
249 	struct ifnet *ifp;
250 	int error;
251 
252 	/*
253 	 * Make sure the socket address length field
254 	 * is set, else rtalloc1() will fail.
255 	 */
256 	dst_tmp.sin_len = sizeof(dst_tmp);
257 
258 	CURVNET_SET(addr->net);
259 	/* set default TTL limit */
260 	addr->hoplimit = V_ip_defttl;
261 
262 	/* lookup route for destination */
263 	rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
264 	CURVNET_RESTORE();
265 
266 	/*
267 	 * Make sure the route exists and has a valid link.
268 	 */
269 	if (rte == NULL) {
270 		error = EHOSTUNREACH;
271 		goto done;
272 	} else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 0) {
273 		RTFREE_LOCKED(rte);
274 		error = EHOSTUNREACH;
275 		goto done;
276 	} else if (src_in->sin_addr.s_addr != INADDR_ANY) {
277 		RT_UNLOCK(rte);
278 
279 		ifp = ip_dev_find(addr->net, src_in->sin_addr.s_addr);
280 		if (ifp == NULL) {
281 			RTFREE(rte);
282 			error = ENETUNREACH;
283 			goto done;
284 		} else if (ifp != rte->rt_ifp) {
285 			error = ENETUNREACH;
286 			goto failure;
287 		}
288 	} else {
289 		struct sockaddr *saddr;
290 
291 		ifp = rte->rt_ifp;
292 		dev_hold(ifp);
293 
294 		saddr = rte->rt_ifa->ifa_addr;
295 		memcpy(src_in, saddr, rdma_addr_size(saddr));
296 		RT_UNLOCK(rte);
297 	}
298 
299 	/*
300 	 * Resolve destination MAC address
301 	 */
302 	if (dst_tmp.sin_addr.s_addr == INADDR_BROADCAST) {
303 		rdma_copy_addr_sub(edst, ifp->if_broadcastaddr,
304 	            ifp->if_addrlen, MAX_ADDR_LEN);
305 	} else if (IN_MULTICAST(ntohl(dst_tmp.sin_addr.s_addr))) {
306 		error = addr_resolve_multi(edst, ifp, (struct sockaddr *)&dst_tmp);
307 		if (error != 0)
308 			goto failure;
309 	} else {
310 		bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
311 		memset(edst, 0, sizeof(edst));
312 		error = arpresolve(ifp, is_gw, NULL, is_gw ?
313 		    rte->rt_gateway : (const struct sockaddr *)&dst_tmp,
314 		    edst, NULL, NULL);
315 		if (error != 0)
316 			goto failure;
317 		else if (is_gw != 0)
318 			addr->network = RDMA_NETWORK_IPV4;
319 	}
320 
321 	/*
322 	 * Copy destination and source MAC addresses
323 	 */
324 	error = -rdma_copy_addr(addr, ifp, edst);
325 	if (error != 0) {
326 failure:
327 		dev_put(ifp);
328 
329 		if (error == EWOULDBLOCK || error == EAGAIN)
330 			error = ENODATA;
331 	} else {
332 		*ifpp = ifp;
333 	}
334 	RTFREE(rte);
335 done:
336 	return (-error);
337 }
338 #else
339 static int addr4_resolve(struct sockaddr_in *src_in,
340 			 const struct sockaddr_in *dst_in,
341 			 struct rdma_dev_addr *addr,
342 			 struct ifnet **ifpp)
343 {
344 	return -EADDRNOTAVAIL;
345 }
346 #endif
347 
348 #ifdef INET6
349 static int addr6_resolve(struct sockaddr_in6 *src_in,
350 			 const struct sockaddr_in6 *dst_in,
351 			 struct rdma_dev_addr *addr,
352 			 struct ifnet **ifpp)
353 {
354 	struct sockaddr_in6 dst_tmp = *dst_in;
355 	u8 edst[MAX_ADDR_LEN];
356 	struct rtentry *rte;
357 	struct ifnet *ifp;
358 	int error;
359 
360 	sa6_embedscope(&dst_tmp, 0);
361 	sa6_embedscope(src_in, 0);
362 
363 	/*
364 	 * Make sure the socket address length field
365 	 * is set, else rtalloc1() will fail.
366 	 */
367 	dst_tmp.sin6_len = sizeof(dst_tmp);
368 
369 	CURVNET_SET(addr->net);
370 	/* set default TTL limit */
371 	addr->hoplimit = V_ip_defttl;
372 
373 	/* lookup route for destination */
374 	rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
375 	CURVNET_RESTORE();
376 
377 	/*
378 	 * Make sure the route exists and has a valid link.
379 	 */
380 	if (rte == NULL) {
381 		error = EHOSTUNREACH;
382 		goto done;
383 	} else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 0) {
384 		RTFREE_LOCKED(rte);
385 		error = EHOSTUNREACH;
386 		goto done;
387 	} else if (!IN6_IS_ADDR_UNSPECIFIED(&src_in->sin6_addr)) {
388 		RT_UNLOCK(rte);
389 
390 		ifp = ip6_dev_find(addr->net, src_in->sin6_addr);
391 		if (ifp == NULL) {
392 			RTFREE(rte);
393 			error = ENETUNREACH;
394 			goto done;
395 		} else if (ifp != rte->rt_ifp) {
396 			error = ENETUNREACH;
397 			goto failure;
398 		}
399 	} else {
400 		struct sockaddr *saddr;
401 
402 		ifp = rte->rt_ifp;
403 		dev_hold(ifp);
404 
405 		saddr = rte->rt_ifa->ifa_addr;
406 		memcpy(src_in, saddr, rdma_addr_size(saddr));
407 		RT_UNLOCK(rte);
408 	}
409 
410 	/*
411 	 * Resolve destination MAC address
412 	 */
413 	if (IN6_IS_ADDR_MULTICAST(&dst_tmp.sin6_addr)) {
414 		error = addr_resolve_multi(edst, ifp, (struct sockaddr *)&dst_tmp);
415 		if (error != 0)
416 			goto failure;
417 	} else {
418 		bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
419 		memset(edst, 0, sizeof(edst));
420 		error = nd6_resolve(ifp, is_gw, NULL, is_gw ?
421 		    rte->rt_gateway : (const struct sockaddr *)&dst_tmp,
422 		    edst, NULL, NULL);
423 		if (error != 0)
424 			goto failure;
425 		else if (is_gw != 0)
426 			addr->network = RDMA_NETWORK_IPV6;
427 	}
428 
429 	/*
430 	 * Copy destination and source MAC addresses
431 	 */
432 	error = -rdma_copy_addr(addr, ifp, edst);
433 	if (error != 0) {
434 failure:
435 		dev_put(ifp);
436 
437 		if (error == EWOULDBLOCK || error == EAGAIN)
438 			error = ENODATA;
439 	} else {
440 		*ifpp = ifp;
441 	}
442 	RTFREE(rte);
443 done:
444 	sa6_recoverscope(&dst_tmp);
445 	sa6_recoverscope(src_in);
446 
447 	return (-error);
448 }
449 #else
450 static int addr6_resolve(struct sockaddr_in6 *src_in,
451 			 const struct sockaddr_in6 *dst_in,
452 			 struct rdma_dev_addr *addr,
453 			 struct ifnet **ifpp)
454 {
455 	return -EADDRNOTAVAIL;
456 }
457 #endif
458 
459 static int addr_resolve_neigh(struct ifnet *dev,
460 			      const struct sockaddr *dst_in,
461 			      struct rdma_dev_addr *addr)
462 {
463 	if (dev->if_flags & IFF_LOOPBACK) {
464 		int ret;
465 
466 		ret = rdma_translate_ip(dst_in, addr, NULL);
467 		if (!ret)
468 			memcpy(addr->dst_dev_addr, addr->src_dev_addr,
469 			       MAX_ADDR_LEN);
470 
471 		return ret;
472 	}
473 
474 	/* If the device doesn't do ARP internally */
475 	if (!(dev->if_flags & IFF_NOARP))
476 		return 0;
477 
478 	return rdma_copy_addr(addr, dev, NULL);
479 }
480 
481 static int addr_resolve(struct sockaddr *src_in,
482 			const struct sockaddr *dst_in,
483 			struct rdma_dev_addr *addr,
484 			bool resolve_neigh)
485 {
486 	struct net_device *ndev = NULL;
487 	int ret;
488 
489 	if (dst_in->sa_family != src_in->sa_family)
490 		return -EINVAL;
491 
492 	if (src_in->sa_family == AF_INET) {
493 		ret = addr4_resolve((struct sockaddr_in *)src_in,
494 				    (const struct sockaddr_in *)dst_in,
495 				    addr, &ndev);
496 		if (ret)
497 			return ret;
498 
499 		if (resolve_neigh)
500 			ret = addr_resolve_neigh(ndev, dst_in, addr);
501 	} else {
502 		ret = addr6_resolve((struct sockaddr_in6 *)src_in,
503 				    (const struct sockaddr_in6 *)dst_in, addr,
504 				    &ndev);
505 		if (ret)
506 			return ret;
507 
508 		if (resolve_neigh)
509 			ret = addr_resolve_neigh(ndev, dst_in, addr);
510 	}
511 
512 	addr->bound_dev_if = ndev->if_index;
513 	addr->net = dev_net(ndev);
514 	dev_put(ndev);
515 
516 	return ret;
517 }
518 
519 static void process_req(struct work_struct *work)
520 {
521 	struct addr_req *req, *temp_req;
522 	struct sockaddr *src_in, *dst_in;
523 	struct list_head done_list;
524 
525 	INIT_LIST_HEAD(&done_list);
526 
527 	mutex_lock(&lock);
528 	list_for_each_entry_safe(req, temp_req, &req_list, list) {
529 		if (req->status == -ENODATA) {
530 			src_in = (struct sockaddr *) &req->src_addr;
531 			dst_in = (struct sockaddr *) &req->dst_addr;
532 			req->status = addr_resolve(src_in, dst_in, req->addr,
533 						   true);
534 			if (req->status && time_after_eq(jiffies, req->timeout))
535 				req->status = -ETIMEDOUT;
536 			else if (req->status == -ENODATA)
537 				continue;
538 		}
539 		list_move_tail(&req->list, &done_list);
540 	}
541 
542 	if (!list_empty(&req_list)) {
543 		req = list_entry(req_list.next, struct addr_req, list);
544 		set_timeout(req->timeout);
545 	}
546 	mutex_unlock(&lock);
547 
548 	list_for_each_entry_safe(req, temp_req, &done_list, list) {
549 		list_del(&req->list);
550 		req->callback(req->status, (struct sockaddr *) &req->src_addr,
551 			req->addr, req->context);
552 		put_client(req->client);
553 		kfree(req);
554 	}
555 }
556 
557 int rdma_resolve_ip(struct rdma_addr_client *client,
558 		    struct sockaddr *src_addr, struct sockaddr *dst_addr,
559 		    struct rdma_dev_addr *addr, int timeout_ms,
560 		    void (*callback)(int status, struct sockaddr *src_addr,
561 				     struct rdma_dev_addr *addr, void *context),
562 		    void *context)
563 {
564 	struct sockaddr *src_in, *dst_in;
565 	struct addr_req *req;
566 	int ret = 0;
567 
568 	req = kzalloc(sizeof *req, GFP_KERNEL);
569 	if (!req)
570 		return -ENOMEM;
571 
572 	src_in = (struct sockaddr *) &req->src_addr;
573 	dst_in = (struct sockaddr *) &req->dst_addr;
574 
575 	if (src_addr) {
576 		if (src_addr->sa_family != dst_addr->sa_family) {
577 			ret = -EINVAL;
578 			goto err;
579 		}
580 
581 		memcpy(src_in, src_addr, rdma_addr_size(src_addr));
582 	} else {
583 		src_in->sa_family = dst_addr->sa_family;
584 	}
585 
586 	memcpy(dst_in, dst_addr, rdma_addr_size(dst_addr));
587 	req->addr = addr;
588 	req->callback = callback;
589 	req->context = context;
590 	req->client = client;
591 	atomic_inc(&client->refcount);
592 
593 	req->status = addr_resolve(src_in, dst_in, addr, true);
594 	switch (req->status) {
595 	case 0:
596 		req->timeout = jiffies;
597 		queue_req(req);
598 		break;
599 	case -ENODATA:
600 		req->timeout = msecs_to_jiffies(timeout_ms) + jiffies;
601 		queue_req(req);
602 		break;
603 	default:
604 		ret = req->status;
605 		atomic_dec(&client->refcount);
606 		goto err;
607 	}
608 	return ret;
609 err:
610 	kfree(req);
611 	return ret;
612 }
613 EXPORT_SYMBOL(rdma_resolve_ip);
614 
615 int rdma_resolve_ip_route(struct sockaddr *src_addr,
616 			  const struct sockaddr *dst_addr,
617 			  struct rdma_dev_addr *addr)
618 {
619 	struct sockaddr_storage ssrc_addr = {};
620 	struct sockaddr *src_in = (struct sockaddr *)&ssrc_addr;
621 
622 	if (src_addr) {
623 		if (src_addr->sa_family != dst_addr->sa_family)
624 			return -EINVAL;
625 
626 		memcpy(src_in, src_addr, rdma_addr_size(src_addr));
627 	} else {
628 		src_in->sa_family = dst_addr->sa_family;
629 	}
630 
631 	return addr_resolve(src_in, dst_addr, addr, false);
632 }
633 EXPORT_SYMBOL(rdma_resolve_ip_route);
634 
635 void rdma_addr_cancel(struct rdma_dev_addr *addr)
636 {
637 	struct addr_req *req, *temp_req;
638 
639 	mutex_lock(&lock);
640 	list_for_each_entry_safe(req, temp_req, &req_list, list) {
641 		if (req->addr == addr) {
642 			req->status = -ECANCELED;
643 			req->timeout = jiffies;
644 			list_move(&req->list, &req_list);
645 			set_timeout(req->timeout);
646 			break;
647 		}
648 	}
649 	mutex_unlock(&lock);
650 }
651 EXPORT_SYMBOL(rdma_addr_cancel);
652 
653 struct resolve_cb_context {
654 	struct rdma_dev_addr *addr;
655 	struct completion comp;
656 	int status;
657 };
658 
659 static void resolve_cb(int status, struct sockaddr *src_addr,
660 	     struct rdma_dev_addr *addr, void *context)
661 {
662 	if (!status)
663 		memcpy(((struct resolve_cb_context *)context)->addr,
664 		       addr, sizeof(struct rdma_dev_addr));
665 	((struct resolve_cb_context *)context)->status = status;
666 	complete(&((struct resolve_cb_context *)context)->comp);
667 }
668 
669 int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
670 				 const union ib_gid *dgid,
671 				 u8 *dmac, u16 *vlan_id, int *if_index,
672 				 int *hoplimit)
673 {
674 	int ret = 0;
675 	struct rdma_dev_addr dev_addr;
676 	struct resolve_cb_context ctx;
677 	struct net_device *dev;
678 
679 	union {
680 		struct sockaddr     _sockaddr;
681 		struct sockaddr_in  _sockaddr_in;
682 		struct sockaddr_in6 _sockaddr_in6;
683 	} sgid_addr, dgid_addr;
684 
685 
686 	rdma_gid2ip(&sgid_addr._sockaddr, sgid);
687 	rdma_gid2ip(&dgid_addr._sockaddr, dgid);
688 
689 	memset(&dev_addr, 0, sizeof(dev_addr));
690 	if (if_index)
691 		dev_addr.bound_dev_if = *if_index;
692 	dev_addr.net = TD_TO_VNET(curthread);
693 
694 	ctx.addr = &dev_addr;
695 	init_completion(&ctx.comp);
696 	ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
697 			&dev_addr, 1000, resolve_cb, &ctx);
698 	if (ret)
699 		return ret;
700 
701 	wait_for_completion(&ctx.comp);
702 
703 	ret = ctx.status;
704 	if (ret)
705 		return ret;
706 
707 	memcpy(dmac, dev_addr.dst_dev_addr, ETH_ALEN);
708 	dev = dev_get_by_index(dev_addr.net, dev_addr.bound_dev_if);
709 	if (!dev)
710 		return -ENODEV;
711 	if (if_index)
712 		*if_index = dev_addr.bound_dev_if;
713 	if (vlan_id)
714 		*vlan_id = rdma_vlan_dev_vlan_id(dev);
715 	if (hoplimit)
716 		*hoplimit = dev_addr.hoplimit;
717 	dev_put(dev);
718 	return ret;
719 }
720 EXPORT_SYMBOL(rdma_addr_find_l2_eth_by_grh);
721 
722 int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id)
723 {
724 	int ret = 0;
725 	struct rdma_dev_addr dev_addr;
726 	union {
727 		struct sockaddr     _sockaddr;
728 		struct sockaddr_in  _sockaddr_in;
729 		struct sockaddr_in6 _sockaddr_in6;
730 	} gid_addr;
731 
732 	rdma_gid2ip(&gid_addr._sockaddr, sgid);
733 
734 	memset(&dev_addr, 0, sizeof(dev_addr));
735 	dev_addr.net = TD_TO_VNET(curthread);
736 	ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id);
737 	if (ret)
738 		return ret;
739 
740 	memcpy(smac, dev_addr.src_dev_addr, ETH_ALEN);
741 	return ret;
742 }
743 EXPORT_SYMBOL(rdma_addr_find_smac_by_sgid);
744 
745 int addr_init(void)
746 {
747 	addr_wq = alloc_workqueue("ib_addr", WQ_MEM_RECLAIM, 0);
748 	if (!addr_wq)
749 		return -ENOMEM;
750 
751 	rdma_addr_register_client(&self);
752 
753 	return 0;
754 }
755 
756 void addr_cleanup(void)
757 {
758 	rdma_addr_unregister_client(&self);
759 	destroy_workqueue(addr_wq);
760 }
761