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 struct list_head dreq_featneg;
167 __u32 dreq_timestamp_echo;
168 __u32 dreq_timestamp_time;
169};
170
171static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
172{
173 return (struct dccp_request_sock *)req;
174}
175
176extern struct inet_timewait_death_row dccp_death_row;
177
178extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
179 struct sk_buff *skb);
180
181struct dccp_options_received {
182 u64 dccpor_ndp:48;
183 u32 dccpor_timestamp;
184 u32 dccpor_timestamp_echo;
185 u32 dccpor_elapsed_time;
186};
187
188struct ccid;
189
190enum dccp_role {
191 DCCP_ROLE_UNDEFINED,
192 DCCP_ROLE_LISTEN,
193 DCCP_ROLE_CLIENT,
194 DCCP_ROLE_SERVER,
195};
196
197struct dccp_service_list {
198 __u32 dccpsl_nr;
199 __be32 dccpsl_list[0];
200};
201
202#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
203#define DCCP_SERVICE_CODE_IS_ABSENT 0
204
205static inline bool dccp_list_has_service(const struct dccp_service_list *sl,
206 const __be32 service)
207{
208 if (likely(sl != NULL)) {
209 u32 i = sl->dccpsl_nr;
210 while (i--)
211 if (sl->dccpsl_list[i] == service)
212 return true;
213 }
214 return false;
215}
216
217struct dccp_ackvec;
218
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
262struct dccp_sock {
263
264 struct inet_connection_sock dccps_inet_connection;
265#define dccps_syn_rtt dccps_inet_connection.icsk_ack.lrcvtime
266 __u64 dccps_swl;
267 __u64 dccps_swh;
268 __u64 dccps_awl;
269 __u64 dccps_awh;
270 __u64 dccps_iss;
271 __u64 dccps_isr;
272 __u64 dccps_osr;
273 __u64 dccps_gss;
274 __u64 dccps_gsr;
275 __u64 dccps_gar;
276 __be32 dccps_service;
277 __u32 dccps_mss_cache;
278 struct dccp_service_list *dccps_service_list;
279 __u32 dccps_timestamp_echo;
280 __u32 dccps_timestamp_time;
281 __u16 dccps_l_ack_ratio;
282 __u16 dccps_r_ack_ratio;
283 __u64 dccps_l_seq_win:48;
284 __u64 dccps_r_seq_win:48;
285 __u8 dccps_pcslen:4;
286 __u8 dccps_pcrlen:4;
287 __u8 dccps_send_ndp_count:1;
288 __u64 dccps_ndp_count:48;
289 unsigned long dccps_rate_last;
290 struct list_head dccps_featneg;
291 struct dccp_ackvec *dccps_hc_rx_ackvec;
292 struct ccid *dccps_hc_rx_ccid;
293 struct ccid *dccps_hc_tx_ccid;
294 struct dccp_options_received dccps_options_received;
295 __u8 dccps_qpolicy;
296 __u32 dccps_tx_qlen;
297 enum dccp_role dccps_role:2;
298 __u8 dccps_hc_rx_insert_options:1;
299 __u8 dccps_hc_tx_insert_options:1;
300 __u8 dccps_server_timewait:1;
301 __u8 dccps_sync_scheduled:1;
302 struct tasklet_struct dccps_xmitlet;
303 struct timer_list dccps_xmit_timer;
304};
305
306static inline struct dccp_sock *dccp_sk(const struct sock *sk)
307{
308 return (struct dccp_sock *)sk;
309}
310
311static inline const char *dccp_role(const struct sock *sk)
312{
313 switch (dccp_sk(sk)->dccps_role) {
314 case DCCP_ROLE_UNDEFINED: return "undefined";
315 case DCCP_ROLE_LISTEN: return "listen";
316 case DCCP_ROLE_SERVER: return "server";
317 case DCCP_ROLE_CLIENT: return "client";
318 }
319 return NULL;
320}
321
322extern void dccp_syn_ack_timeout(const struct request_sock *req);
323
324#endif
325