svn commit: r341533 - in head/sys: compat/linuxkpi/common/include/linux ofed/drivers/infiniband/core

Slava Shwartsman slavash at FreeBSD.org
Wed Dec 5 13:24:44 UTC 2018


Author: slavash
Date: Wed Dec  5 13:24:43 2018
New Revision: 341533
URL: https://svnweb.freebsd.org/changeset/base/341533

Log:
  ibcore: ip6_dev_find() needs to know the scope ID.
  
  Else the wrong network device can be returned for link-local addresses.
  
  Submitted by:   hselasky@
  Approved by:    hselasky (mentor)
  MFC after:      1 week
  Sponsored by:   Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/linux/inetdevice.h
  head/sys/ofed/drivers/infiniband/core/ib_addr.c
  head/sys/ofed/drivers/infiniband/core/ib_cma.c

Modified: head/sys/compat/linuxkpi/common/include/linux/inetdevice.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/inetdevice.h	Wed Dec  5 13:24:12 2018	(r341532)
+++ head/sys/compat/linuxkpi/common/include/linux/inetdevice.h	Wed Dec  5 13:24:43 2018	(r341533)
@@ -59,37 +59,32 @@ ip_dev_find(struct vnet *vnet, uint32_t addr)
 }
 
 static inline struct net_device *
-ip6_dev_find(struct vnet *vnet, struct in6_addr addr)
+ip6_dev_find(struct vnet *vnet, struct in6_addr addr, uint16_t scope_id)
 {
 	struct sockaddr_in6 sin6;
-	struct ifaddr *ifa = NULL;
-	struct ifnet *ifp = NULL;
-	int x;
+	struct ifaddr *ifa;
+	struct ifnet *ifp;
 
 	memset(&sin6, 0, sizeof(sin6));
 	sin6.sin6_addr = addr;
 	sin6.sin6_len = sizeof(sin6);
 	sin6.sin6_family = AF_INET6;
-	NET_EPOCH_ENTER();
-	CURVNET_SET_QUIET(vnet);
 	if (IN6_IS_SCOPE_LINKLOCAL(&addr) ||
 	    IN6_IS_ADDR_MC_INTFACELOCAL(&addr)) {
-		/* XXX need to search all scope ID's */
-		for (x = 0; x <= V_if_index && x < 65536; x++) {
-			sin6.sin6_addr.s6_addr16[1] = htons(x);
-			ifa = ifa_ifwithaddr((struct sockaddr *)&sin6);
-			if (ifa != NULL)
-				break;
-		}
-	} else {
-		ifa = ifa_ifwithaddr((struct sockaddr *)&sin6);
+		/* embed the IPv6 scope ID */
+		sin6.sin6_addr.s6_addr16[1] = htons(scope_id);
 	}
+	NET_EPOCH_ENTER();
+	CURVNET_SET_QUIET(vnet);
+	ifa = ifa_ifwithaddr((struct sockaddr *)&sin6);
+	CURVNET_RESTORE();
 	if (ifa != NULL) {
 		ifp = ifa->ifa_ifp;
 		if_ref(ifp);
+	} else {
+		ifp = NULL;
 	}
 	NET_EPOCH_EXIT();
-	CURVNET_RESTORE();
 	return (ifp);
 }
 

Modified: head/sys/ofed/drivers/infiniband/core/ib_addr.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_addr.c	Wed Dec  5 13:24:12 2018	(r341532)
+++ head/sys/ofed/drivers/infiniband/core/ib_addr.c	Wed Dec  5 13:24:43 2018	(r341533)
@@ -185,7 +185,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
 #ifdef INET6
 	case AF_INET6:
 		dev = ip6_dev_find(dev_addr->net,
-			((const struct sockaddr_in6 *)addr)->sin6_addr);
+			((const struct sockaddr_in6 *)addr)->sin6_addr, 0);
 		break;
 #endif
 	default:
@@ -525,7 +525,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		if (addr->bound_dev_if != 0) {
 			ifp = dev_get_by_index(addr->net, addr->bound_dev_if);
 		} else {
-			ifp = ip6_dev_find(addr->net, src_in->sin6_addr);
+			ifp = ip6_dev_find(addr->net, src_in->sin6_addr, 0);
 		}
 
 		/* check source interface */

Modified: head/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Dec  5 13:24:12 2018	(r341532)
+++ head/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Dec  5 13:24:43 2018	(r341533)
@@ -1329,7 +1329,8 @@ static bool validate_ipv6_net_dev(struct net_device *n
 	struct rtentry *rte;
 	bool ret;
 
-	dst_dev = ip6_dev_find(net_dev->if_vnet, dst_tmp.sin6_addr);
+	dst_dev = ip6_dev_find(net_dev->if_vnet, dst_tmp.sin6_addr,
+	    net_dev->if_index);
 	if (dst_dev != net_dev) {
 		if (dst_dev != NULL)
 			dev_put(dst_dev);


More information about the svn-src-head mailing list