Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ccid.h
Go to the documentation of this file.
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 
49  unsigned char ccid_id;
51  const char *ccid_name;
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);
64  struct sk_buff *skb);
66  u8 opt, u8 *val, u8 len);
68  struct sk_buff *skb);
70  struct sk_buff *skb);
72  u8 opt, u8 *val, u8 len);
74  struct sk_buff *skb);
76  unsigned int len);
78  struct tcp_info *info);
80  struct tcp_info *info);
82  const int optname, int len,
83  u32 __user *optval,
84  int __user *optlen);
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 {
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 
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)
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);
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 
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 
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 != NULL && 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 != NULL && 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 */