Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2018 11:14:52 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r341880 - in stable/11/sys: compat/linuxkpi/common/include/linux ofed/drivers/infiniband/core
Message-ID:  <201812121114.wBCBEqLC041056@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Wed Dec 12 11:14:52 2018
New Revision: 341880
URL: https://svnweb.freebsd.org/changeset/base/341880

Log:
  MFC r341533:
  ibcore: ip6_dev_find() needs to know the scope ID.
  
  Else the wrong network device can be returned for link-local addresses.
  
  Sponsored by:   Mellanox Technologies

Modified:
  stable/11/sys/compat/linuxkpi/common/include/linux/inetdevice.h
  stable/11/sys/ofed/drivers/infiniband/core/ib_addr.c
  stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/compat/linuxkpi/common/include/linux/inetdevice.h
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/include/linux/inetdevice.h	Wed Dec 12 11:02:48 2018	(r341879)
+++ stable/11/sys/compat/linuxkpi/common/include/linux/inetdevice.h	Wed Dec 12 11:14:52 2018	(r341880)
@@ -58,36 +58,31 @@ 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;
-	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);
 	}
+	CURVNET_SET_QUIET(vnet);
+	ifa = ifa_ifwithaddr((struct sockaddr *)&sin6);
+	CURVNET_RESTORE();
 	if (ifa != NULL) {
 		ifp = ifa->ifa_ifp;
 		if_ref(ifp);
 		ifa_free(ifa);
+	} else {
+		ifp = NULL;
 	}
-	CURVNET_RESTORE();
 	return (ifp);
 }
 

Modified: stable/11/sys/ofed/drivers/infiniband/core/ib_addr.c
==============================================================================
--- stable/11/sys/ofed/drivers/infiniband/core/ib_addr.c	Wed Dec 12 11:02:48 2018	(r341879)
+++ stable/11/sys/ofed/drivers/infiniband/core/ib_addr.c	Wed Dec 12 11:14:52 2018	(r341880)
@@ -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: stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Dec 12 11:02:48 2018	(r341879)
+++ stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Dec 12 11:14:52 2018	(r341880)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812121114.wBCBEqLC041056>