1#ifndef _LINUX_DCCP_H
2#define _LINUX_DCCP_H
3
4
5#include <linux/in.h>
6#include <linux/interrupt.h>
7#include <linux/ktime.h>
8#include <linux/list.h>
9#include <linux/uio.h>
10#include <linux/workqueue.h>
11
12#include <net/inet_connection_sock.h>
13#include <net/inet_sock.h>
14#include <net/inet_timewait_sock.h>
15#include <net/tcp_states.h>
16#include <uapi/linux/dccp.h>
17
18enum dccp_state {
19 DCCP_OPEN = TCP_ESTABLISHED,
20 DCCP_REQUESTING = TCP_SYN_SENT,
21 DCCP_LISTEN = TCP_LISTEN,
22 DCCP_RESPOND = TCP_SYN_RECV,
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 DCCP_ACTIVE_CLOSEREQ = TCP_FIN_WAIT1,
42 DCCP_PASSIVE_CLOSE = TCP_CLOSE_WAIT,
43 DCCP_CLOSING = TCP_CLOSING,
44 DCCP_TIME_WAIT = TCP_TIME_WAIT,
45 DCCP_CLOSED = TCP_CLOSE,
46 DCCP_NEW_SYN_RECV = TCP_NEW_SYN_RECV,
47 DCCP_PARTOPEN = TCP_MAX_STATES,
48 DCCP_PASSIVE_CLOSEREQ,
49 DCCP_MAX_STATES
50};
51
52enum {
53 DCCPF_OPEN = TCPF_ESTABLISHED,
54 DCCPF_REQUESTING = TCPF_SYN_SENT,
55 DCCPF_LISTEN = TCPF_LISTEN,
56 DCCPF_RESPOND = TCPF_SYN_RECV,
57 DCCPF_ACTIVE_CLOSEREQ = TCPF_FIN_WAIT1,
58 DCCPF_CLOSING = TCPF_CLOSING,
59 DCCPF_TIME_WAIT = TCPF_TIME_WAIT,
60 DCCPF_CLOSED = TCPF_CLOSE,
61 DCCPF_NEW_SYN_RECV = TCPF_NEW_SYN_RECV,
62 DCCPF_PARTOPEN = (1 << DCCP_PARTOPEN),
63};
64
65static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb)
66{
67 return (struct dccp_hdr *)skb_transport_header(skb);
68}
69
70static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen)
71{
72 skb_push(skb, headlen);
73 skb_reset_transport_header(skb);
74 return memset(skb_transport_header(skb), 0, headlen);
75}
76
77static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh)
78{
79 return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh));
80}
81
82static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
83{
84 return sizeof(*dh) + (dh->dccph_x ? sizeof(struct dccp_hdr_ext) : 0);
85}
86
87static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
88{
89 const struct dccp_hdr *dh = dccp_hdr(skb);
90 return __dccp_basic_hdr_len(dh);
91}
92
93static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh)
94{
95 __u64 seq_nr = ntohs(dh->dccph_seq);
96
97 if (dh->dccph_x != 0)
98 seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low);
99 else
100 seq_nr += (u32)dh->dccph_seq2 << 16;
101
102 return seq_nr;
103}
104
105static inline struct dccp_hdr_request *dccp_hdr_request(struct sk_buff *skb)
106{
107 return (struct dccp_hdr_request *)(skb_transport_header(skb) +
108 dccp_basic_hdr_len(skb));
109}
110
111static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff *skb)
112{
113 return (struct dccp_hdr_ack_bits *)(skb_transport_header(skb) +
114 dccp_basic_hdr_len(skb));
115}
116
117static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb)
118{
119 const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb);
120 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low);
121}
122
123static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb)
124{
125 return (struct dccp_hdr_response *)(skb_transport_header(skb) +
126 dccp_basic_hdr_len(skb));
127}
128
129static inline struct dccp_hdr_reset *dccp_hdr_reset(struct sk_buff *skb)
130{
131 return (struct dccp_hdr_reset *)(skb_transport_header(skb) +
132 dccp_basic_hdr_len(skb));
133}
134
135static inline unsigned int __dccp_hdr_len(const struct dccp_hdr *dh)
136{
137 return __dccp_basic_hdr_len(dh) +
138 dccp_packet_hdr_len(dh->dccph_type);
139}
140
141static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
142{
143 return __dccp_hdr_len(dccp_hdr(skb));
144}
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159struct dccp_request_sock {
160 struct inet_request_sock dreq_inet_rsk;
161 __u64 dreq_iss;
162 __u64 dreq_gss;
163 __u64 dreq_isr;
164 __u64 dreq_gsr;
165 __be32 dreq_service;
166 spinlock_t dreq_lock;
167 struct list_head dreq_featneg;
168 __u32 dreq_timestamp_echo;
169 __u32 dreq_timestamp_time;
170};
171
172static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
173{
174 return (struct dccp_request_sock *)req;
175}
176
177extern struct inet_timewait_death_row dccp_death_row;
178
179extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
180 struct sk_buff *skb);
181
182struct dccp_options_received {
183 u64 dccpor_ndp:48;
184 u32 dccpor_timestamp;
185 u32 dccpor_timestamp_echo;
186 u32 dccpor_elapsed_time;
187};
188
189struct ccid;
190
191enum dccp_role {
192 DCCP_ROLE_UNDEFINED,
193 DCCP_ROLE_LISTEN,
194 DCCP_ROLE_CLIENT,
195 DCCP_ROLE_SERVER,
196};
197
198struct dccp_service_list {
199 __u32 dccpsl_nr;
200 __be32 dccpsl_list[0];
201};
202
203#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
204#define DCCP_SERVICE_CODE_IS_ABSENT 0
205
206static inline bool dccp_list_has_service(const struct dccp_service_list *sl,
207 const __be32 service)
208{
209 if (likely(sl != NULL)) {
210 u32 i = sl->dccpsl_nr;
211 while (i--)
212 if (sl->dccpsl_list[i] == service)
213 return true;
214 }
215 return false;
216}
217
218struct dccp_ackvec;
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263struct dccp_sock {
264
265 struct inet_connection_sock dccps_inet_connection;
266#define dccps_syn_rtt dccps_inet_connection.icsk_ack.lrcvtime
267 __u64 dccps_swl;
268 __u64 dccps_swh;
269 __u64 dccps_awl;
270 __u64 dccps_awh;
271 __u64 dccps_iss;
272 __u64 dccps_isr;
273 __u64 dccps_osr;
274 __u64 dccps_gss;
275 __u64 dccps_gsr;
276 __u64 dccps_gar;
277 __be32 dccps_service;
278 __u32 dccps_mss_cache;
279 struct dccp_service_list *dccps_service_list;
280 __u32 dccps_timestamp_echo;
281 __u32 dccps_timestamp_time;
282 __u16 dccps_l_ack_ratio;
283 __u16 dccps_r_ack_ratio;
284 __u64 dccps_l_seq_win:48;
285 __u64 dccps_r_seq_win:48;
286 __u8 dccps_pcslen:4;
287 __u8 dccps_pcrlen:4;
288 __u8 dccps_send_ndp_count:1;
289 __u64 dccps_ndp_count:48;
290 unsigned long dccps_rate_last;
291 struct list_head dccps_featneg;
292 struct dccp_ackvec *dccps_hc_rx_ackvec;
293 struct ccid *dccps_hc_rx_ccid;
294 struct ccid *dccps_hc_tx_ccid;
295 struct dccp_options_received dccps_options_received;
296 __u8 dccps_qpolicy;
297 __u32 dccps_tx_qlen;
298 enum dccp_role dccps_role:2;
299 __u8 dccps_hc_rx_insert_options:1;
300 __u8 dccps_hc_tx_insert_options:1;
301 __u8 dccps_server_timewait:1;
302 __u8 dccps_sync_scheduled:1;
303 struct tasklet_struct dccps_xmitlet;
304 struct timer_list dccps_xmit_timer;
305};
306
307static inline struct dccp_sock *dccp_sk(const struct sock *sk)
308{
309 return (struct dccp_sock *)sk;
310}
311
312static inline const char *dccp_role(const struct sock *sk)
313{
314 switch (dccp_sk(sk)->dccps_role) {
315 case DCCP_ROLE_UNDEFINED: return "undefined";
316 case DCCP_ROLE_LISTEN: return "listen";
317 case DCCP_ROLE_SERVER: return "server";
318 case DCCP_ROLE_CLIENT: return "client";
319 }
320 return NULL;
321}
322
323extern void dccp_syn_ack_timeout(const struct request_sock *req);
324
325#endif
326