aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet6_connection_sock.h1
-rw-r--r--include/net/inet_connection_sock.h11
-rw-r--r--include/net/request_sock.h15
-rw-r--r--include/net/tcp.h3
-rw-r--r--net/dccp/dccp.h3
-rw-r--r--net/dccp/ipv4.c14
-rw-r--r--net/dccp/ipv6.c19
-rw-r--r--net/dccp/minisocks.c7
-rw-r--r--net/ipv4/inet_connection_sock.c22
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv4/tcp_ipv4.c17
-rw-r--r--net/ipv4/tcp_minisocks.c5
-rw-r--r--net/ipv6/inet6_connection_sock.c10
-rw-r--r--net/ipv6/tcp_ipv6.c12
14 files changed, 67 insertions, 74 deletions
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
index 74af137304be..15bd40878d2a 100644
--- a/include/net/inet6_connection_sock.h
+++ b/include/net/inet6_connection_sock.h
@@ -29,7 +29,6 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi6 *fl6,
29 const struct request_sock *req); 29 const struct request_sock *req);
30 30
31struct request_sock *inet6_csk_search_req(const struct sock *sk, 31struct request_sock *inet6_csk_search_req(const struct sock *sk,
32 struct request_sock ***prevp,
33 const __be16 rport, 32 const __be16 rport,
34 const struct in6_addr *raddr, 33 const struct in6_addr *raddr,
35 const struct in6_addr *laddr, 34 const struct in6_addr *laddr,
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index b9a6b0a94cc6..423a46106e57 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -257,7 +257,6 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
257struct sock *inet_csk_accept(struct sock *sk, int flags, int *err); 257struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
258 258
259struct request_sock *inet_csk_search_req(const struct sock *sk, 259struct request_sock *inet_csk_search_req(const struct sock *sk,
260 struct request_sock ***prevp,
261 const __be16 rport, 260 const __be16 rport,
262 const __be32 raddr, 261 const __be32 raddr,
263 const __be32 laddr); 262 const __be32 laddr);
@@ -310,17 +309,15 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
310} 309}
311 310
312static inline void inet_csk_reqsk_queue_unlink(struct sock *sk, 311static inline void inet_csk_reqsk_queue_unlink(struct sock *sk,
313 struct request_sock *req, 312 struct request_sock *req)
314 struct request_sock **prev)
315{ 313{
316 reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req, prev); 314 reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req);
317} 315}
318 316
319static inline void inet_csk_reqsk_queue_drop(struct sock *sk, 317static inline void inet_csk_reqsk_queue_drop(struct sock *sk,
320 struct request_sock *req, 318 struct request_sock *req)
321 struct request_sock **prev)
322{ 319{
323 inet_csk_reqsk_queue_unlink(sk, req, prev); 320 inet_csk_reqsk_queue_unlink(sk, req);
324 inet_csk_reqsk_queue_removed(sk, req); 321 inet_csk_reqsk_queue_removed(sk, req);
325 reqsk_free(req); 322 reqsk_free(req);
326} 323}
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index e7ef86340514..65223905d139 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -50,6 +50,7 @@ int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req);
50struct request_sock { 50struct request_sock {
51 struct sock_common __req_common; 51 struct sock_common __req_common;
52#define rsk_refcnt __req_common.skc_refcnt 52#define rsk_refcnt __req_common.skc_refcnt
53#define rsk_hash __req_common.skc_hash
53 54
54 struct request_sock *dl_next; 55 struct request_sock *dl_next;
55 struct sock *rsk_listener; 56 struct sock *rsk_listener;
@@ -216,11 +217,16 @@ static inline int reqsk_queue_empty(struct request_sock_queue *queue)
216} 217}
217 218
218static inline void reqsk_queue_unlink(struct request_sock_queue *queue, 219static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
219 struct request_sock *req, 220 struct request_sock *req)
220 struct request_sock **prev_req)
221{ 221{
222 struct listen_sock *lopt = queue->listen_opt;
223 struct request_sock **prev;
224
222 write_lock(&queue->syn_wait_lock); 225 write_lock(&queue->syn_wait_lock);
223 *prev_req = req->dl_next; 226 prev = &lopt->syn_table[req->rsk_hash];
227 while (*prev != req)
228 prev = &(*prev)->dl_next;
229 *prev = req->dl_next;
224 write_unlock(&queue->syn_wait_lock); 230 write_unlock(&queue->syn_wait_lock);
225} 231}
226 232
@@ -300,7 +306,6 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
300 req->num_retrans = 0; 306 req->num_retrans = 0;
301 req->num_timeout = 0; 307 req->num_timeout = 0;
302 req->sk = NULL; 308 req->sk = NULL;
303 req->dl_next = lopt->syn_table[hash];
304 309
305 /* before letting lookups find us, make sure all req fields 310 /* before letting lookups find us, make sure all req fields
306 * are committed to memory and refcnt initialized. 311 * are committed to memory and refcnt initialized.
@@ -308,7 +313,9 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
308 smp_wmb(); 313 smp_wmb();
309 atomic_set(&req->rsk_refcnt, 1); 314 atomic_set(&req->rsk_refcnt, 1);
310 315
316 req->rsk_hash = hash;
311 write_lock(&queue->syn_wait_lock); 317 write_lock(&queue->syn_wait_lock);
318 req->dl_next = lopt->syn_table[hash];
312 lopt->syn_table[hash] = req; 319 lopt->syn_table[hash] = req;
313 write_unlock(&queue->syn_wait_lock); 320 write_unlock(&queue->syn_wait_lock);
314} 321}
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5b29835b81d8..082fd79132b7 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -406,8 +406,7 @@ enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw,
406 struct sk_buff *skb, 406 struct sk_buff *skb,
407 const struct tcphdr *th); 407 const struct tcphdr *th);
408struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 408struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
409 struct request_sock *req, struct request_sock **prev, 409 struct request_sock *req, bool fastopen);
410 bool fastopen);
411int tcp_child_process(struct sock *parent, struct sock *child, 410int tcp_child_process(struct sock *parent, struct sock *child,
412 struct sk_buff *skb); 411 struct sk_buff *skb);
413void tcp_enter_loss(struct sock *sk); 412void tcp_enter_loss(struct sock *sk);
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 3b1d64d6e093..2396f50c5b04 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -280,8 +280,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
280 struct request_sock *req, 280 struct request_sock *req,
281 struct dst_entry *dst); 281 struct dst_entry *dst);
282struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, 282struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
283 struct request_sock *req, 283 struct request_sock *req);
284 struct request_sock **prev);
285 284
286int dccp_child_process(struct sock *parent, struct sock *child, 285int dccp_child_process(struct sock *parent, struct sock *child,
287 struct sk_buff *skb); 286 struct sk_buff *skb);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index e7ad291cd96b..5bffbbaf1fac 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -288,11 +288,11 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
288 } 288 }
289 289
290 switch (sk->sk_state) { 290 switch (sk->sk_state) {
291 struct request_sock *req , **prev; 291 struct request_sock *req;
292 case DCCP_LISTEN: 292 case DCCP_LISTEN:
293 if (sock_owned_by_user(sk)) 293 if (sock_owned_by_user(sk))
294 goto out; 294 goto out;
295 req = inet_csk_search_req(sk, &prev, dh->dccph_dport, 295 req = inet_csk_search_req(sk, dh->dccph_dport,
296 iph->daddr, iph->saddr); 296 iph->daddr, iph->saddr);
297 if (!req) 297 if (!req)
298 goto out; 298 goto out;
@@ -314,7 +314,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
314 * created socket, and POSIX does not want network 314 * created socket, and POSIX does not want network
315 * errors returned from accept(). 315 * errors returned from accept().
316 */ 316 */
317 inet_csk_reqsk_queue_drop(sk, req, prev); 317 inet_csk_reqsk_queue_drop(sk, req);
318 goto out; 318 goto out;
319 319
320 case DCCP_REQUESTING: 320 case DCCP_REQUESTING:
@@ -448,13 +448,11 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
448 const struct dccp_hdr *dh = dccp_hdr(skb); 448 const struct dccp_hdr *dh = dccp_hdr(skb);
449 const struct iphdr *iph = ip_hdr(skb); 449 const struct iphdr *iph = ip_hdr(skb);
450 struct sock *nsk; 450 struct sock *nsk;
451 struct request_sock **prev;
452 /* Find possible connection requests. */ 451 /* Find possible connection requests. */
453 struct request_sock *req = inet_csk_search_req(sk, &prev, 452 struct request_sock *req = inet_csk_search_req(sk, dh->dccph_sport,
454 dh->dccph_sport,
455 iph->saddr, iph->daddr); 453 iph->saddr, iph->daddr);
456 if (req != NULL) 454 if (req)
457 return dccp_check_req(sk, skb, req, prev); 455 return dccp_check_req(sk, skb, req);
458 456
459 nsk = inet_lookup_established(sock_net(sk), &dccp_hashinfo, 457 nsk = inet_lookup_established(sock_net(sk), &dccp_hashinfo,
460 iph->saddr, dh->dccph_sport, 458 iph->saddr, dh->dccph_sport,
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index c655de5f67c9..ae2184039fe3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -149,12 +149,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
149 149
150 /* Might be for an request_sock */ 150 /* Might be for an request_sock */
151 switch (sk->sk_state) { 151 switch (sk->sk_state) {
152 struct request_sock *req, **prev; 152 struct request_sock *req;
153 case DCCP_LISTEN: 153 case DCCP_LISTEN:
154 if (sock_owned_by_user(sk)) 154 if (sock_owned_by_user(sk))
155 goto out; 155 goto out;
156 156
157 req = inet6_csk_search_req(sk, &prev, dh->dccph_dport, 157 req = inet6_csk_search_req(sk, dh->dccph_dport,
158 &hdr->daddr, &hdr->saddr, 158 &hdr->daddr, &hdr->saddr,
159 inet6_iif(skb)); 159 inet6_iif(skb));
160 if (req == NULL) 160 if (req == NULL)
@@ -172,7 +172,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
172 goto out; 172 goto out;
173 } 173 }
174 174
175 inet_csk_reqsk_queue_drop(sk, req, prev); 175 inet_csk_reqsk_queue_drop(sk, req);
176 goto out; 176 goto out;
177 177
178 case DCCP_REQUESTING: 178 case DCCP_REQUESTING:
@@ -317,16 +317,13 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
317{ 317{
318 const struct dccp_hdr *dh = dccp_hdr(skb); 318 const struct dccp_hdr *dh = dccp_hdr(skb);
319 const struct ipv6hdr *iph = ipv6_hdr(skb); 319 const struct ipv6hdr *iph = ipv6_hdr(skb);
320 struct request_sock *req;
320 struct sock *nsk; 321 struct sock *nsk;
321 struct request_sock **prev; 322
322 /* Find possible connection requests. */ 323 req = inet6_csk_search_req(sk, dh->dccph_sport, &iph->saddr,
323 struct request_sock *req = inet6_csk_search_req(sk, &prev, 324 &iph->daddr, inet6_iif(skb));
324 dh->dccph_sport,
325 &iph->saddr,
326 &iph->daddr,
327 inet6_iif(skb));
328 if (req != NULL) 325 if (req != NULL)
329 return dccp_check_req(sk, skb, req, prev); 326 return dccp_check_req(sk, skb, req);
330 327
331 nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo, 328 nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo,
332 &iph->saddr, dh->dccph_sport, 329 &iph->saddr, dh->dccph_sport,
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index b50dc436db1f..332f7d6d9942 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -152,8 +152,7 @@ EXPORT_SYMBOL_GPL(dccp_create_openreq_child);
152 * as an request_sock. 152 * as an request_sock.
153 */ 153 */
154struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, 154struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
155 struct request_sock *req, 155 struct request_sock *req)
156 struct request_sock **prev)
157{ 156{
158 struct sock *child = NULL; 157 struct sock *child = NULL;
159 struct dccp_request_sock *dreq = dccp_rsk(req); 158 struct dccp_request_sock *dreq = dccp_rsk(req);
@@ -200,7 +199,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
200 if (child == NULL) 199 if (child == NULL)
201 goto listen_overflow; 200 goto listen_overflow;
202 201
203 inet_csk_reqsk_queue_unlink(sk, req, prev); 202 inet_csk_reqsk_queue_unlink(sk, req);
204 inet_csk_reqsk_queue_removed(sk, req); 203 inet_csk_reqsk_queue_removed(sk, req);
205 inet_csk_reqsk_queue_add(sk, req, child); 204 inet_csk_reqsk_queue_add(sk, req, child);
206out: 205out:
@@ -212,7 +211,7 @@ drop:
212 if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) 211 if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET)
213 req->rsk_ops->send_reset(sk, skb); 212 req->rsk_ops->send_reset(sk, skb);
214 213
215 inet_csk_reqsk_queue_drop(sk, req, prev); 214 inet_csk_reqsk_queue_drop(sk, req);
216 goto out; 215 goto out;
217} 216}
218 217
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index f0f91858aecf..4f57a017928c 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -480,18 +480,17 @@ static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
480#endif 480#endif
481 481
482struct request_sock *inet_csk_search_req(const struct sock *sk, 482struct request_sock *inet_csk_search_req(const struct sock *sk,
483 struct request_sock ***prevp,
484 const __be16 rport, const __be32 raddr, 483 const __be16 rport, const __be32 raddr,
485 const __be32 laddr) 484 const __be32 laddr)
486{ 485{
487 const struct inet_connection_sock *icsk = inet_csk(sk); 486 const struct inet_connection_sock *icsk = inet_csk(sk);
488 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; 487 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
489 struct request_sock *req, **prev; 488 struct request_sock *req;
490 489
491 for (prev = &lopt->syn_table[inet_synq_hash(raddr, rport, lopt->hash_rnd, 490 for (req = lopt->syn_table[inet_synq_hash(raddr, rport, lopt->hash_rnd,
492 lopt->nr_table_entries)]; 491 lopt->nr_table_entries)];
493 (req = *prev) != NULL; 492 req != NULL;
494 prev = &req->dl_next) { 493 req = req->dl_next) {
495 const struct inet_request_sock *ireq = inet_rsk(req); 494 const struct inet_request_sock *ireq = inet_rsk(req);
496 495
497 if (ireq->ir_rmt_port == rport && 496 if (ireq->ir_rmt_port == rport &&
@@ -499,7 +498,6 @@ struct request_sock *inet_csk_search_req(const struct sock *sk,
499 ireq->ir_loc_addr == laddr && 498 ireq->ir_loc_addr == laddr &&
500 AF_INET_FAMILY(req->rsk_ops->family)) { 499 AF_INET_FAMILY(req->rsk_ops->family)) {
501 WARN_ON(req->sk); 500 WARN_ON(req->sk);
502 *prevp = prev;
503 break; 501 break;
504 } 502 }
505 } 503 }
@@ -610,7 +608,10 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
610 i = lopt->clock_hand; 608 i = lopt->clock_hand;
611 609
612 do { 610 do {
613 reqp=&lopt->syn_table[i]; 611 reqp = &lopt->syn_table[i];
612 if (!*reqp)
613 goto next_bucket;
614 write_lock(&queue->syn_wait_lock);
614 while ((req = *reqp) != NULL) { 615 while ((req = *reqp) != NULL) {
615 if (time_after_eq(now, req->expires)) { 616 if (time_after_eq(now, req->expires)) {
616 int expire = 0, resend = 0; 617 int expire = 0, resend = 0;
@@ -635,14 +636,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
635 } 636 }
636 637
637 /* Drop this request */ 638 /* Drop this request */
638 inet_csk_reqsk_queue_unlink(parent, req, reqp); 639 *reqp = req->dl_next;
639 reqsk_queue_removed(queue, req); 640 reqsk_queue_removed(queue, req);
640 reqsk_put(req); 641 reqsk_put(req);
641 continue; 642 continue;
642 } 643 }
643 reqp = &req->dl_next; 644 reqp = &req->dl_next;
644 } 645 }
645 646 write_unlock(&queue->syn_wait_lock);
647next_bucket:
646 i = (i + 1) & (lopt->nr_table_entries - 1); 648 i = (i + 1) & (lopt->nr_table_entries - 1);
647 649
648 } while (--budget > 0); 650 } while (--budget > 0);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 1dfbaee3554e..95caea707f54 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5694,7 +5694,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5694 WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && 5694 WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV &&
5695 sk->sk_state != TCP_FIN_WAIT1); 5695 sk->sk_state != TCP_FIN_WAIT1);
5696 5696
5697 if (tcp_check_req(sk, skb, req, NULL, true) == NULL) 5697 if (tcp_check_req(sk, skb, req, true) == NULL)
5698 goto discard; 5698 goto discard;
5699 } 5699 }
5700 5700
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index ddd0b1f25b96..19c3770f1e97 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -458,12 +458,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
458 } 458 }
459 459
460 switch (sk->sk_state) { 460 switch (sk->sk_state) {
461 struct request_sock *req, **prev; 461 struct request_sock *req;
462 case TCP_LISTEN: 462 case TCP_LISTEN:
463 if (sock_owned_by_user(sk)) 463 if (sock_owned_by_user(sk))
464 goto out; 464 goto out;
465 465
466 req = inet_csk_search_req(sk, &prev, th->dest, 466 req = inet_csk_search_req(sk, th->dest,
467 iph->daddr, iph->saddr); 467 iph->daddr, iph->saddr);
468 if (!req) 468 if (!req)
469 goto out; 469 goto out;
@@ -484,7 +484,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
484 * created socket, and POSIX does not want network 484 * created socket, and POSIX does not want network
485 * errors returned from accept(). 485 * errors returned from accept().
486 */ 486 */
487 inet_csk_reqsk_queue_drop(sk, req, prev); 487 inet_csk_reqsk_queue_drop(sk, req);
488 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); 488 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
489 goto out; 489 goto out;
490 490
@@ -1392,15 +1392,14 @@ EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
1392 1392
1393static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) 1393static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
1394{ 1394{
1395 struct tcphdr *th = tcp_hdr(skb); 1395 const struct tcphdr *th = tcp_hdr(skb);
1396 const struct iphdr *iph = ip_hdr(skb); 1396 const struct iphdr *iph = ip_hdr(skb);
1397 struct request_sock *req;
1397 struct sock *nsk; 1398 struct sock *nsk;
1398 struct request_sock **prev; 1399
1399 /* Find possible connection requests. */ 1400 req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr);
1400 struct request_sock *req = inet_csk_search_req(sk, &prev, th->source,
1401 iph->saddr, iph->daddr);
1402 if (req) 1401 if (req)
1403 return tcp_check_req(sk, skb, req, prev, false); 1402 return tcp_check_req(sk, skb, req, false);
1404 1403
1405 nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr, 1404 nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr,
1406 th->source, iph->daddr, th->dest, inet_iif(skb)); 1405 th->source, iph->daddr, th->dest, inet_iif(skb));
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index dd11ac7798c6..848bcab358e4 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -572,7 +572,6 @@ EXPORT_SYMBOL(tcp_create_openreq_child);
572 572
573struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 573struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
574 struct request_sock *req, 574 struct request_sock *req,
575 struct request_sock **prev,
576 bool fastopen) 575 bool fastopen)
577{ 576{
578 struct tcp_options_received tmp_opt; 577 struct tcp_options_received tmp_opt;
@@ -766,7 +765,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
766 if (child == NULL) 765 if (child == NULL)
767 goto listen_overflow; 766 goto listen_overflow;
768 767
769 inet_csk_reqsk_queue_unlink(sk, req, prev); 768 inet_csk_reqsk_queue_unlink(sk, req);
770 inet_csk_reqsk_queue_removed(sk, req); 769 inet_csk_reqsk_queue_removed(sk, req);
771 770
772 inet_csk_reqsk_queue_add(sk, req, child); 771 inet_csk_reqsk_queue_add(sk, req, child);
@@ -791,7 +790,7 @@ embryonic_reset:
791 tcp_reset(sk); 790 tcp_reset(sk);
792 } 791 }
793 if (!fastopen) { 792 if (!fastopen) {
794 inet_csk_reqsk_queue_drop(sk, req, prev); 793 inet_csk_reqsk_queue_drop(sk, req);
795 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); 794 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
796 } 795 }
797 return NULL; 796 return NULL;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 29b32206e494..b7acb9ebc4f5 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -113,7 +113,6 @@ static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
113} 113}
114 114
115struct request_sock *inet6_csk_search_req(const struct sock *sk, 115struct request_sock *inet6_csk_search_req(const struct sock *sk,
116 struct request_sock ***prevp,
117 const __be16 rport, 116 const __be16 rport,
118 const struct in6_addr *raddr, 117 const struct in6_addr *raddr,
119 const struct in6_addr *laddr, 118 const struct in6_addr *laddr,
@@ -121,13 +120,13 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk,
121{ 120{
122 const struct inet_connection_sock *icsk = inet_csk(sk); 121 const struct inet_connection_sock *icsk = inet_csk(sk);
123 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; 122 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
124 struct request_sock *req, **prev; 123 struct request_sock *req;
125 124
126 for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport, 125 for (req = lopt->syn_table[inet6_synq_hash(raddr, rport,
127 lopt->hash_rnd, 126 lopt->hash_rnd,
128 lopt->nr_table_entries)]; 127 lopt->nr_table_entries)];
129 (req = *prev) != NULL; 128 req != NULL;
130 prev = &req->dl_next) { 129 req = req->dl_next) {
131 const struct inet_request_sock *ireq = inet_rsk(req); 130 const struct inet_request_sock *ireq = inet_rsk(req);
132 131
133 if (ireq->ir_rmt_port == rport && 132 if (ireq->ir_rmt_port == rport &&
@@ -136,7 +135,6 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk,
136 ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) && 135 ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) &&
137 (!ireq->ir_iif || ireq->ir_iif == iif)) { 136 (!ireq->ir_iif || ireq->ir_iif == iif)) {
138 WARN_ON(req->sk != NULL); 137 WARN_ON(req->sk != NULL);
139 *prevp = prev;
140 return req; 138 return req;
141 } 139 }
142 } 140 }
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 720676d073d9..146f123b52c9 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -403,13 +403,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
403 403
404 /* Might be for an request_sock */ 404 /* Might be for an request_sock */
405 switch (sk->sk_state) { 405 switch (sk->sk_state) {
406 struct request_sock *req, **prev; 406 struct request_sock *req;
407 case TCP_LISTEN: 407 case TCP_LISTEN:
408 if (sock_owned_by_user(sk)) 408 if (sock_owned_by_user(sk))
409 goto out; 409 goto out;
410 410
411 /* Note : We use inet6_iif() here, not tcp_v6_iif() */ 411 /* Note : We use inet6_iif() here, not tcp_v6_iif() */
412 req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, 412 req = inet6_csk_search_req(sk, th->dest, &hdr->daddr,
413 &hdr->saddr, inet6_iif(skb)); 413 &hdr->saddr, inet6_iif(skb));
414 if (!req) 414 if (!req)
415 goto out; 415 goto out;
@@ -424,7 +424,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
424 goto out; 424 goto out;
425 } 425 }
426 426
427 inet_csk_reqsk_queue_drop(sk, req, prev); 427 inet_csk_reqsk_queue_drop(sk, req);
428 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); 428 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
429 goto out; 429 goto out;
430 430
@@ -980,16 +980,16 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
980 980
981static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb) 981static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb)
982{ 982{
983 struct request_sock *req, **prev;
984 const struct tcphdr *th = tcp_hdr(skb); 983 const struct tcphdr *th = tcp_hdr(skb);
984 struct request_sock *req;
985 struct sock *nsk; 985 struct sock *nsk;
986 986
987 /* Find possible connection requests. */ 987 /* Find possible connection requests. */
988 req = inet6_csk_search_req(sk, &prev, th->source, 988 req = inet6_csk_search_req(sk, th->source,
989 &ipv6_hdr(skb)->saddr, 989 &ipv6_hdr(skb)->saddr,
990 &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb)); 990 &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb));
991 if (req) 991 if (req)
992 return tcp_check_req(sk, skb, req, prev, false); 992 return tcp_check_req(sk, skb, req, false);
993 993
994 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, 994 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
995 &ipv6_hdr(skb)->saddr, th->source, 995 &ipv6_hdr(skb)->saddr, th->source,