extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
 int tcp_fastopen_reset_cipher(void *key, unsigned int len);
-bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
-                     struct request_sock *req,
-                     struct tcp_fastopen_cookie *foc,
-                     struct dst_entry *dst);
+struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
+                             struct request_sock *req,
+                             struct tcp_fastopen_cookie *foc,
+                             struct dst_entry *dst);
 void tcp_fastopen_init_key_once(bool publish);
 #define TCP_FASTOPEN_KEY_LENGTH 16
 
 
        return false;
 }
 
-static bool tcp_fastopen_create_child(struct sock *sk,
-                                     struct sk_buff *skb,
-                                     struct dst_entry *dst,
-                                     struct request_sock *req)
+static struct sock *tcp_fastopen_create_child(struct sock *sk,
+                                             struct sk_buff *skb,
+                                             struct dst_entry *dst,
+                                             struct request_sock *req)
 {
        struct tcp_sock *tp;
        struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
 
        child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
        if (!child)
-               return false;
+               return NULL;
 
        spin_lock(&queue->fastopenq->lock);
        queue->fastopenq->qlen++;
        tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = end_seq;
        sk->sk_data_ready(sk);
        bh_unlock_sock(child);
-       sock_put(child);
+       /* Note: sock_put(child) will be done by tcp_conn_request()
+        * after SYNACK packet is sent.
+        */
        WARN_ON(!req->sk);
-       return true;
+       return child;
 }
 
 static bool tcp_fastopen_queue_check(struct sock *sk)
  * may be updated and return the client in the SYN-ACK later. E.g., Fast Open
  * cookie request (foc->len == 0).
  */
-bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
-                     struct request_sock *req,
-                     struct tcp_fastopen_cookie *foc,
-                     struct dst_entry *dst)
+struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
+                             struct request_sock *req,
+                             struct tcp_fastopen_cookie *foc,
+                             struct dst_entry *dst)
 {
        struct tcp_fastopen_cookie valid_foc = { .len = -1 };
        bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
+       struct sock *child;
 
        if (foc->len == 0) /* Client requests a cookie */
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENCOOKIEREQD);
              (syn_data || foc->len >= 0) &&
              tcp_fastopen_queue_check(sk))) {
                foc->len = -1;
-               return false;
+               return NULL;
        }
 
        if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
                 * data in SYN_RECV state.
                 */
 fastopen:
-               if (tcp_fastopen_create_child(sk, skb, dst, req)) {
+               child = tcp_fastopen_create_child(sk, skb, dst, req);
+               if (child) {
                        foc->len = -1;
                        NET_INC_STATS_BH(sock_net(sk),
                                         LINUX_MIB_TCPFASTOPENPASSIVE);
-                       return true;
+                       return child;
                }
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVEFAIL);
        } else if (foc->len > 0) /* Client presents an invalid cookie */
 
        valid_foc.exp = foc->exp;
        *foc = valid_foc;
-       return false;
+       return NULL;
 }
-EXPORT_SYMBOL(tcp_try_fastopen);
 
                     const struct tcp_request_sock_ops *af_ops,
                     struct sock *sk, struct sk_buff *skb)
 {
+       struct tcp_fastopen_cookie foc = { .len = -1 };
+       __u32 isn = TCP_SKB_CB(skb)->tcp_tw_isn;
        struct tcp_options_received tmp_opt;
-       struct request_sock *req;
        struct tcp_sock *tp = tcp_sk(sk);
+       struct sock *fastopen_sk = NULL;
        struct dst_entry *dst = NULL;
-       __u32 isn = TCP_SKB_CB(skb)->tcp_tw_isn;
-       bool want_cookie = false, fastopen;
+       struct request_sock *req;
+       bool want_cookie = false;
        struct flowi fl;
-       struct tcp_fastopen_cookie foc = { .len = -1 };
        int err;
 
 
        tcp_rsk(req)->snt_isn = isn;
        tcp_rsk(req)->txhash = net_tx_rndhash();
        tcp_openreq_init_rwin(req, sk, dst);
-       fastopen = !want_cookie &&
-                  tcp_try_fastopen(sk, skb, req, &foc, dst);
-       err = af_ops->send_synack(sk, dst, &fl, req,
+       if (!want_cookie)
+               fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst);
+       err = af_ops->send_synack(fastopen_sk ?: sk, dst, &fl, req,
                                  skb_get_queue_mapping(skb), &foc);
-       if (!fastopen) {
+       if (fastopen_sk) {
+               sock_put(fastopen_sk);
+       } else {
                if (err || want_cookie)
                        goto drop_and_free;