Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/dccp/ccid.h
15109 views
1
#ifndef _CCID_H
2
#define _CCID_H
3
/*
4
* net/dccp/ccid.h
5
*
6
* An implementation of the DCCP protocol
7
* Arnaldo Carvalho de Melo <[email protected]>
8
*
9
* CCID infrastructure
10
*
11
* This program is free software; you can redistribute it and/or modify it
12
* under the terms of the GNU General Public License version 2 as
13
* published by the Free Software Foundation.
14
*/
15
16
#include <net/sock.h>
17
#include <linux/compiler.h>
18
#include <linux/dccp.h>
19
#include <linux/list.h>
20
#include <linux/module.h>
21
22
/* maximum value for a CCID (RFC 4340, 19.5) */
23
#define CCID_MAX 255
24
#define CCID_SLAB_NAME_LENGTH 32
25
26
struct tcp_info;
27
28
/**
29
* struct ccid_operations - Interface to Congestion-Control Infrastructure
30
*
31
* @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
32
* @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
33
* @ccid_name: alphabetical identifier string for @ccid_id
34
* @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
35
* @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
36
*
37
* @ccid_hc_{r,t}x_init: CCID-specific initialisation routine (before startup)
38
* @ccid_hc_{r,t}x_exit: CCID-specific cleanup routine (before destruction)
39
* @ccid_hc_rx_packet_recv: implements the HC-receiver side
40
* @ccid_hc_{r,t}x_parse_options: parsing routine for CCID/HC-specific options
41
* @ccid_hc_{r,t}x_insert_options: insert routine for CCID/HC-specific options
42
* @ccid_hc_tx_packet_recv: implements feedback processing for the HC-sender
43
* @ccid_hc_tx_send_packet: implements the sending part of the HC-sender
44
* @ccid_hc_tx_packet_sent: does accounting for packets in flight by HC-sender
45
* @ccid_hc_{r,t}x_get_info: INET_DIAG information for HC-receiver/sender
46
* @ccid_hc_{r,t}x_getsockopt: socket options specific to HC-receiver/sender
47
*/
48
struct ccid_operations {
49
unsigned char ccid_id;
50
__u32 ccid_ccmps;
51
const char *ccid_name;
52
struct kmem_cache *ccid_hc_rx_slab,
53
*ccid_hc_tx_slab;
54
char ccid_hc_rx_slab_name[CCID_SLAB_NAME_LENGTH];
55
char ccid_hc_tx_slab_name[CCID_SLAB_NAME_LENGTH];
56
__u32 ccid_hc_rx_obj_size,
57
ccid_hc_tx_obj_size;
58
/* Interface Routines */
59
int (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk);
60
int (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk);
61
void (*ccid_hc_rx_exit)(struct sock *sk);
62
void (*ccid_hc_tx_exit)(struct sock *sk);
63
void (*ccid_hc_rx_packet_recv)(struct sock *sk,
64
struct sk_buff *skb);
65
int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt,
66
u8 opt, u8 *val, u8 len);
67
int (*ccid_hc_rx_insert_options)(struct sock *sk,
68
struct sk_buff *skb);
69
void (*ccid_hc_tx_packet_recv)(struct sock *sk,
70
struct sk_buff *skb);
71
int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt,
72
u8 opt, u8 *val, u8 len);
73
int (*ccid_hc_tx_send_packet)(struct sock *sk,
74
struct sk_buff *skb);
75
void (*ccid_hc_tx_packet_sent)(struct sock *sk,
76
unsigned int len);
77
void (*ccid_hc_rx_get_info)(struct sock *sk,
78
struct tcp_info *info);
79
void (*ccid_hc_tx_get_info)(struct sock *sk,
80
struct tcp_info *info);
81
int (*ccid_hc_rx_getsockopt)(struct sock *sk,
82
const int optname, int len,
83
u32 __user *optval,
84
int __user *optlen);
85
int (*ccid_hc_tx_getsockopt)(struct sock *sk,
86
const int optname, int len,
87
u32 __user *optval,
88
int __user *optlen);
89
};
90
91
extern struct ccid_operations ccid2_ops;
92
#ifdef CONFIG_IP_DCCP_CCID3
93
extern struct ccid_operations ccid3_ops;
94
#endif
95
96
extern int ccid_initialize_builtins(void);
97
extern void ccid_cleanup_builtins(void);
98
99
struct ccid {
100
struct ccid_operations *ccid_ops;
101
char ccid_priv[0];
102
};
103
104
static inline void *ccid_priv(const struct ccid *ccid)
105
{
106
return (void *)ccid->ccid_priv;
107
}
108
109
extern bool ccid_support_check(u8 const *ccid_array, u8 array_len);
110
extern int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len);
111
extern int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
112
char __user *, int __user *);
113
114
extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
115
116
static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
117
{
118
struct ccid *ccid = dp->dccps_hc_rx_ccid;
119
120
if (ccid == NULL || ccid->ccid_ops == NULL)
121
return -1;
122
return ccid->ccid_ops->ccid_id;
123
}
124
125
static inline int ccid_get_current_tx_ccid(struct dccp_sock *dp)
126
{
127
struct ccid *ccid = dp->dccps_hc_tx_ccid;
128
129
if (ccid == NULL || ccid->ccid_ops == NULL)
130
return -1;
131
return ccid->ccid_ops->ccid_id;
132
}
133
134
extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk);
135
extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk);
136
137
/*
138
* Congestion control of queued data packets via CCID decision.
139
*
140
* The TX CCID performs its congestion-control by indicating whether and when a
141
* queued packet may be sent, using the return code of ccid_hc_tx_send_packet().
142
* The following modes are supported via the symbolic constants below:
143
* - timer-based pacing (CCID returns a delay value in milliseconds);
144
* - autonomous dequeueing (CCID internally schedules dccps_xmitlet).
145
*/
146
147
enum ccid_dequeueing_decision {
148
CCID_PACKET_SEND_AT_ONCE = 0x00000, /* "green light": no delay */
149
CCID_PACKET_DELAY_MAX = 0x0FFFF, /* maximum delay in msecs */
150
CCID_PACKET_DELAY = 0x10000, /* CCID msec-delay mode */
151
CCID_PACKET_WILL_DEQUEUE_LATER = 0x20000, /* CCID autonomous mode */
152
CCID_PACKET_ERR = 0xF0000, /* error condition */
153
};
154
155
static inline int ccid_packet_dequeue_eval(const int return_code)
156
{
157
if (return_code < 0)
158
return CCID_PACKET_ERR;
159
if (return_code == 0)
160
return CCID_PACKET_SEND_AT_ONCE;
161
if (return_code <= CCID_PACKET_DELAY_MAX)
162
return CCID_PACKET_DELAY;
163
return return_code;
164
}
165
166
static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
167
struct sk_buff *skb)
168
{
169
if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL)
170
return ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb);
171
return CCID_PACKET_SEND_AT_ONCE;
172
}
173
174
static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk,
175
unsigned int len)
176
{
177
if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL)
178
ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, len);
179
}
180
181
static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk,
182
struct sk_buff *skb)
183
{
184
if (ccid->ccid_ops->ccid_hc_rx_packet_recv != NULL)
185
ccid->ccid_ops->ccid_hc_rx_packet_recv(sk, skb);
186
}
187
188
static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
189
struct sk_buff *skb)
190
{
191
if (ccid->ccid_ops->ccid_hc_tx_packet_recv != NULL)
192
ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
193
}
194
195
/**
196
* ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver
197
* @pkt: type of packet that @opt appears on (RFC 4340, 5.1)
198
* @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3)
199
* @val: value of @opt
200
* @len: length of @val in bytes
201
*/
202
static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
203
u8 pkt, u8 opt, u8 *val, u8 len)
204
{
205
if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL)
206
return 0;
207
return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len);
208
}
209
210
/**
211
* ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender
212
* Arguments are analogous to ccid_hc_tx_parse_options()
213
*/
214
static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
215
u8 pkt, u8 opt, u8 *val, u8 len)
216
{
217
if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL)
218
return 0;
219
return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len);
220
}
221
222
static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
223
struct sk_buff *skb)
224
{
225
if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL)
226
return ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb);
227
return 0;
228
}
229
230
static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
231
struct tcp_info *info)
232
{
233
if (ccid->ccid_ops->ccid_hc_rx_get_info != NULL)
234
ccid->ccid_ops->ccid_hc_rx_get_info(sk, info);
235
}
236
237
static inline void ccid_hc_tx_get_info(struct ccid *ccid, struct sock *sk,
238
struct tcp_info *info)
239
{
240
if (ccid->ccid_ops->ccid_hc_tx_get_info != NULL)
241
ccid->ccid_ops->ccid_hc_tx_get_info(sk, info);
242
}
243
244
static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
245
const int optname, int len,
246
u32 __user *optval, int __user *optlen)
247
{
248
int rc = -ENOPROTOOPT;
249
if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
250
rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len,
251
optval, optlen);
252
return rc;
253
}
254
255
static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk,
256
const int optname, int len,
257
u32 __user *optval, int __user *optlen)
258
{
259
int rc = -ENOPROTOOPT;
260
if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
261
rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len,
262
optval, optlen);
263
return rc;
264
}
265
#endif /* _CCID_H */
266
267