diff mbox series

[07/20] lnet: ksocklnd: support IPv6 in ksocknal_ip2index()

Message ID 1665783491-13827-8-git-send-email-jsimmons@infradead.org (mailing list archive)
State New, archived
Headers show
Series lustre: backport OpenSFS work as of Oct 14, 2022 | expand

Commit Message

James Simmons Oct. 14, 2022, 9:37 p.m. UTC
From: Mr NeilBrown <neilb@suse.de>

ksocknal_ip2index() can now find the interface index for an IPv6
address.

WC-bug-id: https://jira.whamcloud.com/browse/LU-10391
Lustre-commit: c0fdf9efbf927db40 ("LU-10391 socklnd: support IPv6 in ksocknal_ip2index()")
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48570
Reviewed-by: jsimmons <jsimmons@infradead.org>
Reviewed-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Reviewed-by: Frank Sehr <fsehr@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Signed-off-by: James Simmons <jsimmons@infradead.org>
---
 net/lnet/klnds/socklnd/socklnd.c | 40 +++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/net/lnet/klnds/socklnd/socklnd.c b/net/lnet/klnds/socklnd/socklnd.c
index 69cb738796e7..89696977ac63 100644
--- a/net/lnet/klnds/socklnd/socklnd.c
+++ b/net/lnet/klnds/socklnd/socklnd.c
@@ -40,6 +40,7 @@ 
 #include <linux/ethtool.h>
 #include <linux/inetdevice.h>
 #include <linux/sunrpc/addr.h>
+#include <net/addrconf.h>
 #include "socklnd.h"
 
 static struct lnet_lnd the_ksocklnd;
@@ -79,8 +80,7 @@  static int ksocknal_ip2index(struct sockaddr *addr, struct lnet_ni *ni)
 	int ret = -1;
 	const struct in_ifaddr *ifa;
 
-	if (addr->sa_family != AF_INET)
-		/* No IPv6 support yet */
+	if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
 		return ret;
 
 	rcu_read_lock();
@@ -94,14 +94,36 @@  static int ksocknal_ip2index(struct sockaddr *addr, struct lnet_ni *ni)
 		if (!(flags & IFF_UP))
 			continue;
 
-		in_dev = __in_dev_get_rcu(dev);
-		if (!in_dev)
-			continue;
+		switch (addr->sa_family) {
+		case AF_INET:
+			in_dev = __in_dev_get_rcu(dev);
+			if (!in_dev)
+				continue;
 
-		in_dev_for_each_ifa_rcu(ifa, in_dev) {
-			if (ifa->ifa_local ==
-			    ((struct sockaddr_in *)addr)->sin_addr.s_addr)
-				ret = dev->ifindex;
+			in_dev_for_each_ifa_rcu(ifa, in_dev) {
+				if (ifa->ifa_local ==
+				    ((struct sockaddr_in *)addr)->sin_addr.s_addr)
+					ret = dev->ifindex;
+			}
+			break;
+#if IS_ENABLED(CONFIG_IPV6)
+		case AF_INET6: {
+			struct inet6_dev *in6_dev;
+			const struct inet6_ifaddr *ifa6;
+			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
+
+			in6_dev = __in6_dev_get(dev);
+			if (!in6_dev)
+				continue;
+
+			list_for_each_entry_rcu(ifa6, &in6_dev->addr_list, if_list) {
+				if (ipv6_addr_cmp(&ifa6->addr,
+						  &addr6->sin6_addr) == 0)
+					ret = dev->ifindex;
+			}
+			break;
+			}
+#endif /* IS_ENABLED(CONFIG_IPV6) */
 		}
 		if (ret >= 0)
 			break;