Skip to content

Commit f2aeed3

Browse files
committed
rxrpc: Fix error reception on AF_INET6 sockets
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: 75b54cb ("rxrpc: Add IPv6 support") Signed-off-by: David Howells <[email protected]>
1 parent c54e43d commit f2aeed3

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

net/rxrpc/local_object.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
134134
}
135135
}
136136

137-
/* we want to receive ICMP errors */
138-
opt = 1;
139-
ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
140-
(char *) &opt, sizeof(opt));
141-
if (ret < 0) {
142-
_debug("setsockopt failed");
143-
goto error;
144-
}
137+
switch (local->srx.transport.family) {
138+
case AF_INET:
139+
/* we want to receive ICMP errors */
140+
opt = 1;
141+
ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
142+
(char *) &opt, sizeof(opt));
143+
if (ret < 0) {
144+
_debug("setsockopt failed");
145+
goto error;
146+
}
145147

146-
/* we want to set the don't fragment bit */
147-
opt = IP_PMTUDISC_DO;
148-
ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
149-
(char *) &opt, sizeof(opt));
150-
if (ret < 0) {
151-
_debug("setsockopt failed");
152-
goto error;
148+
/* we want to set the don't fragment bit */
149+
opt = IP_PMTUDISC_DO;
150+
ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
151+
(char *) &opt, sizeof(opt));
152+
if (ret < 0) {
153+
_debug("setsockopt failed");
154+
goto error;
155+
}
156+
break;
157+
158+
case AF_INET6:
159+
/* we want to receive ICMP errors */
160+
opt = 1;
161+
ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
162+
(char *) &opt, sizeof(opt));
163+
if (ret < 0) {
164+
_debug("setsockopt failed");
165+
goto error;
166+
}
167+
168+
/* we want to set the don't fragment bit */
169+
opt = IPV6_PMTUDISC_DO;
170+
ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
171+
(char *) &opt, sizeof(opt));
172+
if (ret < 0) {
173+
_debug("setsockopt failed");
174+
goto error;
175+
}
176+
break;
177+
178+
default:
179+
BUG();
153180
}
154181

155182
/* set the socket up */

0 commit comments

Comments
 (0)