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_PARTOPEN = TCP_MAX_STATES,
47 DCCP_PASSIVE_CLOSEREQ,
48 DCCP_MAX_STATES
49};
50
51enum {
52 DCCPF_OPEN = TCPF_ESTABLISHED,
53 DCCPF_REQUESTING = TCPF_SYN_SENT,
54 DCCPF_LISTEN = TCPF_LISTEN,
55 DCCPF_RESPOND = TCPF_SYN_RECV,
56 DCCPF_ACTIVE_CLOSEREQ = TCPF_FIN_WAIT1,
57 DCCPF_CLOSING = TCPF_CLOSING,
58 DCCPF_TIME_WAIT = TCPF_TIME_WAIT,
59 DCCPF_CLOSED = TCPF_CLOSE,
60 DCCPF_PARTOPEN = (1 << DCCP_PARTOPEN),
61};
62
63static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb)
64{
65 return (struct dccp_hdr *)skb_transport_header(skb);
66}
67
68static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen)
69{
70 skb_push(skb, headlen);
71 skb_reset_transport_header(skb);
72 return memset(skb_transport_header(skb), 0, headlen);
73}
74
75static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh)
76{
77 return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh));
78}
79
80static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
81{
82 return sizeof(*dh) + (dh->dccph_x ? sizeof(struct dccp_hdr_ext) : 0);
83}
84
85static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
86{
87 const struct dccp_hdr *dh = dccp_hdr(skb);
88 return __dccp_basic_hdr_len(dh);
89}
90
91static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh)
92{
93 __u64 seq_nr = ntohs(dh->dccph_seq);
94
95 if (dh->dccph_x != 0)
96 seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low);
97 else
98 seq_nr += (u32)dh->dccph_seq2 << 16;
99
100 return seq_nr;
101}
102
103static inline struct dccp_hdr_request *dccp_hdr_request(struct sk_buff *skb)
104{
105 return (struct dccp_hdr_request *)(skb_transport_header(skb) +
106 dccp_basic_hdr_len(skb));
107}
108
109static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff *skb)
110{
111 return (struct dccp_hdr_ack_bits *)(skb_transport_header(skb) +
112 dccp_basic_hdr_len(skb));
113}
114
115static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb)
116{
117 const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb);
118 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low);
119}
120
121static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb)
122{
123 return (struct dccp_hdr_response *)(skb_transport_header(skb) +
124 dccp_basic_hdr_len(skb));
125}
126
127static inline struct dccp_hdr_reset *dccp_hdr_reset(struct sk_buff *skb)
128{
129 return (struct dccp_hdr_reset *)(skb_transport_header(skb) +
130 dccp_basic_hdr_len(skb));
131}
132
133static inline unsigned int __dccp_hdr_len(const struct dccp_hdr *dh)
134{
135 return __dccp_basic_hdr_len(dh) +
136 dccp_packet_hdr_len(dh->dccph_type);
137}
138
139static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
140{
141 return __dccp_hdr_len(dccp_hdr(skb));
142}
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157struct dccp_request_sock {
158 struct inet_request_sock dreq_inet_rsk;
159 __u64 dreq_iss;
160 __u64 dreq_gss;
161 __u64 dreq_isr;
162 __u64 dreq_gsr;
163 __be32 dreq_service;
164 struct list_head dreq_featneg;
165 __u32 dreq_timestamp_echo;
166 __u32 dreq_timestamp_time;
167};
168
169static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
170{
171 return (struct dccp_request_sock *)req;
172}
173
174extern struct inet_timewait_death_row dccp_death_row;
175
176extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
177 struct sk_buff *skb);
178
179struct dccp_options_received {
180 u64 dccpor_ndp:48;
181 u32 dccpor_timestamp;
182 u32 dccpor_timestamp_echo;
183 u32 dccpor_elapsed_time;
184};
185
186struct ccid;
187
188enum dccp_role {
189 DCCP_ROLE_UNDEFINED,
190 DCCP_ROLE_LISTEN,
191 DCCP_ROLE_CLIENT,
192 DCCP_ROLE_SERVER,
193};
194
195struct dccp_service_list {
196 __u32 dccpsl_nr;
197 __be32 dccpsl_list[0];
198};
199
200#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
201#define DCCP_SERVICE_CODE_IS_ABSENT 0
202
203static inline int dccp_list_has_service(const struct dccp_service_list *sl,
204 const __be32 service)
205{
206 if (likely(sl != NULL)) {
207 u32 i = sl->dccpsl_nr;
208 while (i--)
209 if (sl->dccpsl_list[i] == service)
210 return 1;
211 }
212 return 0;
213}
214
215struct dccp_ackvec;
216
217
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
260struct dccp_sock {
261
262 struct inet_connection_sock dccps_inet_connection;
263#define dccps_syn_rtt dccps_inet_connection.icsk_ack.lrcvtime
264 __u64 dccps_swl;
265 __u64 dccps_swh;
266 __u64 dccps_awl;
267 __u64 dccps_awh;
268 __u64 dccps_iss;
269 __u64 dccps_isr;
270 __u64 dccps_osr;
271 __u64 dccps_gss;
272 __u64 dccps_gsr;
273 __u64 dccps_gar;
274 __be32 dccps_service;
275 __u32 dccps_mss_cache;
276 struct dccp_service_list *dccps_service_list;
277 __u32 dccps_timestamp_echo;
278 __u32 dccps_timestamp_time;
279 __u16 dccps_l_ack_ratio;
280 __u16 dccps_r_ack_ratio;
281 __u64 dccps_l_seq_win:48;
282 __u64 dccps_r_seq_win:48;
283 __u8 dccps_pcslen:4;
284 __u8 dccps_pcrlen:4;
285 __u8 dccps_send_ndp_count:1;
286 __u64 dccps_ndp_count:48;
287 unsigned long dccps_rate_last;
288 struct list_head dccps_featneg;
289 struct dccp_ackvec *dccps_hc_rx_ackvec;
290 struct ccid *dccps_hc_rx_ccid;
291 struct ccid *dccps_hc_tx_ccid;
292 struct dccp_options_received dccps_options_received;
293 __u8 dccps_qpolicy;
294 __u32 dccps_tx_qlen;
295 enum dccp_role dccps_role:2;
296 __u8 dccps_hc_rx_insert_options:1;
297 __u8 dccps_hc_tx_insert_options:1;
298 __u8 dccps_server_timewait:1;
299 __u8 dccps_sync_scheduled:1;
300 struct tasklet_struct dccps_xmitlet;
301 struct timer_list dccps_xmit_timer;
302};
303
304static inline struct dccp_sock *dccp_sk(const struct sock *sk)
305{
306 return (struct dccp_sock *)sk;
307}
308
309static inline const char *dccp_role(const struct sock *sk)
310{
311 switch (dccp_sk(sk)->dccps_role) {
312 case DCCP_ROLE_UNDEFINED: return "undefined";
313 case DCCP_ROLE_LISTEN: return "listen";
314 case DCCP_ROLE_SERVER: return "server";
315 case DCCP_ROLE_CLIENT: return "client";
316 }
317 return NULL;
318}
319
320extern void dccp_syn_ack_timeout(struct sock *sk, struct request_sock *req);
321
322#endif
323