aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 412139f4eccd..883df0ad5bfe 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1451,6 +1451,7 @@ process:
1451 1451
1452 if (sk->sk_state == TCP_NEW_SYN_RECV) { 1452 if (sk->sk_state == TCP_NEW_SYN_RECV) {
1453 struct request_sock *req = inet_reqsk(sk); 1453 struct request_sock *req = inet_reqsk(sk);
1454 bool req_stolen = false;
1454 struct sock *nsk; 1455 struct sock *nsk;
1455 1456
1456 sk = req->rsk_listener; 1457 sk = req->rsk_listener;
@@ -1470,10 +1471,20 @@ process:
1470 th = (const struct tcphdr *)skb->data; 1471 th = (const struct tcphdr *)skb->data;
1471 hdr = ipv6_hdr(skb); 1472 hdr = ipv6_hdr(skb);
1472 tcp_v6_fill_cb(skb, hdr, th); 1473 tcp_v6_fill_cb(skb, hdr, th);
1473 nsk = tcp_check_req(sk, skb, req, false); 1474 nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
1474 } 1475 }
1475 if (!nsk) { 1476 if (!nsk) {
1476 reqsk_put(req); 1477 reqsk_put(req);
1478 if (req_stolen) {
1479 /* Another cpu got exclusive access to req
1480 * and created a full blown socket.
1481 * Try to feed this packet to this socket
1482 * instead of discarding it.
1483 */
1484 tcp_v6_restore_cb(skb);
1485 sock_put(sk);
1486 goto lookup;
1487 }
1477 goto discard_and_relse; 1488 goto discard_and_relse;
1478 } 1489 }
1479 if (nsk == sk) { 1490 if (nsk == sk) {