xref: /freebsd/sys/ofed/drivers/infiniband/core/ib_addr.c (revision 3defe8195684c3ee4cf5295a58967e3face8dce1)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3  *
4  * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
5  * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
6  * Copyright (c) 1999-2019, Mellanox Technologies, Inc. All rights reserved.
7  * Copyright (c) 2005 Intel Corporation.  All rights reserved.
8  *
9  * This software is available to you under a choice of one of two
10  * licenses.  You may choose to be licensed under the terms of the GNU
11  * General Public License (GPL) Version 2, available from the file
12  * COPYING in the main directory of this source tree, or the
13  * OpenIB.org BSD license below:
14  *
15  *     Redistribution and use in source and binary forms, with or
16  *     without modification, are permitted provided that the following
17  *     conditions are met:
18  *
19  *      - Redistributions of source code must retain the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer.
22  *
23  *      - Redistributions in binary form must reproduce the above
24  *        copyright notice, this list of conditions and the following
25  *        disclaimer in the documentation and/or other materials
26  *        provided with the distribution.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
32  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
33  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35  * SOFTWARE.
36  */
37 
38 #include <sys/cdefs.h>
39 #include <linux/mutex.h>
40 #include <linux/slab.h>
41 #include <linux/workqueue.h>
42 #include <linux/module.h>
43 #include <net/if_llatbl.h>
44 #include <net/route.h>
45 #include <net/route/nhop.h>
46 #include <net/netevent.h>
47 #include <rdma/ib_addr.h>
48 #include <rdma/ib_cache.h>
49 #include <rdma/ib_sa.h>
50 #include <rdma/ib.h>
51 
52 #include <netinet/in_fib.h>
53 #include <netinet/if_ether.h>
54 #include <netinet/ip_var.h>
55 #include <netinet6/scope6_var.h>
56 #include <netinet6/in6_pcb.h>
57 #include <netinet6/in6_fib.h>
58 
59 #include "core_priv.h"
60 
61 struct addr_req {
62 	struct list_head list;
63 	struct sockaddr_storage src_addr;
64 	struct sockaddr_storage dst_addr;
65 	struct rdma_dev_addr *addr;
66 	void *context;
67 	void (*callback)(int status, struct sockaddr *src_addr,
68 			 struct rdma_dev_addr *addr, void *context);
69 	unsigned long timeout;
70 	struct delayed_work work;
71 	bool resolve_by_gid_attr;	/* Consider gid attr in resolve phase */
72 	int status;
73 };
74 
75 static DEFINE_SPINLOCK(lock);
76 static LIST_HEAD(req_list);
77 static struct workqueue_struct *addr_wq;
78 
rdma_addr_size(const struct sockaddr * addr)79 int rdma_addr_size(const struct sockaddr *addr)
80 {
81 	switch (addr->sa_family) {
82 	case AF_INET:
83 		return sizeof(struct sockaddr_in);
84 	case AF_INET6:
85 		return sizeof(struct sockaddr_in6);
86 	case AF_IB:
87 		return sizeof(struct sockaddr_ib);
88 	default:
89 		return 0;
90 	}
91 }
92 EXPORT_SYMBOL(rdma_addr_size);
93 
rdma_addr_size_in6(struct sockaddr_in6 * addr)94 int rdma_addr_size_in6(struct sockaddr_in6 *addr)
95 {
96 	int ret = rdma_addr_size((struct sockaddr *) addr);
97 
98 	return ret <= sizeof(*addr) ? ret : 0;
99 }
100 EXPORT_SYMBOL(rdma_addr_size_in6);
101 
rdma_addr_size_kss(struct sockaddr_storage * addr)102 int rdma_addr_size_kss(struct sockaddr_storage *addr)
103 {
104 	int ret = rdma_addr_size((struct sockaddr *) addr);
105 
106 	return ret <= sizeof(*addr) ? ret : 0;
107 }
108 EXPORT_SYMBOL(rdma_addr_size_kss);
109 
110 static inline void
rdma_copy_addr_sub(u8 * dst,const u8 * src,unsigned min,unsigned max)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 /**
120  * rdma_copy_src_l2_addr - Copy netdevice source addresses
121  * @dev_addr:	Destination address pointer where to copy the addresses
122  * @dev:	Netdevice whose source addresses to copy
123  *
124  * rdma_copy_src_l2_addr() copies source addresses from the specified netdevice.
125  * This includes unicast address, broadcast address, device type and
126  * interface index.
127  */
rdma_copy_src_l2_addr(struct rdma_dev_addr * dev_addr,const if_t dev)128 void rdma_copy_src_l2_addr(struct rdma_dev_addr *dev_addr,
129 			   const if_t dev)
130 {
131 	int dev_type = if_gettype(dev);
132 
133 	/* check for loopback device */
134 	if (if_getflags(dev) & IFF_LOOPBACK) {
135 		dev_addr->dev_type = ARPHRD_ETHER;
136 		memset(dev_addr->src_dev_addr, 0, MAX_ADDR_LEN);
137 		memset(dev_addr->broadcast, 0, MAX_ADDR_LEN);
138 		memset(dev_addr->dst_dev_addr, 0, MAX_ADDR_LEN);
139 		dev_addr->bound_dev_if = if_getindex(dev);
140 		return;
141 	} else if (dev_type == IFT_INFINIBAND)
142 		dev_addr->dev_type = ARPHRD_INFINIBAND;
143 	else if (dev_type == IFT_ETHER || dev_type == IFT_L2VLAN)
144 		dev_addr->dev_type = ARPHRD_ETHER;
145 	else
146 		dev_addr->dev_type = 0;
147 	rdma_copy_addr_sub(dev_addr->src_dev_addr, if_getlladdr(dev),
148 			   if_getaddrlen(dev), MAX_ADDR_LEN);
149 	rdma_copy_addr_sub(dev_addr->broadcast, if_getbroadcastaddr(dev),
150 			   if_getaddrlen(dev), MAX_ADDR_LEN);
151 	dev_addr->bound_dev_if = if_getindex(dev);
152 }
153 EXPORT_SYMBOL(rdma_copy_src_l2_addr);
154 
155 static if_t
rdma_find_ndev_for_src_ip_rcu(struct vnet * net,const struct sockaddr * src_in)156 rdma_find_ndev_for_src_ip_rcu(struct vnet *net, const struct sockaddr *src_in)
157 {
158 	if_t dev = NULL;
159 	int ret = -EADDRNOTAVAIL;
160 
161 	switch (src_in->sa_family) {
162 #ifdef INET
163 	case AF_INET:
164 		dev = ip_ifp_find(net,
165 			((const struct sockaddr_in *)src_in)->sin_addr.s_addr);
166 		if (dev)
167 			ret = 0;
168 		break;
169 #endif
170 #ifdef INET6
171 	case AF_INET6:
172 		dev = ip6_ifp_find(net,
173 			((const struct sockaddr_in6 *)src_in)->sin6_addr, 0);
174 		if (dev)
175 			ret = 0;
176 		break;
177 #endif
178 	}
179 	return ret ? ERR_PTR(ret) : dev;
180 }
181 
rdma_translate_ip(const struct sockaddr * addr,struct rdma_dev_addr * dev_addr)182 int rdma_translate_ip(const struct sockaddr *addr,
183 		      struct rdma_dev_addr *dev_addr)
184 {
185 	if_t dev;
186 	int ret = 0;
187 
188 	if (dev_addr->bound_dev_if) {
189 		dev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if);
190 		if (!dev)
191 			return -ENODEV;
192 	} else {
193 		rcu_read_lock();
194 		dev = rdma_find_ndev_for_src_ip_rcu(dev_addr->net, addr);
195 		rcu_read_unlock();
196 		if (IS_ERR(dev))
197 			return PTR_ERR(dev);
198 	}
199 
200 	/* disallow connections through 127.0.0.1 itself */
201 	if (if_getflags(dev) & IFF_LOOPBACK)
202 		ret = -EINVAL;
203 	else
204 		rdma_copy_src_l2_addr(dev_addr, dev);
205 	dev_put(dev);
206 	return ret;
207 }
208 EXPORT_SYMBOL(rdma_translate_ip);
209 
set_timeout(struct addr_req * req,unsigned long time)210 static void set_timeout(struct addr_req *req, unsigned long time)
211 {
212 	unsigned long delay;
213 
214 	delay = time - jiffies;
215 	if (delay <= 0)
216 		delay = 1;
217 	else if (delay > hz)
218 		delay = hz;
219 
220 	mod_delayed_work(addr_wq, &req->work, delay);
221 }
222 
queue_req(struct addr_req * req)223 static void queue_req(struct addr_req *req)
224 {
225 	spin_lock_bh(&lock);
226 	list_add_tail(&req->list, &req_list);
227 	set_timeout(req, req->timeout);
228 	spin_unlock_bh(&lock);
229 }
230 
231 #if defined(INET) || defined(INET6)
addr_resolve_multi(u8 * edst,if_t ifp,struct sockaddr * dst_in)232 static int addr_resolve_multi(u8 *edst, if_t ifp, struct sockaddr *dst_in)
233 {
234 	struct sockaddr *llsa;
235 	struct sockaddr_dl sdl;
236 	int error;
237 
238 	sdl.sdl_len = sizeof(sdl);
239 	llsa = (struct sockaddr *)&sdl;
240 
241 	error = if_resolvemulti(ifp, &llsa, dst_in);
242 	if (error == 0) {
243 		rdma_copy_addr_sub(edst, LLADDR((struct sockaddr_dl *)llsa),
244 		    if_getaddrlen(ifp), MAX_ADDR_LEN);
245 	}
246 	return (error);
247 }
248 #endif
249 
250 #ifdef INET
addr4_resolve(struct sockaddr * src_sock,const struct sockaddr * dst_sock,struct rdma_dev_addr * addr,u8 * edst,if_t * ifpp)251 static int addr4_resolve(struct sockaddr *src_sock,
252 			 const struct sockaddr *dst_sock,
253 			 struct rdma_dev_addr *addr,
254 			 u8 *edst,
255 			 if_t *ifpp)
256 {
257 	struct sockaddr_in *src_in = (struct sockaddr_in *)src_sock;
258 	const struct sockaddr_in *dst_in =
259 			(const struct sockaddr_in *)dst_sock;
260 	enum {
261 		ADDR_VALID = 0,
262 		ADDR_SRC_ANY = 1,
263 		ADDR_DST_ANY = 2,
264 	};
265 	struct sockaddr_in dst_tmp = *dst_in;
266 	in_port_t src_port;
267 	struct sockaddr *saddr = NULL;
268 	struct nhop_object *nh;
269 	if_t ifp;
270 	int error;
271 	int type;
272 
273 	NET_EPOCH_ASSERT();
274 
275 	/* set VNET, if any */
276 	CURVNET_SET(addr->net);
277 
278 	/* set default TTL limit */
279 	addr->hoplimit = V_ip_defttl;
280 
281 	type = ADDR_VALID;
282 	if (src_in->sin_addr.s_addr == INADDR_ANY)
283 		type |= ADDR_SRC_ANY;
284 	if (dst_tmp.sin_addr.s_addr == INADDR_ANY)
285 		type |= ADDR_DST_ANY;
286 
287 	/*
288 	 * Make sure the socket address length field is set.
289 	 */
290 	dst_tmp.sin_len = sizeof(dst_tmp);
291 
292 	/* Step 1 - lookup destination route if any */
293 	switch (type) {
294 	case ADDR_VALID:
295 	case ADDR_SRC_ANY:
296 		/* regular destination route lookup */
297 		nh = fib4_lookup(RT_DEFAULT_FIB, dst_tmp.sin_addr,0,NHR_NONE,0);
298 		if (nh == NULL) {
299 			error = EHOSTUNREACH;
300 			goto done;
301 		}
302 		break;
303 	default:
304 		error = ENETUNREACH;
305 		goto done;
306 	}
307 
308 	/* Step 2 - find outgoing network interface */
309 	switch (type) {
310 	case ADDR_VALID:
311 		/* get source interface */
312 		if (addr->bound_dev_if != 0) {
313 			ifp = dev_get_by_index(addr->net, addr->bound_dev_if);
314 		} else {
315 			ifp = ip_ifp_find(addr->net, src_in->sin_addr.s_addr);
316 		}
317 
318 		/* check source interface */
319 		if (ifp == NULL) {
320 			error = ENETUNREACH;
321 			goto done;
322 		} else if (if_getflags(ifp) & IFF_LOOPBACK) {
323 			/*
324 			 * Source address cannot be a loopback device.
325 			 */
326 			error = EHOSTUNREACH;
327 			goto error_put_ifp;
328 		} else if (if_getflags(nh->nh_ifp) & IFF_LOOPBACK) {
329 			if (memcmp(&src_in->sin_addr, &dst_in->sin_addr,
330 			    sizeof(src_in->sin_addr))) {
331 				/*
332 				 * Destination is loopback, but source
333 				 * and destination address is not the
334 				 * same.
335 				 */
336 				error = EHOSTUNREACH;
337 				goto error_put_ifp;
338 			}
339 			/* get destination network interface from route */
340 			dev_put(ifp);
341 			ifp = nh->nh_ifp;
342 			dev_hold(ifp);
343 		} else if (ifp != nh->nh_ifp) {
344 			/*
345 			 * Source and destination interfaces are
346 			 * different.
347 			 */
348 			error = ENETUNREACH;
349 			goto error_put_ifp;
350 		}
351 		break;
352 	case ADDR_SRC_ANY:
353 		/* check for loopback device */
354 		if (if_getflags(nh->nh_ifp) & IFF_LOOPBACK)
355 			saddr = (struct sockaddr *)&dst_tmp;
356 		else
357 			saddr = nh->nh_ifa->ifa_addr;
358 
359 		/* get destination network interface from route */
360 		ifp = nh->nh_ifp;
361 		dev_hold(ifp);
362 		break;
363 	default:
364 		break;
365 	}
366 
367 	/*
368 	 * Step 3 - resolve destination MAC address
369 	 */
370 	if (dst_tmp.sin_addr.s_addr == INADDR_BROADCAST) {
371 		rdma_copy_addr_sub(edst, if_getbroadcastaddr(ifp),
372 		    if_getaddrlen(ifp), MAX_ADDR_LEN);
373 		error = 0;
374 	} else if (IN_MULTICAST(ntohl(dst_tmp.sin_addr.s_addr))) {
375 		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
376 		error = addr_resolve_multi(edst, ifp, (struct sockaddr *)&dst_tmp);
377 		if (error != 0)
378 			goto error_put_ifp;
379 		else if (is_gw)
380 			addr->network = RDMA_NETWORK_IPV4;
381 	} else if (if_getflags(ifp) & IFF_LOOPBACK) {
382 		memset(edst, 0, MAX_ADDR_LEN);
383 		error = 0;
384 	} else {
385 		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
386 		memset(edst, 0, MAX_ADDR_LEN);
387 #ifdef INET6
388 		if (is_gw && nh->gw_sa.sa_family == AF_INET6)
389 			error = nd6_resolve(ifp, LLE_SF(AF_INET, is_gw), NULL,
390 			    &nh->gw_sa, edst, NULL, NULL);
391 		else
392 #endif
393 			error = arpresolve(ifp, is_gw, NULL, is_gw ?
394 			    &nh->gw_sa : (const struct sockaddr *)&dst_tmp,
395 			    edst, NULL, NULL);
396 
397 		if (error != 0)
398 			goto error_put_ifp;
399 		else if (is_gw)
400 			addr->network = RDMA_NETWORK_IPV4;
401 	}
402 
403 	/*
404 	 * Step 4 - update source address, if any
405 	 */
406 	if (saddr != NULL) {
407 		src_port = src_in->sin_port;
408 		memcpy(src_in, saddr, rdma_addr_size(saddr));
409 		src_in->sin_port = src_port;	/* preserve port number */
410 	}
411 
412 	*ifpp = ifp;
413 
414 	goto done;
415 
416 error_put_ifp:
417 	dev_put(ifp);
418 done:
419 	CURVNET_RESTORE();
420 
421 	if (error == EWOULDBLOCK || error == EAGAIN)
422 		error = ENODATA;
423 	return (-error);
424 }
425 #else
addr4_resolve(struct sockaddr * src_sock,const struct sockaddr * dst_sock,struct rdma_dev_addr * addr,u8 * edst,if_t * ifpp)426 static int addr4_resolve(struct sockaddr *src_sock,
427 			 const struct sockaddr *dst_sock,
428 			 struct rdma_dev_addr *addr,
429 			 u8 *edst,
430 			 if_t *ifpp)
431 {
432 	return -EADDRNOTAVAIL;
433 }
434 #endif
435 
436 #ifdef INET6
addr6_resolve(struct sockaddr * src_sock,const struct sockaddr * dst_sock,struct rdma_dev_addr * addr,u8 * edst,if_t * ifpp)437 static int addr6_resolve(struct sockaddr *src_sock,
438 			 const struct sockaddr *dst_sock,
439 			 struct rdma_dev_addr *addr,
440 			 u8 *edst,
441 			 if_t *ifpp)
442 {
443 	struct sockaddr_in6 *src_in = (struct sockaddr_in6 *)src_sock;
444 	const struct sockaddr_in6 *dst_in =
445 				(const struct sockaddr_in6 *)dst_sock;
446 	enum {
447 		ADDR_VALID = 0,
448 		ADDR_SRC_ANY = 1,
449 		ADDR_DST_ANY = 2,
450 	};
451 	struct sockaddr_in6 dst_tmp = *dst_in;
452 	in_port_t src_port;
453 	struct sockaddr *saddr = NULL;
454 	struct nhop_object *nh;
455 	if_t ifp;
456 	int error;
457 	int type;
458 
459 	NET_EPOCH_ASSERT();
460 
461 	/* set VNET, if any */
462 	CURVNET_SET(addr->net);
463 
464 	/* set default TTL limit */
465 	addr->hoplimit = V_ip_defttl;
466 
467 	type = ADDR_VALID;
468 	if (ipv6_addr_any(&src_in->sin6_addr))
469 		type |= ADDR_SRC_ANY;
470 	if (ipv6_addr_any(&dst_tmp.sin6_addr))
471 		type |= ADDR_DST_ANY;
472 
473 	/*
474 	 * Make sure the socket address length field is set.
475 	 */
476 	dst_tmp.sin6_len = sizeof(dst_tmp);
477 
478 	/*
479 	 * Make sure the scope ID gets embedded, else nd6_resolve() will
480 	 * not find the record.
481 	 */
482 	dst_tmp.sin6_scope_id = addr->bound_dev_if;
483 	sa6_embedscope(&dst_tmp, 0);
484 
485 	/* Step 1 - lookup destination route if any */
486 	switch (type) {
487 	case ADDR_VALID:
488 		/* sanity check for IPv4 addresses */
489 		if (ipv6_addr_v4mapped(&src_in->sin6_addr) !=
490 		    ipv6_addr_v4mapped(&dst_tmp.sin6_addr)) {
491 			error = EAFNOSUPPORT;
492 			goto done;
493 		}
494 		/* FALLTHROUGH */
495 	case ADDR_SRC_ANY:
496 		/* regular destination route lookup */
497 		nh = fib6_lookup(RT_DEFAULT_FIB, &dst_in->sin6_addr,
498 		    addr->bound_dev_if, NHR_NONE, 0);
499 		if (nh == NULL) {
500 			error = EHOSTUNREACH;
501 			goto done;
502 		}
503 		break;
504 	default:
505 		error = ENETUNREACH;
506 		goto done;
507 	}
508 
509 	/* Step 2 - find outgoing network interface */
510 	switch (type) {
511 	case ADDR_VALID:
512 		/* get source interface */
513 		if (addr->bound_dev_if != 0) {
514 			ifp = dev_get_by_index(addr->net, addr->bound_dev_if);
515 		} else {
516 			ifp = ip6_ifp_find(addr->net, src_in->sin6_addr, 0);
517 		}
518 
519 		/* check source interface */
520 		if (ifp == NULL) {
521 			error = ENETUNREACH;
522 			goto done;
523 		} else if (if_getflags(ifp) & IFF_LOOPBACK) {
524 			/*
525 			 * Source address cannot be a loopback device.
526 			 */
527 			error = EHOSTUNREACH;
528 			goto error_put_ifp;
529 		} else if (if_getflags(nh->nh_ifp) & IFF_LOOPBACK) {
530 			if (memcmp(&src_in->sin6_addr, &dst_in->sin6_addr,
531 			    sizeof(src_in->sin6_addr))) {
532 				/*
533 				 * Destination is loopback, but source
534 				 * and destination address is not the
535 				 * same.
536 				 */
537 				error = EHOSTUNREACH;
538 				goto error_put_ifp;
539 			}
540 			/* get destination network interface from route */
541 			dev_put(ifp);
542 			ifp = nh->nh_ifp;
543 			dev_hold(ifp);
544 		} else if (ifp != nh->nh_ifp) {
545 			/*
546 			 * Source and destination interfaces are
547 			 * different.
548 			 */
549 			error = ENETUNREACH;
550 			goto error_put_ifp;
551 		}
552 		break;
553 	case ADDR_SRC_ANY:
554 		/* check for loopback device */
555 		if (if_getflags(nh->nh_ifp) & IFF_LOOPBACK)
556 			saddr = (struct sockaddr *)&dst_tmp;
557 		else
558 			saddr = nh->nh_ifa->ifa_addr;
559 
560 		/* get destination network interface from route */
561 		ifp = nh->nh_ifp;
562 		dev_hold(ifp);
563 		break;
564 	default:
565 		break;
566 	}
567 
568 	/*
569 	 * Step 3 - resolve destination MAC address
570 	 */
571 	if (IN6_IS_ADDR_MULTICAST(&dst_tmp.sin6_addr)) {
572 		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
573 		error = addr_resolve_multi(edst, ifp,
574 		    (struct sockaddr *)&dst_tmp);
575 		if (error != 0)
576 			goto error_put_ifp;
577 		else if (is_gw)
578 			addr->network = RDMA_NETWORK_IPV6;
579 	} else if (if_getflags(nh->nh_ifp) & IFF_LOOPBACK) {
580 		memset(edst, 0, MAX_ADDR_LEN);
581 		error = 0;
582 	} else {
583 		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
584 		memset(edst, 0, MAX_ADDR_LEN);
585 		error = nd6_resolve(ifp, LLE_SF(AF_INET6, is_gw), NULL,
586 		    is_gw ? &nh->gw_sa : (const struct sockaddr *)&dst_tmp,
587 		    edst, NULL, NULL);
588 		if (error != 0)
589 			goto error_put_ifp;
590 		else if (is_gw)
591 			addr->network = RDMA_NETWORK_IPV6;
592 	}
593 
594 	/*
595 	 * Step 4 - update source address, if any
596 	 */
597 	if (saddr != NULL) {
598 		src_port = src_in->sin6_port;
599 		memcpy(src_in, saddr, rdma_addr_size(saddr));
600 		src_in->sin6_port = src_port;	/* preserve port number */
601 	}
602 
603 	*ifpp = ifp;
604 
605 	goto done;
606 
607 error_put_ifp:
608 	dev_put(ifp);
609 done:
610 	CURVNET_RESTORE();
611 
612 	if (error == EWOULDBLOCK || error == EAGAIN)
613 		error = ENODATA;
614 	return (-error);
615 }
616 #else
addr6_resolve(struct sockaddr * src_sock,const struct sockaddr * dst_sock,struct rdma_dev_addr * addr,u8 * edst,if_t * ifpp)617 static int addr6_resolve(struct sockaddr *src_sock,
618 			 const struct sockaddr *dst_sock,
619 			 struct rdma_dev_addr *addr,
620 			 u8 *edst,
621 			 if_t *ifpp)
622 {
623 	return -EADDRNOTAVAIL;
624 }
625 #endif
626 
addr_resolve_neigh(if_t dev,const struct sockaddr * dst_in,u8 * edst,struct rdma_dev_addr * addr,unsigned int ndev_flags)627 static int addr_resolve_neigh(if_t dev,
628 			      const struct sockaddr *dst_in,
629 			      u8 *edst,
630 			      struct rdma_dev_addr *addr,
631 			      unsigned int ndev_flags)
632 {
633 	int ret = 0;
634 
635 	if (ndev_flags & IFF_LOOPBACK) {
636 		/*
637 		 * Binding to a loopback device is not allowed. Make
638 		 * sure the destination device address is global by
639 		 * clearing the bound device interface:
640 		 */
641 		if (addr->bound_dev_if == if_getindex(dev))
642 			addr->bound_dev_if = 0;
643 
644 		memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
645 	} else {
646 		if (!(ndev_flags & IFF_NOARP)) {
647 			/* If the device doesn't do ARP internally */
648 			memcpy(addr->dst_dev_addr, edst, MAX_ADDR_LEN);
649 		}
650         }
651 
652 	return ret;
653 }
654 
copy_src_l2_addr(struct rdma_dev_addr * dev_addr,const struct sockaddr * dst_in,if_t ndev)655 static int copy_src_l2_addr(struct rdma_dev_addr *dev_addr,
656 			    const struct sockaddr *dst_in,
657 			    if_t ndev)
658 {
659 	int ret = 0;
660 
661 	if (if_getflags(ndev) & IFF_LOOPBACK)
662 		ret = rdma_translate_ip(dst_in, dev_addr);
663 	else
664 		rdma_copy_src_l2_addr(dev_addr, ndev);
665 
666 	return ret;
667 }
668 
rdma_set_src_addr_rcu(struct rdma_dev_addr * dev_addr,unsigned int * ndev_flags,const struct sockaddr * dst_in,if_t ndev)669 static int rdma_set_src_addr_rcu(struct rdma_dev_addr *dev_addr,
670 				 unsigned int *ndev_flags,
671 				 const struct sockaddr *dst_in,
672 				 if_t ndev)
673 {
674 	*ndev_flags = if_getflags(ndev);
675 	/* A physical device must be the RDMA device to use */
676 	if (if_getflags(ndev) & IFF_LOOPBACK) {
677 		/*
678 		 * RDMA (IB/RoCE, iWarp) doesn't run on lo interface or
679 		 * loopback IP address. So if route is resolved to loopback
680 		 * interface, translate that to a real ndev based on non
681 		 * loopback IP address.
682 		 */
683 		ndev = rdma_find_ndev_for_src_ip_rcu(dev_net(ndev), dst_in);
684 		if (!ndev)
685 			return -ENODEV;
686 	}
687 
688 	return copy_src_l2_addr(dev_addr, dst_in, ndev);
689 }
690 
set_addr_netns_by_gid_rcu(struct rdma_dev_addr * addr)691 static int set_addr_netns_by_gid_rcu(struct rdma_dev_addr *addr)
692 {
693 	if_t ndev;
694 
695 	ndev = rdma_read_gid_attr_ndev_rcu(addr->sgid_attr);
696 	if (IS_ERR(ndev))
697 		return PTR_ERR(ndev);
698 
699 	/*
700 	 * Since we are holding the rcu, reading net and ifindex
701 	 * are safe without any additional reference; because
702 	 * change_net_namespace() in net/core/ib_dev.c does rcu sync
703 	 * after it changes the state to IFF_DOWN and before
704 	 * updating netdev fields {net, ifindex}.
705 	 */
706 	addr->net = dev_net(ndev);
707 	addr->bound_dev_if = if_getindex(ndev);
708 	return 0;
709 }
710 
rdma_addr_set_net_defaults(struct rdma_dev_addr * addr)711 static void rdma_addr_set_net_defaults(struct rdma_dev_addr *addr)
712 {
713 	addr->net = &init_net;
714 	addr->bound_dev_if = 0;
715 }
716 
addr_resolve(struct sockaddr * src_in,const struct sockaddr * dst_in,struct rdma_dev_addr * addr,bool resolve_by_gid_attr)717 static int addr_resolve(struct sockaddr *src_in,
718 			const struct sockaddr *dst_in,
719 			struct rdma_dev_addr *addr,
720 			bool resolve_by_gid_attr)
721 {
722 	struct epoch_tracker et;
723 	if_t ndev = NULL;
724 	u8 edst[MAX_ADDR_LEN];
725 	unsigned int ndev_flags = 0;
726 	int ret;
727 
728 	if (dst_in->sa_family != src_in->sa_family)
729 		return -EINVAL;
730 
731 	NET_EPOCH_ENTER(et);
732 	if (resolve_by_gid_attr) {
733 		if (!addr->sgid_attr) {
734 			NET_EPOCH_EXIT(et);
735 			pr_warn_ratelimited("%s: missing gid_attr\n", __func__);
736 			return -EINVAL;
737 		}
738 		/*
739 		 * If the request is for a specific gid attribute of the
740 		 * rdma_dev_addr, derive net from the netdevice of the
741 		 * GID attribute.
742 		 */
743 		ret = set_addr_netns_by_gid_rcu(addr);
744 		if (ret) {
745 			NET_EPOCH_EXIT(et);
746 			return ret;
747 		}
748 	}
749 	switch (src_in->sa_family) {
750 	case AF_INET:
751 		ret = addr4_resolve(src_in, dst_in, addr, edst, &ndev);
752 		break;
753 	case AF_INET6:
754 		ret = addr6_resolve(src_in, dst_in, addr, edst, &ndev);
755 		break;
756 	default:
757 		ret = -EADDRNOTAVAIL;
758 		break;
759 	}
760 	if (ret) {
761 		NET_EPOCH_EXIT(et);
762 		goto done;
763 	}
764 	ret = rdma_set_src_addr_rcu(addr, &ndev_flags, dst_in, ndev);
765 	NET_EPOCH_EXIT(et);
766 
767 	/* store MAC addresses and check for loopback */
768 	if (!ret)
769 		ret = addr_resolve_neigh(ndev, dst_in, edst, addr, ndev_flags);
770 
771 	/* set belonging VNET, if any */
772 	addr->net = dev_net(ndev);
773 	dev_put(ndev);
774 done:
775 	/*
776 	 * Clear the addr net to go back to its original state, only if it was
777 	 * derived from GID attribute in this context.
778 	 */
779 	if (resolve_by_gid_attr)
780 		rdma_addr_set_net_defaults(addr);
781 	return ret;
782 }
783 
process_one_req(struct work_struct * _work)784 static void process_one_req(struct work_struct *_work)
785 {
786 	struct addr_req *req;
787 	struct sockaddr *src_in, *dst_in;
788 
789 	req = container_of(_work, struct addr_req, work.work);
790 
791 	if (req->status == -ENODATA) {
792 		src_in = (struct sockaddr *)&req->src_addr;
793 		dst_in = (struct sockaddr *)&req->dst_addr;
794 		req->status = addr_resolve(src_in, dst_in, req->addr,
795 					   req->resolve_by_gid_attr);
796 		if (req->status && time_after_eq(jiffies, req->timeout)) {
797 			req->status = -ETIMEDOUT;
798 		} else if (req->status == -ENODATA) {
799 			/* requeue the work for retrying again */
800 			spin_lock_bh(&lock);
801 			if (!list_empty(&req->list))
802 				set_timeout(req, req->timeout);
803 			spin_unlock_bh(&lock);
804 			return;
805 		}
806 	}
807 
808 	req->callback(req->status, (struct sockaddr *)&req->src_addr,
809 		req->addr, req->context);
810 	req->callback = NULL;
811 
812 	spin_lock_bh(&lock);
813 	if (!list_empty(&req->list)) {
814 		/*
815 		 * Although the work will normally have been canceled by the
816 		 * workqueue, it can still be requeued as long as it is on the
817 		 * req_list.
818 		 */
819 		cancel_delayed_work(&req->work);
820 		list_del_init(&req->list);
821 		kfree(req);
822 	}
823 	spin_unlock_bh(&lock);
824 }
825 
rdma_resolve_ip(struct sockaddr * src_addr,const struct sockaddr * dst_addr,struct rdma_dev_addr * addr,int timeout_ms,void (* callback)(int status,struct sockaddr * src_addr,struct rdma_dev_addr * addr,void * context),bool resolve_by_gid_attr,void * context)826 int rdma_resolve_ip(struct sockaddr *src_addr, const struct sockaddr *dst_addr,
827 		    struct rdma_dev_addr *addr, int timeout_ms,
828 		    void (*callback)(int status, struct sockaddr *src_addr,
829 				     struct rdma_dev_addr *addr, void *context),
830 		    bool resolve_by_gid_attr,
831 		    void *context)
832 {
833 	struct sockaddr *src_in, *dst_in;
834 	struct addr_req *req;
835 	int ret = 0;
836 
837 	req = kzalloc(sizeof *req, GFP_KERNEL);
838 	if (!req)
839 		return -ENOMEM;
840 
841 	src_in = (struct sockaddr *) &req->src_addr;
842 	dst_in = (struct sockaddr *) &req->dst_addr;
843 
844 	if (src_addr) {
845 		if (src_addr->sa_family != dst_addr->sa_family) {
846 			ret = -EINVAL;
847 			goto err;
848 		}
849 
850 		memcpy(src_in, src_addr, rdma_addr_size(src_addr));
851 	} else {
852 		src_in->sa_family = dst_addr->sa_family;
853 	}
854 
855 	memcpy(dst_in, dst_addr, rdma_addr_size(dst_addr));
856 	req->addr = addr;
857 	req->callback = callback;
858 	req->context = context;
859 	req->resolve_by_gid_attr = resolve_by_gid_attr;
860 	INIT_DELAYED_WORK(&req->work, process_one_req);
861 
862 	req->status = addr_resolve(src_in, dst_in, addr,
863 				   req->resolve_by_gid_attr);
864 	switch (req->status) {
865 	case 0:
866 		req->timeout = jiffies;
867 		queue_req(req);
868 		break;
869 	case -ENODATA:
870 		req->timeout = msecs_to_jiffies(timeout_ms) + jiffies;
871 		queue_req(req);
872 		break;
873 	default:
874 		ret = req->status;
875 		goto err;
876 	}
877 	return ret;
878 err:
879 	kfree(req);
880 	return ret;
881 }
882 EXPORT_SYMBOL(rdma_resolve_ip);
883 
roce_resolve_route_from_path(struct sa_path_rec * rec,const struct ib_gid_attr * attr)884 int roce_resolve_route_from_path(struct sa_path_rec *rec,
885 				 const struct ib_gid_attr *attr)
886 {
887 	union rdma_sockaddr sgid, dgid;
888 	struct rdma_dev_addr dev_addr = {};
889 	int ret;
890 
891 	if (rec->roce.route_resolved)
892 		return 0;
893 
894 	rdma_gid2ip(&sgid._sockaddr, &rec->sgid);
895 	rdma_gid2ip(&dgid._sockaddr, &rec->dgid);
896 
897 	if (sgid._sockaddr.sa_family != dgid._sockaddr.sa_family)
898 		return -EINVAL;
899 
900 	if (!attr || !attr->ndev)
901 		return -EINVAL;
902 
903 	dev_addr.net = &init_net;
904 	dev_addr.sgid_attr = attr;
905 
906 	ret = addr_resolve(&sgid._sockaddr, &dgid._sockaddr,
907 			   &dev_addr, true);
908 	if (ret)
909 		return ret;
910 
911 	if ((dev_addr.network == RDMA_NETWORK_IPV4 ||
912 	     dev_addr.network == RDMA_NETWORK_IPV6) &&
913 	    rec->rec_type != SA_PATH_REC_TYPE_ROCE_V2)
914 		return -EINVAL;
915 
916 	rec->roce.route_resolved = true;
917 	return 0;
918 }
919 
920 /**
921  * rdma_addr_cancel - Cancel resolve ip request
922  * @addr:	Pointer to address structure given previously
923  *		during rdma_resolve_ip().
924  * rdma_addr_cancel() is synchronous function which cancels any pending
925  * request if there is any.
926  */
rdma_addr_cancel(struct rdma_dev_addr * addr)927 void rdma_addr_cancel(struct rdma_dev_addr *addr)
928 {
929 	struct addr_req *req, *temp_req;
930 	struct addr_req *found = NULL;
931 
932 	spin_lock_bh(&lock);
933 	list_for_each_entry_safe(req, temp_req, &req_list, list) {
934 		if (req->addr == addr) {
935 			/*
936 			 * Removing from the list means we take ownership of
937 			 * the req
938 			 */
939 			list_del_init(&req->list);
940 			found = req;
941 			break;
942 		}
943 	}
944 	spin_unlock_bh(&lock);
945 
946 	if (!found)
947 		return;
948 
949 	/*
950 	 * sync canceling the work after removing it from the req_list
951 	 * guarentees no work is running and none will be started.
952 	 */
953 	cancel_delayed_work_sync(&found->work);
954 	kfree(found);
955 }
956 EXPORT_SYMBOL(rdma_addr_cancel);
957 
958 struct resolve_cb_context {
959 	struct completion comp;
960 	int status;
961 };
962 
resolve_cb(int status,struct sockaddr * src_addr,struct rdma_dev_addr * addr,void * context)963 static void resolve_cb(int status, struct sockaddr *src_addr,
964 	     struct rdma_dev_addr *addr, void *context)
965 {
966 	((struct resolve_cb_context *)context)->status = status;
967 	complete(&((struct resolve_cb_context *)context)->comp);
968 }
969 
rdma_addr_find_l2_eth_by_grh(const union ib_gid * sgid,const union ib_gid * dgid,u8 * dmac,const struct ib_gid_attr * sgid_attr,int * hoplimit)970 int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
971 				 const union ib_gid *dgid,
972 				 u8 *dmac, const struct ib_gid_attr *sgid_attr,
973 				 int *hoplimit)
974 {
975 	struct rdma_dev_addr dev_addr;
976 	struct resolve_cb_context ctx;
977 	union rdma_sockaddr sgid_addr, dgid_addr;
978 	int ret;
979 
980 	rdma_gid2ip(&sgid_addr._sockaddr, sgid);
981 	rdma_gid2ip(&dgid_addr._sockaddr, dgid);
982 
983 	memset(&dev_addr, 0, sizeof(dev_addr));
984 	dev_addr.net = &init_net;
985 	dev_addr.sgid_attr = sgid_attr;
986 
987 	init_completion(&ctx.comp);
988 	ret = rdma_resolve_ip(&sgid_addr._sockaddr, &dgid_addr._sockaddr,
989 			      &dev_addr, 1000, resolve_cb, true, &ctx);
990 	if (ret)
991 		return ret;
992 
993 	wait_for_completion(&ctx.comp);
994 
995 	ret = ctx.status;
996 	if (ret)
997 		return ret;
998 
999 	memcpy(dmac, dev_addr.dst_dev_addr, ETH_ALEN);
1000 	*hoplimit = dev_addr.hoplimit;
1001 	return 0;
1002 }
1003 
addr_init(void)1004 int addr_init(void)
1005 {
1006 	addr_wq = alloc_ordered_workqueue("ib_addr", WQ_MEM_RECLAIM);
1007 	if (!addr_wq)
1008 		return -ENOMEM;
1009 
1010 	return 0;
1011 }
1012 
addr_cleanup(void)1013 void addr_cleanup(void)
1014 {
1015 	destroy_workqueue(addr_wq);
1016 	WARN_ON(!list_empty(&req_list));
1017 }
1018