rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket
commit 37a675e768d7606fe8a53e0c459c9b53e121ac20 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: f2aeed3a591f ("rxrpc: Fix error reception on AF_INET6 sockets")
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
60f4dba707
commit
c1bc642250
1 changed files with 23 additions and 20 deletions
|
|
@ -134,6 +134,29 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
|
|||
}
|
||||
|
||||
switch (local->srx.transport.family) {
|
||||
case AF_INET6:
|
||||
/* we want to receive ICMPv6 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
|
@ -154,26 +177,6 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
|
|||
}
|
||||
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;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue