10e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo/* 20e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * NET Generic infrastructure for Network protocols. 30e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * 40e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 50e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * 60e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * From code originally in include/net/tcp.h 70e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * 80e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * This program is free software; you can redistribute it and/or 90e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * modify it under the terms of the GNU General Public License 100e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * as published by the Free Software Foundation; either version 110e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo * 2 of the License, or (at your option) any later version. 120e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo */ 130e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 140e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo#include <linux/module.h> 150e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo#include <linux/random.h> 160e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo#include <linux/slab.h> 170e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo#include <linux/string.h> 188336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu#include <linux/tcp.h> 1972a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet#include <linux/vmalloc.h> 200e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 210e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo#include <net/request_sock.h> 220e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 23e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller/* 24e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * Maximum number of SYN_RECV sockets in queue per LISTEN socket. 25e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * One SYN_RECV socket costs about 80bytes on a 32bit machine. 26e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * It would be better to replace it with a global counter for all sockets 27e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * but then some measure against one socket starving all other sockets 28e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * would be needed. 29e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * 3099b53bdd810611cc178e1a86bc112d8f4f56a1e9Peter Pan(潘卫平) * The minimum value of it is 128. Experiments with real servers show that 31e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller * it is absolutely not enough even at 100conn/sec. 256 cures most 3299b53bdd810611cc178e1a86bc112d8f4f56a1e9Peter Pan(潘卫平) * of problems. 3399b53bdd810611cc178e1a86bc112d8f4f56a1e9Peter Pan(潘卫平) * This value is adjusted to 128 for low memory machines, 3499b53bdd810611cc178e1a86bc112d8f4f56a1e9Peter Pan(潘卫平) * and it will increase in proportion to the memory of machine. 3572a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet * Note : Dont forget somaxconn that may limit backlog too. 36e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller */ 37e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Millerint sysctl_max_syn_backlog = 256; 38493f377d6dd56f4e98b198d637fe714ab124681bDavid S. MillerEXPORT_SYMBOL(sysctl_max_syn_backlog); 39e52c1f17e4ea8e61bd26eb25f1a184202693c2b9David S. Miller 400e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Meloint reqsk_queue_alloc(struct request_sock_queue *queue, 4172a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet unsigned int nr_table_entries) 420e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo{ 4372a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet size_t lopt_size = sizeof(struct listen_sock); 44f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet struct listen_sock *lopt = NULL; 4572a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet 4672a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet nr_table_entries = min_t(u32, nr_table_entries, sysctl_max_syn_backlog); 4772a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet nr_table_entries = max_t(u32, nr_table_entries, 8); 4872a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet nr_table_entries = roundup_pow_of_two(nr_table_entries + 1); 4972a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet lopt_size += nr_table_entries * sizeof(struct request_sock *); 50f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet 51f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet if (lopt_size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) 52f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet lopt = kzalloc(lopt_size, GFP_KERNEL | 53f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet __GFP_NOWARN | 54f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet __GFP_NORETRY); 55f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet if (!lopt) 567a1c8e5ab120a5f352e78bbc1fa5bb64e6f23639Eric Dumazet lopt = vzalloc(lopt_size); 57f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet if (!lopt) 580e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo return -ENOMEM; 590e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 600e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd)); 610e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo rwlock_init(&queue->syn_wait_lock); 623eb4801d7bde42b82f05137392a1ee0ece090badNorbert Kiesel queue->rskq_accept_head = NULL; 6383e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo lopt->nr_table_entries = nr_table_entries; 64f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet lopt->max_qlen_log = ilog2(nr_table_entries); 650e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 660e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo write_lock_bh(&queue->syn_wait_lock); 670e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo queue->listen_opt = lopt; 680e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo write_unlock_bh(&queue->syn_wait_lock); 690e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 700e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo return 0; 710e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo} 720e87506fcc734647c7b2497eee4eb81e785c857aArnaldo Carvalho de Melo 73dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanovvoid __reqsk_queue_destroy(struct request_sock_queue *queue) 74dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov{ 75f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet /* This is an error recovery path only, no locking needed */ 76f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet kvfree(queue->listen_opt); 77dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov} 78dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov 79dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanovstatic inline struct listen_sock *reqsk_queue_yank_listen_sk( 80dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov struct request_sock_queue *queue) 81dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov{ 82dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov struct listen_sock *lopt; 83dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov 84dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov write_lock_bh(&queue->syn_wait_lock); 85dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov lopt = queue->listen_opt; 86dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov queue->listen_opt = NULL; 87dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov write_unlock_bh(&queue->syn_wait_lock); 88dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov 89dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov return lopt; 90dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov} 91dab6ba36888a12f3e3edff71eeef968fc159178aPavel Emelyanov 9283e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melovoid reqsk_queue_destroy(struct request_sock_queue *queue) 9383e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo{ 9483e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo /* make all the listen_opt local to us */ 9583e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo struct listen_sock *lopt = reqsk_queue_yank_listen_sk(queue); 9683e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo 9783e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo if (lopt->qlen != 0) { 9872a3effaf633bcae9034b7e176bdbd78d64a71dbEric Dumazet unsigned int i; 9983e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo 10083e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo for (i = 0; i < lopt->nr_table_entries; i++) { 10183e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo struct request_sock *req; 10283e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo 10383e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo while ((req = lopt->syn_table[i]) != NULL) { 10483e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo lopt->syn_table[i] = req->dl_next; 10583e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo lopt->qlen--; 10683e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo reqsk_free(req); 10783e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo } 10883e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo } 10983e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo } 11083e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo 111547b792cac0a038b9dbf958d3c120df3740b5572Ilpo Järvinen WARN_ON(lopt->qlen != 0); 112f6d8cb2eeded7df18b821a321d4cd1cdd1754bf8Eric Dumazet kvfree(lopt); 11383e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo} 11483e3609eba3818f6e18b8bf9442195169ac306b7Arnaldo Carvalho de Melo 1158336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu/* 1168336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * This function is called to set a Fast Open socket's "fastopen_rsk" field 1178336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * to NULL when a TFO socket no longer needs to access the request_sock. 1188336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * This happens only after 3WHS has been either completed or aborted (e.g., 1198336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * RST is received). 1208336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1218336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * Before TFO, a child socket is created only after 3WHS is completed, 1228336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * hence it never needs to access the request_sock. things get a lot more 1238336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * complex with TFO. A child socket, accepted or not, has to access its 1248336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * request_sock for 3WHS processing, e.g., to retransmit SYN-ACK pkts, 1258336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * until 3WHS is either completed or aborted. Afterwards the req will stay 1268336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * until either the child socket is accepted, or in the rare case when the 1278336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * listener is closed before the child is accepted. 1288336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1298336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * In short, a request socket is only freed after BOTH 3WHS has completed 1308336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * (or aborted) and the child socket has been accepted (or listener closed). 1318336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * When a child socket is accepted, its corresponding req->sk is set to 1328336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * NULL since it's no longer needed. More importantly, "req->sk == NULL" 1338336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * will be used by the code below to determine if a child socket has been 1348336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * accepted or not, and the check is protected by the fastopenq->lock 1358336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * described below. 1368336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1378336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * Note that fastopen_rsk is only accessed from the child socket's context 1388336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * with its socket lock held. But a request_sock (req) can be accessed by 1398336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * both its child socket through fastopen_rsk, and a listener socket through 1408336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * icsk_accept_queue.rskq_accept_head. To protect the access a simple spin 1418336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * lock per listener "icsk->icsk_accept_queue.fastopenq->lock" is created. 1428336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * only in the rare case when both the listener and the child locks are held, 1438336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * e.g., in inet_csk_listen_stop() do we not need to acquire the lock. 1448336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * The lock also protects other fields such as fastopenq->qlen, which is 1458336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * decremented by this function when fastopen_rsk is no longer needed. 1468336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1478336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * Note that another solution was to simply use the existing socket lock 1488336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * from the listener. But first socket lock is difficult to use. It is not 1498336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * a simple spin lock - one must consider sock_owned_by_user() and arrange 1508336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * to use sk_add_backlog() stuff. But what really makes it infeasible is the 1518336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * locking hierarchy violation. E.g., inet_csk_listen_stop() may try to 1528336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * acquire a child's lock while holding listener's socket lock. A corner 1538336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * case might also exist in tcp_v4_hnd_req() that will trigger this locking 1548336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * order. 1558336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1568336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * When a TFO req is created, it needs to sock_hold its listener to prevent 1578336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * the latter data structure from going away. 1588336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1598336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * This function also sets "treq->listener" to NULL and unreference listener 1608336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * socket. treq->listener is used by the listener so it is protected by the 1618336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * fastopenq->lock in this function. 1628336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu */ 1638336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chuvoid reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, 1648336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu bool reset) 1658336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu{ 1668336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu struct sock *lsk = tcp_rsk(req)->listener; 1678336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu struct fastopen_queue *fastopenq = 1688336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu inet_csk(lsk)->icsk_accept_queue.fastopenq; 1698336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu 1708336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu tcp_sk(sk)->fastopen_rsk = NULL; 1718336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu spin_lock_bh(&fastopenq->lock); 1728336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu fastopenq->qlen--; 1738336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu tcp_rsk(req)->listener = NULL; 1748336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu if (req->sk) /* the child socket hasn't been accepted yet */ 1758336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu goto out; 1768336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu 1778336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu if (!reset || lsk->sk_state != TCP_LISTEN) { 1788336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu /* If the listener has been closed don't bother with the 1798336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * special RST handling below. 1808336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu */ 1818336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu spin_unlock_bh(&fastopenq->lock); 1828336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu sock_put(lsk); 1838336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu reqsk_free(req); 1848336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu return; 1858336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu } 1868336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu /* Wait for 60secs before removing a req that has triggered RST. 1878336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * This is a simple defense against TFO spoofing attack - by 1888336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * counting the req against fastopen.max_qlen, and disabling 1898336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * TFO when the qlen exceeds max_qlen. 1908336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * 1918336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu * For more details see CoNext'11 "TCP Fast Open" paper. 1928336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu */ 1938336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu req->expires = jiffies + 60*HZ; 1948336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu if (fastopenq->rskq_rst_head == NULL) 1958336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu fastopenq->rskq_rst_head = req; 1968336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu else 1978336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu fastopenq->rskq_rst_tail->dl_next = req; 1988336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu 1998336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu req->dl_next = NULL; 2008336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu fastopenq->rskq_rst_tail = req; 2018336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu fastopenq->qlen++; 2028336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chuout: 2038336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu spin_unlock_bh(&fastopenq->lock); 2048336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu sock_put(lsk); 2058336886f786fdacbc19b719c1f7ea91eb70706d4Jerry Chu} 206