xref: /openbmc/linux/include/net/inet_connection_sock.h (revision d32fd6bb9f2bc8178cdd65ebec1ad670a8bfa241)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2463c84b9SArnaldo Carvalho de Melo /*
3463c84b9SArnaldo Carvalho de Melo  * NET		Generic infrastructure for INET connection oriented protocols.
4463c84b9SArnaldo Carvalho de Melo  *
5463c84b9SArnaldo Carvalho de Melo  *		Definitions for inet_connection_sock
6463c84b9SArnaldo Carvalho de Melo  *
7463c84b9SArnaldo Carvalho de Melo  * Authors:	Many people, see the TCP sources
8463c84b9SArnaldo Carvalho de Melo  *
9463c84b9SArnaldo Carvalho de Melo  * 		From code originally in TCP
10463c84b9SArnaldo Carvalho de Melo  */
11463c84b9SArnaldo Carvalho de Melo #ifndef _INET_CONNECTION_SOCK_H
12463c84b9SArnaldo Carvalho de Melo #define _INET_CONNECTION_SOCK_H
13463c84b9SArnaldo Carvalho de Melo 
148292a17aSArnaldo Carvalho de Melo #include <linux/compiler.h>
153f421baaSArnaldo Carvalho de Melo #include <linux/string.h>
16463c84b9SArnaldo Carvalho de Melo #include <linux/timer.h>
17bd01f843SAl Viro #include <linux/poll.h>
1896d18d82SNick Desaulniers #include <linux/kernel.h>
19a7b75c5aSChristoph Hellwig #include <linux/sockptr.h>
2014c85021SArnaldo Carvalho de Melo 
2114c85021SArnaldo Carvalho de Melo #include <net/inet_sock.h>
22463c84b9SArnaldo Carvalho de Melo #include <net/request_sock.h>
23463c84b9SArnaldo Carvalho de Melo 
243f421baaSArnaldo Carvalho de Melo /* Cancel timers, when they are not required. */
253f421baaSArnaldo Carvalho de Melo #undef INET_CSK_CLEAR_TIMERS
263f421baaSArnaldo Carvalho de Melo 
27463c84b9SArnaldo Carvalho de Melo struct inet_bind_bucket;
2828044fc1SJoanne Koong struct inet_bind2_bucket;
296687e988SArnaldo Carvalho de Melo struct tcp_congestion_ops;
30463c84b9SArnaldo Carvalho de Melo 
318292a17aSArnaldo Carvalho de Melo /*
328292a17aSArnaldo Carvalho de Melo  * Pointers to address related TCP functions
338292a17aSArnaldo Carvalho de Melo  * (i.e. things that depend on the address family)
348292a17aSArnaldo Carvalho de Melo  */
358292a17aSArnaldo Carvalho de Melo struct inet_connection_sock_af_ops {
36b0270e91SEric Dumazet 	int	    (*queue_xmit)(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
37bb296246SHerbert Xu 	void	    (*send_check)(struct sock *sk, struct sk_buff *skb);
388292a17aSArnaldo Carvalho de Melo 	int	    (*rebuild_header)(struct sock *sk);
395d299f3dSEric Dumazet 	void	    (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb);
408292a17aSArnaldo Carvalho de Melo 	int	    (*conn_request)(struct sock *sk, struct sk_buff *skb);
410c27171eSEric Dumazet 	struct sock *(*syn_recv_sock)(const struct sock *sk, struct sk_buff *skb,
428292a17aSArnaldo Carvalho de Melo 				      struct request_sock *req,
435e0724d0SEric Dumazet 				      struct dst_entry *dst,
445e0724d0SEric Dumazet 				      struct request_sock *req_unhash,
455e0724d0SEric Dumazet 				      bool *own_req);
46850db6b8SArnaldo Carvalho de Melo 	u16	    net_header_len;
4767469601SEric Dumazet 	u16	    net_frag_header_len;
48850db6b8SArnaldo Carvalho de Melo 	u16	    sockaddr_len;
498292a17aSArnaldo Carvalho de Melo 	int	    (*setsockopt)(struct sock *sk, int level, int optname,
50a7b75c5aSChristoph Hellwig 				  sockptr_t optval, unsigned int optlen);
518292a17aSArnaldo Carvalho de Melo 	int	    (*getsockopt)(struct sock *sk, int level, int optname,
528292a17aSArnaldo Carvalho de Melo 				  char __user *optval, int __user *optlen);
538292a17aSArnaldo Carvalho de Melo 	void	    (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
544fab9071SNeal Cardwell 	void	    (*mtu_reduced)(struct sock *sk);
558292a17aSArnaldo Carvalho de Melo };
568292a17aSArnaldo Carvalho de Melo 
57463c84b9SArnaldo Carvalho de Melo /** inet_connection_sock - INET connection oriented sock
58463c84b9SArnaldo Carvalho de Melo  *
59463c84b9SArnaldo Carvalho de Melo  * @icsk_accept_queue:	   FIFO of established children
60463c84b9SArnaldo Carvalho de Melo  * @icsk_bind_hash:	   Bind node
6128044fc1SJoanne Koong  * @icsk_bind2_hash:	   Bind node in the bhash2 table
62463c84b9SArnaldo Carvalho de Melo  * @icsk_timeout:	   Timeout
63463c84b9SArnaldo Carvalho de Melo  * @icsk_retransmit_timer: Resend (no ack)
64463c84b9SArnaldo Carvalho de Melo  * @icsk_rto:		   Retransmit timeout
65d83d8461SArnaldo Carvalho de Melo  * @icsk_pmtu_cookie	   Last pmtu seen by socket
666687e988SArnaldo Carvalho de Melo  * @icsk_ca_ops		   Pluggable congestion control hook
678292a17aSArnaldo Carvalho de Melo  * @icsk_af_ops		   Operations which are AF_INET{4,6} specific
68734942ccSDave Watson  * @icsk_ulp_ops	   Pluggable ULP control hook
69734942ccSDave Watson  * @icsk_ulp_data	   ULP private data
706dac1523SIlya Lesokhin  * @icsk_clean_acked	   Clean acked data hook
716687e988SArnaldo Carvalho de Melo  * @icsk_ca_state:	   Congestion control state
72463c84b9SArnaldo Carvalho de Melo  * @icsk_retransmits:	   Number of unrecovered [RTO] timeouts
73463c84b9SArnaldo Carvalho de Melo  * @icsk_pending:	   Scheduled timer event
74463c84b9SArnaldo Carvalho de Melo  * @icsk_backoff:	   Backoff
75463c84b9SArnaldo Carvalho de Melo  * @icsk_syn_retries:      Number of allowed SYN (or equivalent) retries
766687e988SArnaldo Carvalho de Melo  * @icsk_probes_out:	   unanswered 0 window probes
77d83d8461SArnaldo Carvalho de Melo  * @icsk_ext_hdr_len:	   Network protocol overhead (IP/IPv6 options)
78463c84b9SArnaldo Carvalho de Melo  * @icsk_ack:		   Delayed ACK control data
795d424d5aSJohn Heffner  * @icsk_mtup;		   MTU probing control data
809d9b1ee0SEnke Chen  * @icsk_probes_tstamp:    Probe timestamp (cleared by non-zero window ack)
819d9b1ee0SEnke Chen  * @icsk_user_timeout:	   TCP_USER_TIMEOUT value
82463c84b9SArnaldo Carvalho de Melo  */
83463c84b9SArnaldo Carvalho de Melo struct inet_connection_sock {
84463c84b9SArnaldo Carvalho de Melo 	/* inet_sock has to be the first member! */
85463c84b9SArnaldo Carvalho de Melo 	struct inet_sock	  icsk_inet;
86463c84b9SArnaldo Carvalho de Melo 	struct request_sock_queue icsk_accept_queue;
87463c84b9SArnaldo Carvalho de Melo 	struct inet_bind_bucket	  *icsk_bind_hash;
8828044fc1SJoanne Koong 	struct inet_bind2_bucket  *icsk_bind2_hash;
89463c84b9SArnaldo Carvalho de Melo 	unsigned long		  icsk_timeout;
90463c84b9SArnaldo Carvalho de Melo  	struct timer_list	  icsk_retransmit_timer;
91463c84b9SArnaldo Carvalho de Melo  	struct timer_list	  icsk_delack_timer;
92463c84b9SArnaldo Carvalho de Melo 	__u32			  icsk_rto;
93ca584ba0SMartin KaFai Lau 	__u32                     icsk_rto_min;
942b8ee4f0SMartin KaFai Lau 	__u32                     icsk_delack_max;
95d83d8461SArnaldo Carvalho de Melo 	__u32			  icsk_pmtu_cookie;
96770cfbcfSStephen Hemminger 	const struct tcp_congestion_ops *icsk_ca_ops;
97770cfbcfSStephen Hemminger 	const struct inet_connection_sock_af_ops *icsk_af_ops;
98734942ccSDave Watson 	const struct tcp_ulp_ops  *icsk_ulp_ops;
9915a7dea7SJakub Kicinski 	void __rcu		  *icsk_ulp_data;
1006dac1523SIlya Lesokhin 	void (*icsk_clean_acked)(struct sock *sk, u32 acked_seq);
101d83d8461SArnaldo Carvalho de Melo 	unsigned int		  (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
1028919a9b3SNeal Cardwell 	__u8			  icsk_ca_state:5,
1038919a9b3SNeal Cardwell 				  icsk_ca_initialized:1,
1049f950415SNeal Cardwell 				  icsk_ca_setsockopt:1,
105c5c6a8abSDaniel Borkmann 				  icsk_ca_dst_locked:1;
106463c84b9SArnaldo Carvalho de Melo 	__u8			  icsk_retransmits;
107463c84b9SArnaldo Carvalho de Melo 	__u8			  icsk_pending;
108463c84b9SArnaldo Carvalho de Melo 	__u8			  icsk_backoff;
109463c84b9SArnaldo Carvalho de Melo 	__u8			  icsk_syn_retries;
1106687e988SArnaldo Carvalho de Melo 	__u8			  icsk_probes_out;
111d83d8461SArnaldo Carvalho de Melo 	__u16			  icsk_ext_hdr_len;
112463c84b9SArnaldo Carvalho de Melo 	struct {
113463c84b9SArnaldo Carvalho de Melo 		__u8		  pending;	 /* ACK is pending			   */
114463c84b9SArnaldo Carvalho de Melo 		__u8		  quick;	 /* Scheduled number of quick acks	   */
115463c84b9SArnaldo Carvalho de Melo 		__u8		  pingpong;	 /* The session is interactive		   */
116a37c2134SEric Dumazet 		__u8		  retry;	 /* Number of attempts			   */
117463c84b9SArnaldo Carvalho de Melo 		__u32		  ato;		 /* Predicted tick of soft clock	   */
118463c84b9SArnaldo Carvalho de Melo 		unsigned long	  timeout;	 /* Currently scheduled timeout		   */
119463c84b9SArnaldo Carvalho de Melo 		__u32		  lrcvtime;	 /* timestamp of last received data packet */
120463c84b9SArnaldo Carvalho de Melo 		__u16		  last_seg_size; /* Size of last incoming segment	   */
121463c84b9SArnaldo Carvalho de Melo 		__u16		  rcv_mss;	 /* MSS used for delayed ACK decisions	   */
122463c84b9SArnaldo Carvalho de Melo 	} icsk_ack;
1235d424d5aSJohn Heffner 	struct {
1245d424d5aSJohn Heffner 		/* Range of MTUs to search */
1255d424d5aSJohn Heffner 		int		  search_high;
1265d424d5aSJohn Heffner 		int		  search_low;
1275d424d5aSJohn Heffner 
1285d424d5aSJohn Heffner 		/* Information on the current probe. */
12914e8e0f6SNeal Cardwell 		u32		  probe_size:31,
13014e8e0f6SNeal Cardwell 		/* Is the MTUP feature enabled for this connection? */
13114e8e0f6SNeal Cardwell 				  enabled:1;
13205cbc0dbSFan Du 
13305cbc0dbSFan Du 		u32		  probe_timestamp;
1345d424d5aSJohn Heffner 	} icsk_mtup;
1359d9b1ee0SEnke Chen 	u32			  icsk_probes_tstamp;
136dca43c75SJerry Chu 	u32			  icsk_user_timeout;
137b5d721d7SEric Dumazet 
13878dc70ebSPriyaranjan Jha 	u64			  icsk_ca_priv[104 / sizeof(u64)];
1393f8ad50aSEric Dumazet #define ICSK_CA_PRIV_SIZE	  sizeof_field(struct inet_connection_sock, icsk_ca_priv)
140463c84b9SArnaldo Carvalho de Melo };
141463c84b9SArnaldo Carvalho de Melo 
1423f421baaSArnaldo Carvalho de Melo #define ICSK_TIME_RETRANS	1	/* Retransmit timer */
1433f421baaSArnaldo Carvalho de Melo #define ICSK_TIME_DACK		2	/* Delayed ack timer */
1443f421baaSArnaldo Carvalho de Melo #define ICSK_TIME_PROBE0	3	/* Zero window probe timer */
1456ba8a3b1SNandita Dukkipati #define ICSK_TIME_LOSS_PROBE	5	/* Tail loss probe timer */
14657dde7f7SYuchung Cheng #define ICSK_TIME_REO_TIMEOUT	6	/* Reordering timer */
1473f421baaSArnaldo Carvalho de Melo 
inet_csk(const struct sock * sk)148463c84b9SArnaldo Carvalho de Melo static inline struct inet_connection_sock *inet_csk(const struct sock *sk)
149463c84b9SArnaldo Carvalho de Melo {
150463c84b9SArnaldo Carvalho de Melo 	return (struct inet_connection_sock *)sk;
151463c84b9SArnaldo Carvalho de Melo }
152463c84b9SArnaldo Carvalho de Melo 
inet_csk_ca(const struct sock * sk)1536687e988SArnaldo Carvalho de Melo static inline void *inet_csk_ca(const struct sock *sk)
1546687e988SArnaldo Carvalho de Melo {
1556687e988SArnaldo Carvalho de Melo 	return (void *)inet_csk(sk)->icsk_ca_priv;
1566687e988SArnaldo Carvalho de Melo }
1576687e988SArnaldo Carvalho de Melo 
1581fd51155SJoe Perches struct sock *inet_csk_clone_lock(const struct sock *sk,
1599f1d2604SArnaldo Carvalho de Melo 				 const struct request_sock *req,
160dd0fc66fSAl Viro 				 const gfp_t priority);
1619f1d2604SArnaldo Carvalho de Melo 
1623f421baaSArnaldo Carvalho de Melo enum inet_csk_ack_state_t {
1633f421baaSArnaldo Carvalho de Melo 	ICSK_ACK_SCHED	= 1,
1643f421baaSArnaldo Carvalho de Melo 	ICSK_ACK_TIMER  = 2,
1651ef9696cSAlexey Kuznetsov 	ICSK_ACK_PUSHED = 4,
166466466dcSYuchung Cheng 	ICSK_ACK_PUSHED2 = 8,
167e2142825SMenglong Dong 	ICSK_ACK_NOW = 16,	/* Send the next ACK immediately (once) */
168e2142825SMenglong Dong 	ICSK_ACK_NOMEM = 32,
1693f421baaSArnaldo Carvalho de Melo };
1703f421baaSArnaldo Carvalho de Melo 
1711fd51155SJoe Perches void inet_csk_init_xmit_timers(struct sock *sk,
17259f379f9SKees Cook 			       void (*retransmit_handler)(struct timer_list *),
17359f379f9SKees Cook 			       void (*delack_handler)(struct timer_list *),
17459f379f9SKees Cook 			       void (*keepalive_handler)(struct timer_list *));
1751fd51155SJoe Perches void inet_csk_clear_xmit_timers(struct sock *sk);
176c1ae4d1eSEric Dumazet void inet_csk_clear_xmit_timers_sync(struct sock *sk);
177463c84b9SArnaldo Carvalho de Melo 
inet_csk_schedule_ack(struct sock * sk)1783f421baaSArnaldo Carvalho de Melo static inline void inet_csk_schedule_ack(struct sock *sk)
1793f421baaSArnaldo Carvalho de Melo {
1803f421baaSArnaldo Carvalho de Melo 	inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_SCHED;
1813f421baaSArnaldo Carvalho de Melo }
1823f421baaSArnaldo Carvalho de Melo 
inet_csk_ack_scheduled(const struct sock * sk)1833f421baaSArnaldo Carvalho de Melo static inline int inet_csk_ack_scheduled(const struct sock *sk)
1843f421baaSArnaldo Carvalho de Melo {
1853f421baaSArnaldo Carvalho de Melo 	return inet_csk(sk)->icsk_ack.pending & ICSK_ACK_SCHED;
1863f421baaSArnaldo Carvalho de Melo }
1873f421baaSArnaldo Carvalho de Melo 
inet_csk_delack_init(struct sock * sk)1883f421baaSArnaldo Carvalho de Melo static inline void inet_csk_delack_init(struct sock *sk)
1893f421baaSArnaldo Carvalho de Melo {
1903f421baaSArnaldo Carvalho de Melo 	memset(&inet_csk(sk)->icsk_ack, 0, sizeof(inet_csk(sk)->icsk_ack));
1913f421baaSArnaldo Carvalho de Melo }
1923f421baaSArnaldo Carvalho de Melo 
1931fd51155SJoe Perches void inet_csk_delete_keepalive_timer(struct sock *sk);
1941fd51155SJoe Perches void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long timeout);
1953f421baaSArnaldo Carvalho de Melo 
inet_csk_clear_xmit_timer(struct sock * sk,const int what)1963f421baaSArnaldo Carvalho de Melo static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what)
1973f421baaSArnaldo Carvalho de Melo {
1983f421baaSArnaldo Carvalho de Melo 	struct inet_connection_sock *icsk = inet_csk(sk);
1993f421baaSArnaldo Carvalho de Melo 
2003f421baaSArnaldo Carvalho de Melo 	if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
2013f421baaSArnaldo Carvalho de Melo 		icsk->icsk_pending = 0;
2023f421baaSArnaldo Carvalho de Melo #ifdef INET_CSK_CLEAR_TIMERS
2033f421baaSArnaldo Carvalho de Melo 		sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
2043f421baaSArnaldo Carvalho de Melo #endif
2053f421baaSArnaldo Carvalho de Melo 	} else if (what == ICSK_TIME_DACK) {
206b6b6d653SEric Dumazet 		icsk->icsk_ack.pending = 0;
207a37c2134SEric Dumazet 		icsk->icsk_ack.retry = 0;
2083f421baaSArnaldo Carvalho de Melo #ifdef INET_CSK_CLEAR_TIMERS
2093f421baaSArnaldo Carvalho de Melo 		sk_stop_timer(sk, &icsk->icsk_delack_timer);
2103f421baaSArnaldo Carvalho de Melo #endif
21103bdfc00SJoe Perches 	} else {
21203bdfc00SJoe Perches 		pr_debug("inet_csk BUG: unknown timer value\n");
2133f421baaSArnaldo Carvalho de Melo 	}
2143f421baaSArnaldo Carvalho de Melo }
2153f421baaSArnaldo Carvalho de Melo 
2163f421baaSArnaldo Carvalho de Melo /*
2173f421baaSArnaldo Carvalho de Melo  *	Reset the retransmission timer
2183f421baaSArnaldo Carvalho de Melo  */
inet_csk_reset_xmit_timer(struct sock * sk,const int what,unsigned long when,const unsigned long max_when)2193f421baaSArnaldo Carvalho de Melo static inline void inet_csk_reset_xmit_timer(struct sock *sk, const int what,
2203f421baaSArnaldo Carvalho de Melo 					     unsigned long when,
2213f421baaSArnaldo Carvalho de Melo 					     const unsigned long max_when)
2223f421baaSArnaldo Carvalho de Melo {
2233f421baaSArnaldo Carvalho de Melo 	struct inet_connection_sock *icsk = inet_csk(sk);
2243f421baaSArnaldo Carvalho de Melo 
2253f421baaSArnaldo Carvalho de Melo 	if (when > max_when) {
2263f421baaSArnaldo Carvalho de Melo 		pr_debug("reset_xmit_timer: sk=%p %d when=0x%lx, caller=%p\n",
22796d18d82SNick Desaulniers 			 sk, what, when, (void *)_THIS_IP_);
2283f421baaSArnaldo Carvalho de Melo 		when = max_when;
2293f421baaSArnaldo Carvalho de Melo 	}
2303f421baaSArnaldo Carvalho de Melo 
2316ba8a3b1SNandita Dukkipati 	if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0 ||
232a05a7280SPengcheng Yang 	    what == ICSK_TIME_LOSS_PROBE || what == ICSK_TIME_REO_TIMEOUT) {
2333f421baaSArnaldo Carvalho de Melo 		icsk->icsk_pending = what;
2343f421baaSArnaldo Carvalho de Melo 		icsk->icsk_timeout = jiffies + when;
2353f421baaSArnaldo Carvalho de Melo 		sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
2363f421baaSArnaldo Carvalho de Melo 	} else if (what == ICSK_TIME_DACK) {
2373f421baaSArnaldo Carvalho de Melo 		icsk->icsk_ack.pending |= ICSK_ACK_TIMER;
2383f421baaSArnaldo Carvalho de Melo 		icsk->icsk_ack.timeout = jiffies + when;
2393f421baaSArnaldo Carvalho de Melo 		sk_reset_timer(sk, &icsk->icsk_delack_timer, icsk->icsk_ack.timeout);
24003bdfc00SJoe Perches 	} else {
24103bdfc00SJoe Perches 		pr_debug("inet_csk BUG: unknown timer value\n");
2423f421baaSArnaldo Carvalho de Melo 	}
2433f421baaSArnaldo Carvalho de Melo }
2443f421baaSArnaldo Carvalho de Melo 
245fcdd1cf4SEric Dumazet static inline unsigned long
inet_csk_rto_backoff(const struct inet_connection_sock * icsk,unsigned long max_when)246fcdd1cf4SEric Dumazet inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
247fcdd1cf4SEric Dumazet 		     unsigned long max_when)
248fcdd1cf4SEric Dumazet {
249fcdd1cf4SEric Dumazet         u64 when = (u64)icsk->icsk_rto << icsk->icsk_backoff;
250fcdd1cf4SEric Dumazet 
251fcdd1cf4SEric Dumazet         return (unsigned long)min_t(u64, when, max_when);
252fcdd1cf4SEric Dumazet }
253fcdd1cf4SEric Dumazet 
254cdfbabfbSDavid Howells struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern);
2553f421baaSArnaldo Carvalho de Melo 
2561fd51155SJoe Perches int inet_csk_get_port(struct sock *sk, unsigned short snum);
257463c84b9SArnaldo Carvalho de Melo 
258e5895bc6SEric Dumazet struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4,
259ba3f7f04SDavid S. Miller 				     const struct request_sock *req);
260a2432c4fSEric Dumazet struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
261a2432c4fSEric Dumazet 					    struct sock *newsk,
26277357a95SDavid S. Miller 					    const struct request_sock *req);
263463c84b9SArnaldo Carvalho de Melo 
2647716682cSEric Dumazet struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
2657716682cSEric Dumazet 				      struct request_sock *req,
266ebb516afSEric Dumazet 				      struct sock *child);
267fdae4d13Sluoxuanqiang bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
268c2977c22SArnaldo Carvalho de Melo 				   unsigned long timeout);
2695e0724d0SEric Dumazet struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child,
2705e0724d0SEric Dumazet 					 struct request_sock *req,
2715e0724d0SEric Dumazet 					 bool own_req);
2723f421baaSArnaldo Carvalho de Melo 
inet_csk_reqsk_queue_added(struct sock * sk)2732feda341SEric Dumazet static inline void inet_csk_reqsk_queue_added(struct sock *sk)
2743f421baaSArnaldo Carvalho de Melo {
275fa76ce73SEric Dumazet 	reqsk_queue_added(&inet_csk(sk)->icsk_accept_queue);
2763f421baaSArnaldo Carvalho de Melo }
2773f421baaSArnaldo Carvalho de Melo 
inet_csk_reqsk_queue_len(const struct sock * sk)2783f421baaSArnaldo Carvalho de Melo static inline int inet_csk_reqsk_queue_len(const struct sock *sk)
2793f421baaSArnaldo Carvalho de Melo {
2803f421baaSArnaldo Carvalho de Melo 	return reqsk_queue_len(&inet_csk(sk)->icsk_accept_queue);
2813f421baaSArnaldo Carvalho de Melo }
2823f421baaSArnaldo Carvalho de Melo 
inet_csk_reqsk_queue_is_full(const struct sock * sk)2833f421baaSArnaldo Carvalho de Melo static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
2843f421baaSArnaldo Carvalho de Melo {
285*91f89fe1SZhongqiu Duan 	return inet_csk_reqsk_queue_len(sk) > READ_ONCE(sk->sk_max_ack_backlog);
2863f421baaSArnaldo Carvalho de Melo }
2873f421baaSArnaldo Carvalho de Melo 
2887233da86SAlexander Ovechkin bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req);
289f03f2e15SEric Dumazet void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req);
2903f421baaSArnaldo Carvalho de Melo 
2915903123fSAkhmat Karakotov static inline unsigned long
reqsk_timeout(struct request_sock * req,unsigned long max_timeout)2925903123fSAkhmat Karakotov reqsk_timeout(struct request_sock *req, unsigned long max_timeout)
2935903123fSAkhmat Karakotov {
2945903123fSAkhmat Karakotov 	u64 timeout = (u64)req->timeout << req->num_timeout;
2955903123fSAkhmat Karakotov 
2965903123fSAkhmat Karakotov 	return (unsigned long)min_t(u64, timeout, max_timeout);
2975903123fSAkhmat Karakotov }
2985903123fSAkhmat Karakotov 
inet_csk_prepare_for_destroy_sock(struct sock * sk)2992f8a397dSPaolo Abeni static inline void inet_csk_prepare_for_destroy_sock(struct sock *sk)
3002f8a397dSPaolo Abeni {
3012f8a397dSPaolo Abeni 	/* The below has to be done to allow calling inet_csk_destroy_sock */
3022f8a397dSPaolo Abeni 	sock_set_flag(sk, SOCK_DEAD);
30319757cebSEric Dumazet 	this_cpu_inc(*sk->sk_prot->orphan_count);
3042f8a397dSPaolo Abeni }
3052f8a397dSPaolo Abeni 
3061fd51155SJoe Perches void inet_csk_destroy_sock(struct sock *sk);
3071fd51155SJoe Perches void inet_csk_prepare_forced_close(struct sock *sk);
308dc40c7bcSArnaldo Carvalho de Melo 
309dc40c7bcSArnaldo Carvalho de Melo /*
310dc40c7bcSArnaldo Carvalho de Melo  * LISTEN is a special case for poll..
311dc40c7bcSArnaldo Carvalho de Melo  */
inet_csk_listen_poll(const struct sock * sk)312ade994f4SAl Viro static inline __poll_t inet_csk_listen_poll(const struct sock *sk)
313dc40c7bcSArnaldo Carvalho de Melo {
314dc40c7bcSArnaldo Carvalho de Melo 	return !reqsk_queue_empty(&inet_csk(sk)->icsk_accept_queue) ?
315a9a08845SLinus Torvalds 			(EPOLLIN | EPOLLRDNORM) : 0;
316dc40c7bcSArnaldo Carvalho de Melo }
317dc40c7bcSArnaldo Carvalho de Melo 
318e7049395SKuniyuki Iwashima int inet_csk_listen_start(struct sock *sk);
3191fd51155SJoe Perches void inet_csk_listen_stop(struct sock *sk);
320295f7324SArnaldo Carvalho de Melo 
3211fd51155SJoe Perches void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
322af05dc93SArnaldo Carvalho de Melo 
32362ffc589STim Froidcoeur /* update the fast reuse flag when adding a socket */
32462ffc589STim Froidcoeur void inet_csk_update_fastreuse(struct inet_bind_bucket *tb,
32562ffc589STim Froidcoeur 			       struct sock *sk);
32662ffc589STim Froidcoeur 
3271fd51155SJoe Perches struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu);
32831954cd8SWei Wang 
3294d8f24eeSWei Wang #define TCP_PINGPONG_THRESH	1
33031954cd8SWei Wang 
inet_csk_enter_pingpong_mode(struct sock * sk)33131954cd8SWei Wang static inline void inet_csk_enter_pingpong_mode(struct sock *sk)
33231954cd8SWei Wang {
33331954cd8SWei Wang 	inet_csk(sk)->icsk_ack.pingpong = TCP_PINGPONG_THRESH;
33431954cd8SWei Wang }
33531954cd8SWei Wang 
inet_csk_exit_pingpong_mode(struct sock * sk)33631954cd8SWei Wang static inline void inet_csk_exit_pingpong_mode(struct sock *sk)
33731954cd8SWei Wang {
33831954cd8SWei Wang 	inet_csk(sk)->icsk_ack.pingpong = 0;
33931954cd8SWei Wang }
34031954cd8SWei Wang 
inet_csk_in_pingpong_mode(struct sock * sk)34131954cd8SWei Wang static inline bool inet_csk_in_pingpong_mode(struct sock *sk)
34231954cd8SWei Wang {
34331954cd8SWei Wang 	return inet_csk(sk)->icsk_ack.pingpong >= TCP_PINGPONG_THRESH;
34431954cd8SWei Wang }
3454a41f453SWei Wang 
inet_csk_has_ulp(const struct sock * sk)346b1c0356aSEric Dumazet static inline bool inet_csk_has_ulp(const struct sock *sk)
3477b70973dSLorenz Bauer {
348b1c0356aSEric Dumazet 	return inet_test_bit(IS_ICSK, sk) && !!inet_csk(sk)->icsk_ulp_ops;
3497b70973dSLorenz Bauer }
3507b70973dSLorenz Bauer 
inet_init_csk_locks(struct sock * sk)351168e7e59SZhengchao Shao static inline void inet_init_csk_locks(struct sock *sk)
352168e7e59SZhengchao Shao {
353168e7e59SZhengchao Shao 	struct inet_connection_sock *icsk = inet_csk(sk);
354168e7e59SZhengchao Shao 
355168e7e59SZhengchao Shao 	spin_lock_init(&icsk->icsk_accept_queue.rskq_lock);
356168e7e59SZhengchao Shao 	spin_lock_init(&icsk->icsk_accept_queue.fastopenq.lock);
357168e7e59SZhengchao Shao }
358168e7e59SZhengchao Shao 
359463c84b9SArnaldo Carvalho de Melo #endif /* _INET_CONNECTION_SOCK_H */
360