Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1bc6422 authored by David Howells's avatar David Howells Committed by Greg Kroah-Hartman
Browse files

rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket



commit 37a675e7 upstream.

It seems that enabling IPV6_RECVERR on an IPv6 socket doesn't also turn on
IP_RECVERR, so neither local errors nor ICMP-transported remote errors from
IPv4 peer addresses are returned to the AF_RXRPC protocol.

Make the sockopt setting code in rxrpc_open_socket() fall through from the
AF_INET6 case to the AF_INET case to turn on all the AF_INET options too in
the AF_INET6 case.

Fixes: f2aeed3a ("rxrpc: Fix error reception on AF_INET6 sockets")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 60f4dba7
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -134,10 +134,10 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
	}

	switch (local->srx.transport.family) {
	case AF_INET:
		/* we want to receive ICMP errors */
	case AF_INET6:
		/* we want to receive ICMPv6 errors */
		opt = 1;
		ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
		ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");
@@ -145,19 +145,22 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
		}

		/* we want to set the don't fragment bit */
		opt = IP_PMTUDISC_DO;
		ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
		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;

	case AF_INET6:
		/* Fall through and set IPv4 options too otherwise we don't get
		 * errors from IPv4 packets sent through the IPv6 socket.
		 */

	case AF_INET:
		/* we want to receive ICMP errors */
		opt = 1;
		ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
		ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");
@@ -165,8 +168,8 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
		}

		/* we want to set the don't fragment bit */
		opt = IPV6_PMTUDISC_DO;
		ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
		opt = IP_PMTUDISC_DO;
		ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");