rxrpc: Fix error reception on AF_INET6 sockets
[ 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 <dhowells@redhat.com> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b5b3188098
commit
b2abd2b98a
@ -133,22 +133,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
/* 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;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* set the socket up */
|
||||
|
Loading…
x
Reference in New Issue
Block a user