4.16-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Howells <dhowe...@redhat.com>

[ Upstream commit f2aeed3a591ff29a82495eeaa92ac4780bad7487 ]

AF_RXRPC tries to turn on IP_RECVERR and IP_MTU_DISCOVER on the UDP socket
it just opened for communications with the outside world, regardless of the
type of socket.  Unfortunately, this doesn't work with an AF_INET6 socket.

Fix this by turning on IPV6_RECVERR and IPV6_MTU_DISCOVER instead if the
socket is of the AF_INET6 family.

Without this, kAFS server and address rotation doesn't work correctly
because the algorithm doesn't detect received network errors.

Fixes: 75b54cb57ca3 ("rxrpc: Add IPv6 support")
Signed-off-by: David Howells <dhowe...@redhat.com>
Signed-off-by: Sasha Levin <alexander.le...@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 net/rxrpc/local_object.c |   57 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 15 deletions(-)

--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -133,22 +133,49 @@ static int rxrpc_open_socket(struct rxrp
                }
        }
 
-       /* we want to receive ICMP errors */
-       opt = 1;
-       ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
-                               (char *) &opt, sizeof(opt));
-       if (ret < 0) {
-               _debug("setsockopt failed");
-               goto error;
-       }
+       switch (local->srx.transport.family) {
+       case AF_INET:
+               /* we want to receive ICMP errors */
+               opt = 1;
+               ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
+                                       (char *) &opt, sizeof(opt));
+               if (ret < 0) {
+                       _debug("setsockopt failed");
+                       goto error;
+               }
+
+               /* we want to set the don't fragment bit */
+               opt = IP_PMTUDISC_DO;
+               ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
+                                       (char *) &opt, sizeof(opt));
+               if (ret < 0) {
+                       _debug("setsockopt failed");
+                       goto error;
+               }
+               break;
+
+       case AF_INET6:
+               /* we want to receive ICMP errors */
+               opt = 1;
+               ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
+                                       (char *) &opt, sizeof(opt));
+               if (ret < 0) {
+                       _debug("setsockopt failed");
+                       goto error;
+               }
+
+               /* we want to set the don't fragment bit */
+               opt = IPV6_PMTUDISC_DO;
+               ret = kernel_setsockopt(local->socket, SOL_IPV6, 
IPV6_MTU_DISCOVER,
+                                       (char *) &opt, sizeof(opt));
+               if (ret < 0) {
+                       _debug("setsockopt failed");
+                       goto error;
+               }
+               break;
 
-       /* we want to set the don't fragment bit */
-       opt = IP_PMTUDISC_DO;
-       ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
-                               (char *) &opt, sizeof(opt));
-       if (ret < 0) {
-               _debug("setsockopt failed");
-               goto error;
+       default:
+               BUG();
        }
 
        /* set the socket up */


Reply via email to