aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-05-10 18:26:00 -0400
committerDavid Howells <dhowells@redhat.com>2018-05-10 18:26:00 -0400
commitf2aeed3a591ff29a82495eeaa92ac4780bad7487 (patch)
treec92adff145aee3ca0a9b29400171eedb6f98210d /net
parentc54e43d752c7187595c8c62a231e0b0d53c7fded (diff)
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: 75b54cb57ca3 ("rxrpc: Add IPv6 support") Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/rxrpc/local_object.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 8b54e9531d52..b493e6b62740 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -134,22 +134,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
134 } 134 }
135 } 135 }
136 136
137 /* we want to receive ICMP errors */ 137 switch (local->srx.transport.family) {
138 opt = 1; 138 case AF_INET:
139 ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR, 139 /* we want to receive ICMP errors */
140 (char *) &opt, sizeof(opt)); 140 opt = 1;
141 if (ret < 0) { 141 ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
142 _debug("setsockopt failed"); 142 (char *) &opt, sizeof(opt));
143 goto error; 143 if (ret < 0) {
144 } 144 _debug("setsockopt failed");
145 goto error;
146 }
145 147
146 /* we want to set the don't fragment bit */ 148 /* we want to set the don't fragment bit */
147 opt = IP_PMTUDISC_DO; 149 opt = IP_PMTUDISC_DO;
148 ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER, 150 ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
149 (char *) &opt, sizeof(opt)); 151 (char *) &opt, sizeof(opt));
150 if (ret < 0) { 152 if (ret < 0) {
151 _debug("setsockopt failed"); 153 _debug("setsockopt failed");
152 goto error; 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();
153 } 180 }
154 181
155 /* set the socket up */ 182 /* set the socket up */