Whamcloud - gitweb
LU-14477 lnet: handle possiblity of IPv6 being unavailable. 91/41791/5
authorMr NeilBrown <neilb@suse.de>
Mon, 1 Mar 2021 00:54:25 +0000 (11:54 +1100)
committerOleg Drokin <green@whamcloud.com>
Wed, 10 Mar 2021 08:03:31 +0000 (08:03 +0000)
If CONFIG_IPV6 is not enabled, the attempt to create an IPv6 socket
for accepting new incoming connections will fail.  In that case
we need to creae an IPv4 socket instead.

Also ipv6_dev_get_saddr will not be available, so we must not include
the code that tries to use it.

Test-Parameters: trivial
Fixes: e4fa181abf10 ("LU-10391 lnet: allow creation of IPv6 socket")
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: Ib576c7ea498c90f549958f3c1aa0beb7fe2b66ad
Reviewed-on: https://review.whamcloud.com/41791
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/lnet/lib-socket.c

index 97eef28..f087710 100644 (file)
@@ -194,11 +194,17 @@ lnet_sock_create(int interface, struct sockaddr *remaddr,
        family = AF_INET6;
        if (remaddr)
                family = remaddr->sa_family;
        family = AF_INET6;
        if (remaddr)
                family = remaddr->sa_family;
+retry:
 #ifdef HAVE_SOCK_CREATE_KERN_USE_NET
        rc = sock_create_kern(ns, family, SOCK_STREAM, 0, &sock);
 #else
        rc = sock_create_kern(family, SOCK_STREAM, 0, &sock);
 #endif
 #ifdef HAVE_SOCK_CREATE_KERN_USE_NET
        rc = sock_create_kern(ns, family, SOCK_STREAM, 0, &sock);
 #else
        rc = sock_create_kern(family, SOCK_STREAM, 0, &sock);
 #endif
+       if (rc == -EAFNOSUPPORT && family == AF_INET6 && !remaddr) {
+               family = AF_INET;
+               goto retry;
+       }
+
        if (rc) {
                CERROR("Can't create socket: %d\n", rc);
                return ERR_PTR(rc);
        if (rc) {
                CERROR("Can't create socket: %d\n", rc);
                return ERR_PTR(rc);
@@ -208,11 +214,11 @@ lnet_sock_create(int interface, struct sockaddr *remaddr,
 
        if (interface >= 0 || local_port != 0) {
                struct sockaddr_storage locaddr = {};
 
        if (interface >= 0 || local_port != 0) {
                struct sockaddr_storage locaddr = {};
-               struct sockaddr_in *sin = (void *)&locaddr;
-               struct sockaddr_in6 *sin6 = (void *)&locaddr;
 
                switch (family) {
 
                switch (family) {
-               case AF_INET:
+               case AF_INET: {
+                       struct sockaddr_in *sin = (void *)&locaddr;
+
                        sin->sin_family = AF_INET;
                        sin->sin_addr.s_addr = INADDR_ANY;
                        if (interface >= 0 && remaddr) {
                        sin->sin_family = AF_INET;
                        sin->sin_addr.s_addr = INADDR_ANY;
                        if (interface >= 0 && remaddr) {
@@ -229,7 +235,11 @@ lnet_sock_create(int interface, struct sockaddr *remaddr,
                        }
                        sin->sin_port = htons(local_port);
                        break;
                        }
                        sin->sin_port = htons(local_port);
                        break;
-               case AF_INET6:
+               }
+#if IS_ENABLED(CONFIG_IPV6)
+               case AF_INET6: {
+                       struct sockaddr_in6 *sin6 = (void *)&locaddr;
+
                        sin6->sin6_family = AF_INET6;
                        sin6->sin6_addr = in6addr_any;
                        if (interface >= 0 && remaddr) {
                        sin6->sin6_family = AF_INET6;
                        sin6->sin6_addr = in6addr_any;
                        if (interface >= 0 && remaddr) {
@@ -244,6 +254,8 @@ lnet_sock_create(int interface, struct sockaddr *remaddr,
                        sin6->sin6_port = htons(local_port);
                        break;
                }
                        sin6->sin6_port = htons(local_port);
                        break;
                }
+#endif /* IS_ENABLED(CONFIG_IPV6) */
+               }
                rc = kernel_bind(sock, (struct sockaddr *)&locaddr,
                                 sizeof(locaddr));
                if (rc == -EADDRINUSE) {
                rc = kernel_bind(sock, (struct sockaddr *)&locaddr,
                                 sizeof(locaddr));
                if (rc == -EADDRINUSE) {