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