Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Sep 2017 12:50:13 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r323364 - head/sys/compat/linuxkpi/common/include/linux
Message-ID:  <201709091250.v89CoDeF015759@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Sat Sep  9 12:50:12 2017
New Revision: 323364
URL: https://svnweb.freebsd.org/changeset/base/323364

Log:
  Only search the scope ID in ip6_find_dev() for IPv6 addresses which
  have a scope ID. Change size of the searched scope ID to the full
  16-bits. There can typically be more than 255 interfaces.
  
  Suggested by:		ae @
  MFC after:		1 week
  Sponsored by:		Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/linux/inetdevice.h

Modified: head/sys/compat/linuxkpi/common/include/linux/inetdevice.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/inetdevice.h	Sat Sep  9 11:56:48 2017	(r323363)
+++ head/sys/compat/linuxkpi/common/include/linux/inetdevice.h	Sat Sep  9 12:50:12 2017	(r323364)
@@ -61,7 +61,7 @@ static inline struct net_device *
 ip6_dev_find(struct vnet *vnet, struct in6_addr addr)
 {
 	struct sockaddr_in6 sin6;
-	struct ifaddr *ifa;
+	struct ifaddr *ifa = NULL;
 	struct ifnet *ifp = NULL;
 	int x;
 
@@ -70,16 +70,22 @@ ip6_dev_find(struct vnet *vnet, struct in6_addr addr)
 	sin6.sin6_len = sizeof(sin6);
 	sin6.sin6_family = AF_INET6;
 	CURVNET_SET_QUIET(vnet);
-	/* XXX need to search all scope ID's */
-	for (x = 0; x <= V_if_index; x++) {
-		sin6.sin6_addr.s6_addr[3] = x;
-		ifa = ifa_ifwithaddr((struct sockaddr *)&sin6);
-		if (ifa != NULL) {
-			ifp = ifa->ifa_ifp;
-			if_ref(ifp);
-			ifa_free(ifa);
-			break;
+	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);
+	}
+	if (ifa != NULL) {
+		ifp = ifa->ifa_ifp;
+		if_ref(ifp);
+		ifa_free(ifa);
 	}
 	CURVNET_RESTORE();
 	return (ifp);



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