aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2009-01-05 00:42:53 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-05 00:42:53 -0500
commitddebc973c56b51b4e5d84d606f0430d81b895d67 (patch)
treecebe0e4461346072b2063132fc1d9cf8c3e148f1
parent6ea2fde13abd3444008ab5e9585f9ed249e6047e (diff)
dccp: Lockless integration of CCID congestion-control plugins
Based on Arnaldo's earlier patch, this patch integrates the standardised CCID congestion control plugins (CCID-2 and CCID-3) of DCCP with dccp.ko: * enables a faster connection path by eliminating the need to always go through the CCID registration lock; * updates the implementation to use only a single array whose size equals the number of configured CCIDs instead of the maximum (256); * since the CCIDs are now fixed array elements, synchronization is no longer needed, simplifying use and implementation. CCID-2 is suggested as minimum for a basic DCCP implementation (RFC 4340, 10); CCID-3 is a standards-track CCID supported by RFC 4342 and RFC 5348. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/dccp/Kconfig4
-rw-r--r--net/dccp/Makefile9
-rw-r--r--net/dccp/ackvec.h4
-rw-r--r--net/dccp/ccid.c156
-rw-r--r--net/dccp/ccid.h11
-rw-r--r--net/dccp/ccids/Kconfig70
-rw-r--r--net/dccp/ccids/Makefile8
-rw-r--r--net/dccp/ccids/ccid2.c22
-rw-r--r--net/dccp/ccids/ccid3.c23
-rw-r--r--net/dccp/dccp.h2
-rw-r--r--net/dccp/proto.c7
11 files changed, 148 insertions, 168 deletions
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index 7aa2a7acc7ec..ad6dffd9070e 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
1menuconfig IP_DCCP 1menuconfig IP_DCCP
2 tristate "The DCCP Protocol (EXPERIMENTAL)" 2 tristate "The DCCP Protocol (EXPERIMENTAL)"
3 depends on INET && EXPERIMENTAL 3 depends on INET && EXPERIMENTAL
4 select IP_DCCP_CCID2
5 ---help--- 4 ---help---
6 Datagram Congestion Control Protocol (RFC 4340) 5 Datagram Congestion Control Protocol (RFC 4340)
7 6
@@ -25,9 +24,6 @@ config INET_DCCP_DIAG
25 def_tristate y if (IP_DCCP = y && INET_DIAG = y) 24 def_tristate y if (IP_DCCP = y && INET_DIAG = y)
26 def_tristate m 25 def_tristate m
27 26
28config IP_DCCP_ACKVEC
29 bool
30
31source "net/dccp/ccids/Kconfig" 27source "net/dccp/ccids/Kconfig"
32 28
33menu "DCCP Kernel Hacking" 29menu "DCCP Kernel Hacking"
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index f4f8793aafff..5ff2e7b35690 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -2,14 +2,19 @@ obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o
2 2
3dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o 3dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
4 4
5#
6# CCID algorithms to be used by dccp.ko
7#
8# CCID-2 is default (RFC 4340, p. 77) and has Ack Vectors as dependency
9dccp-y += ccids/ccid2.o ackvec.o
10dccp-$(CONFIG_IP_DCCP_CCID3) += ccids/ccid3.o
11
5dccp_ipv4-y := ipv4.o 12dccp_ipv4-y := ipv4.o
6 13
7# build dccp_ipv6 as module whenever either IPv6 or DCCP is a module 14# build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
8obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o 15obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
9dccp_ipv6-y := ipv6.o 16dccp_ipv6-y := ipv6.o
10 17
11dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o
12
13obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o 18obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
14obj-$(CONFIG_NET_DCCPPROBE) += dccp_probe.o 19obj-$(CONFIG_NET_DCCPPROBE) += dccp_probe.o
15 20
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index 4ccee030524e..569a33a79baa 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,7 @@ struct dccp_ackvec_record {
84struct sock; 84struct sock;
85struct sk_buff; 85struct sk_buff;
86 86
87#ifdef CONFIG_IP_DCCP_ACKVEC 87#ifndef ___OLD_INTERFACE_TO_BE_REMOVED___
88extern int dccp_ackvec_init(void); 88extern int dccp_ackvec_init(void);
89extern void dccp_ackvec_exit(void); 89extern void dccp_ackvec_exit(void);
90 90
@@ -106,7 +106,7 @@ static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
106{ 106{
107 return av->av_vec_len; 107 return av->av_vec_len;
108} 108}
109#else /* CONFIG_IP_DCCP_ACKVEC */ 109#else /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
110static inline int dccp_ackvec_init(void) 110static inline int dccp_ackvec_init(void)
111{ 111{
112 return 0; 112 return 0;
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index bcc643f992ae..538d3b1da623 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,6 +13,70 @@
13 13
14#include "ccid.h" 14#include "ccid.h"
15 15
16static struct ccid_operations *ccids[] = {
17 &ccid2_ops,
18#ifdef CONFIG_IP_DCCP_CCID3
19 &ccid3_ops,
20#endif
21};
22
23static struct ccid_operations *ccid_by_number(const u8 id)
24{
25 int i;
26
27 for (i = 0; i < ARRAY_SIZE(ccids); i++)
28 if (ccids[i]->ccid_id == id)
29 return ccids[i];
30 return NULL;
31}
32
33/* check that up to @array_len members in @ccid_array are supported */
34bool ccid_support_check(u8 const *ccid_array, u8 array_len)
35{
36 while (array_len > 0)
37 if (ccid_by_number(ccid_array[--array_len]) == NULL)
38 return false;
39 return true;
40}
41
42/**
43 * ccid_get_builtin_ccids - Populate a list of built-in CCIDs
44 * @ccid_array: pointer to copy into
45 * @array_len: value to return length into
46 * This function allocates memory - caller must see that it is freed after use.
47 */
48int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
49{
50 *ccid_array = kmalloc(ARRAY_SIZE(ccids), gfp_any());
51 if (*ccid_array == NULL)
52 return -ENOBUFS;
53
54 for (*array_len = 0; *array_len < ARRAY_SIZE(ccids); *array_len += 1)
55 (*ccid_array)[*array_len] = ccids[*array_len]->ccid_id;
56 return 0;
57}
58
59int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
60 char __user *optval, int __user *optlen)
61{
62 u8 *ccid_array, array_len;
63 int err = 0;
64
65 if (len < ARRAY_SIZE(ccids))
66 return -EINVAL;
67
68 if (ccid_get_builtin_ccids(&ccid_array, &array_len))
69 return -ENOBUFS;
70
71 if (put_user(array_len, optlen) ||
72 copy_to_user(optval, ccid_array, array_len))
73 err = -EFAULT;
74
75 kfree(ccid_array);
76 return err;
77}
78
79#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
16static u8 builtin_ccids[] = { 80static u8 builtin_ccids[] = {
17 DCCPC_CCID2, /* CCID2 is supported by default */ 81 DCCPC_CCID2, /* CCID2 is supported by default */
18#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE) 82#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
@@ -62,6 +126,7 @@ static inline void ccids_read_unlock(void)
62#define ccids_read_lock() do { } while(0) 126#define ccids_read_lock() do { } while(0)
63#define ccids_read_unlock() do { } while(0) 127#define ccids_read_unlock() do { } while(0)
64#endif 128#endif
129#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
65 130
66static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...) 131static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
67{ 132{
@@ -93,6 +158,7 @@ static void ccid_kmem_cache_destroy(struct kmem_cache *slab)
93 } 158 }
94} 159}
95 160
161#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
96/* check that up to @array_len members in @ccid_array are supported */ 162/* check that up to @array_len members in @ccid_array are supported */
97bool ccid_support_check(u8 const *ccid_array, u8 array_len) 163bool ccid_support_check(u8 const *ccid_array, u8 array_len)
98{ 164{
@@ -133,8 +199,9 @@ int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
133 return -EFAULT; 199 return -EFAULT;
134 return 0; 200 return 0;
135} 201}
202#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
136 203
137int ccid_register(struct ccid_operations *ccid_ops) 204static int ccid_activate(struct ccid_operations *ccid_ops)
138{ 205{
139 int err = -ENOBUFS; 206 int err = -ENOBUFS;
140 207
@@ -152,79 +219,40 @@ int ccid_register(struct ccid_operations *ccid_ops)
152 if (ccid_ops->ccid_hc_tx_slab == NULL) 219 if (ccid_ops->ccid_hc_tx_slab == NULL)
153 goto out_free_rx_slab; 220 goto out_free_rx_slab;
154 221
155 ccids_write_lock(); 222 pr_info("CCID: Activated CCID %d (%s)\n",
156 err = -EEXIST;
157 if (ccids[ccid_ops->ccid_id] == NULL) {
158 ccids[ccid_ops->ccid_id] = ccid_ops;
159 err = 0;
160 }
161 ccids_write_unlock();
162 if (err != 0)
163 goto out_free_tx_slab;
164
165 pr_info("CCID: Registered CCID %d (%s)\n",
166 ccid_ops->ccid_id, ccid_ops->ccid_name); 223 ccid_ops->ccid_id, ccid_ops->ccid_name);
224 err = 0;
167out: 225out:
168 return err; 226 return err;
169out_free_tx_slab:
170 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
171 ccid_ops->ccid_hc_tx_slab = NULL;
172 goto out;
173out_free_rx_slab: 227out_free_rx_slab:
174 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab); 228 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
175 ccid_ops->ccid_hc_rx_slab = NULL; 229 ccid_ops->ccid_hc_rx_slab = NULL;
176 goto out; 230 goto out;
177} 231}
178 232
179EXPORT_SYMBOL_GPL(ccid_register); 233static void ccid_deactivate(struct ccid_operations *ccid_ops)
180
181int ccid_unregister(struct ccid_operations *ccid_ops)
182{ 234{
183 ccids_write_lock();
184 ccids[ccid_ops->ccid_id] = NULL;
185 ccids_write_unlock();
186
187 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab); 235 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
188 ccid_ops->ccid_hc_tx_slab = NULL; 236 ccid_ops->ccid_hc_tx_slab = NULL;
189 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab); 237 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
190 ccid_ops->ccid_hc_rx_slab = NULL; 238 ccid_ops->ccid_hc_rx_slab = NULL;
191 239
192 pr_info("CCID: Unregistered CCID %d (%s)\n", 240 pr_info("CCID: Deactivated CCID %d (%s)\n",
193 ccid_ops->ccid_id, ccid_ops->ccid_name); 241 ccid_ops->ccid_id, ccid_ops->ccid_name);
194 return 0;
195} 242}
196 243
197EXPORT_SYMBOL_GPL(ccid_unregister);
198
199struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp) 244struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
200{ 245{
201 struct ccid_operations *ccid_ops; 246 struct ccid_operations *ccid_ops = ccid_by_number(id);
202 struct ccid *ccid = NULL; 247 struct ccid *ccid = NULL;
203 248
204 ccids_read_lock();
205#ifdef CONFIG_MODULES
206 if (ccids[id] == NULL) {
207 /* We only try to load if in process context */
208 ccids_read_unlock();
209 if (gfp & GFP_ATOMIC)
210 goto out;
211 request_module("net-dccp-ccid-%d", id);
212 ccids_read_lock();
213 }
214#endif
215 ccid_ops = ccids[id];
216 if (ccid_ops == NULL) 249 if (ccid_ops == NULL)
217 goto out_unlock; 250 goto out;
218
219 if (!try_module_get(ccid_ops->ccid_owner))
220 goto out_unlock;
221
222 ccids_read_unlock();
223 251
224 ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab : 252 ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
225 ccid_ops->ccid_hc_tx_slab, gfp); 253 ccid_ops->ccid_hc_tx_slab, gfp);
226 if (ccid == NULL) 254 if (ccid == NULL)
227 goto out_module_put; 255 goto out;
228 ccid->ccid_ops = ccid_ops; 256 ccid->ccid_ops = ccid_ops;
229 if (rx) { 257 if (rx) {
230 memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size); 258 memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
@@ -239,15 +267,10 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
239 } 267 }
240out: 268out:
241 return ccid; 269 return ccid;
242out_unlock:
243 ccids_read_unlock();
244 goto out;
245out_free_ccid: 270out_free_ccid:
246 kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab : 271 kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
247 ccid_ops->ccid_hc_tx_slab, ccid); 272 ccid_ops->ccid_hc_tx_slab, ccid);
248 ccid = NULL; 273 ccid = NULL;
249out_module_put:
250 module_put(ccid_ops->ccid_owner);
251 goto out; 274 goto out;
252} 275}
253 276
@@ -270,10 +293,6 @@ static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
270 ccid_ops->ccid_hc_tx_exit(sk); 293 ccid_ops->ccid_hc_tx_exit(sk);
271 kmem_cache_free(ccid_ops->ccid_hc_tx_slab, ccid); 294 kmem_cache_free(ccid_ops->ccid_hc_tx_slab, ccid);
272 } 295 }
273 ccids_read_lock();
274 if (ccids[ccid_ops->ccid_id] != NULL)
275 module_put(ccid_ops->ccid_owner);
276 ccids_read_unlock();
277} 296}
278 297
279void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk) 298void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
@@ -289,3 +308,28 @@ void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk)
289} 308}
290 309
291EXPORT_SYMBOL_GPL(ccid_hc_tx_delete); 310EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
311
312int __init ccid_initialize_builtins(void)
313{
314 int i, err;
315
316 for (i = 0; i < ARRAY_SIZE(ccids); i++) {
317 err = ccid_activate(ccids[i]);
318 if (err)
319 goto unwind_registrations;
320 }
321 return 0;
322
323unwind_registrations:
324 while(--i >= 0)
325 ccid_deactivate(ccids[i]);
326 return err;
327}
328
329void ccid_cleanup_builtins(void)
330{
331 int i;
332
333 for (i = 0; i < ARRAY_SIZE(ccids); i++)
334 ccid_deactivate(ccids[i]);
335}
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 18f69423a708..75c21c52ed7a 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -29,7 +29,6 @@ struct tcp_info;
29 * @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.) 29 * @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
30 * @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled) 30 * @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
31 * @ccid_name: alphabetical identifier string for @ccid_id 31 * @ccid_name: alphabetical identifier string for @ccid_id
32 * @ccid_owner: module which implements/owns this CCID
33 * @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection 32 * @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
34 * @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket 33 * @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
35 * 34 *
@@ -48,7 +47,6 @@ struct ccid_operations {
48 unsigned char ccid_id; 47 unsigned char ccid_id;
49 __u32 ccid_ccmps; 48 __u32 ccid_ccmps;
50 const char *ccid_name; 49 const char *ccid_name;
51 struct module *ccid_owner;
52 struct kmem_cache *ccid_hc_rx_slab, 50 struct kmem_cache *ccid_hc_rx_slab,
53 *ccid_hc_tx_slab; 51 *ccid_hc_tx_slab;
54 __u32 ccid_hc_rx_obj_size, 52 __u32 ccid_hc_rx_obj_size,
@@ -90,8 +88,13 @@ struct ccid_operations {
90 int __user *optlen); 88 int __user *optlen);
91}; 89};
92 90
93extern int ccid_register(struct ccid_operations *ccid_ops); 91extern struct ccid_operations ccid2_ops;
94extern int ccid_unregister(struct ccid_operations *ccid_ops); 92#ifdef CONFIG_IP_DCCP_CCID3
93extern struct ccid_operations ccid3_ops;
94#endif
95
96extern int ccid_initialize_builtins(void);
97extern void ccid_cleanup_builtins(void);
95 98
96struct ccid { 99struct ccid {
97 struct ccid_operations *ccid_ops; 100 struct ccid_operations *ccid_ops;
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 12275943eab8..b30f049cf1d3 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,80 +1,52 @@
1menu "DCCP CCIDs Configuration (EXPERIMENTAL)" 1menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
2 depends on EXPERIMENTAL 2 depends on EXPERIMENTAL
3 3
4config IP_DCCP_CCID2
5 tristate "CCID2 (TCP-Like) (EXPERIMENTAL)"
6 def_tristate IP_DCCP
7 select IP_DCCP_ACKVEC
8 ---help---
9 CCID 2, TCP-like Congestion Control, denotes Additive Increase,
10 Multiplicative Decrease (AIMD) congestion control with behavior
11 modelled directly on TCP, including congestion window, slow start,
12 timeouts, and so forth [RFC 2581]. CCID 2 achieves maximum
13 bandwidth over the long term, consistent with the use of end-to-end
14 congestion control, but halves its congestion window in response to
15 each congestion event. This leads to the abrupt rate changes
16 typical of TCP. Applications should use CCID 2 if they prefer
17 maximum bandwidth utilization to steadiness of rate. This is often
18 the case for applications that are not playing their data directly
19 to the user. For example, a hypothetical application that
20 transferred files over DCCP, using application-level retransmissions
21 for lost packets, would prefer CCID 2 to CCID 3. On-line games may
22 also prefer CCID 2. See RFC 4341 for further details.
23
24 CCID2 is the default CCID used by DCCP.
25
26config IP_DCCP_CCID2_DEBUG 4config IP_DCCP_CCID2_DEBUG
27 bool "CCID2 debugging messages" 5 bool "CCID-2 debugging messages"
28 depends on IP_DCCP_CCID2 6 ---help---
29 ---help--- 7 Enable CCID-2 specific debugging messages.
30 Enable CCID2-specific debugging messages.
31 8
32 When compiling CCID2 as a module, this debugging output can 9 The debugging output can additionally be toggled by setting the
33 additionally be toggled by setting the ccid2_debug module 10 ccid2_debug parameter to 0 or 1.
34 parameter to 0 or 1.
35 11
36 If in doubt, say N. 12 If in doubt, say N.
37 13
38config IP_DCCP_CCID3 14config IP_DCCP_CCID3
39 tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)" 15 bool "CCID-3 (TCP-Friendly) (EXPERIMENTAL)"
40 def_tristate IP_DCCP 16 def_bool y if (IP_DCCP = y || IP_DCCP = m)
41 select IP_DCCP_TFRC_LIB 17 select IP_DCCP_TFRC_LIB
42 ---help--- 18 ---help---
43 CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based 19 CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
44 rate-controlled congestion control mechanism. TFRC is designed to 20 rate-controlled congestion control mechanism. TFRC is designed to
45 be reasonably fair when competing for bandwidth with TCP-like flows, 21 be reasonably fair when competing for bandwidth with TCP-like flows,
46 where a flow is "reasonably fair" if its sending rate is generally 22 where a flow is "reasonably fair" if its sending rate is generally
47 within a factor of two of the sending rate of a TCP flow under the 23 within a factor of two of the sending rate of a TCP flow under the
48 same conditions. However, TFRC has a much lower variation of 24 same conditions. However, TFRC has a much lower variation of
49 throughput over time compared with TCP, which makes CCID 3 more 25 throughput over time compared with TCP, which makes CCID-3 more
50 suitable than CCID 2 for applications such streaming media where a 26 suitable than CCID-2 for applications such streaming media where a
51 relatively smooth sending rate is of importance. 27 relatively smooth sending rate is of importance.
52 28
53 CCID 3 is further described in RFC 4342, 29 CCID-3 is further described in RFC 4342,
54 http://www.ietf.org/rfc/rfc4342.txt 30 http://www.ietf.org/rfc/rfc4342.txt
55 31
56 The TFRC congestion control algorithms were initially described in 32 The TFRC congestion control algorithms were initially described in
57 RFC 3448. 33 RFC 5448.
58 34
59 This text was extracted from RFC 4340 (sec. 10.2), 35 This text was extracted from RFC 4340 (sec. 10.2),
60 http://www.ietf.org/rfc/rfc4340.txt 36 http://www.ietf.org/rfc/rfc4340.txt
61
62 To compile this CCID as a module, choose M here: the module will be
63 called dccp_ccid3.
64 37
65 If in doubt, say M. 38 If in doubt, say N.
66 39
67config IP_DCCP_CCID3_DEBUG 40config IP_DCCP_CCID3_DEBUG
68 bool "CCID3 debugging messages" 41 bool "CCID-3 debugging messages"
69 depends on IP_DCCP_CCID3 42 depends on IP_DCCP_CCID3
70 ---help--- 43 ---help---
71 Enable CCID3-specific debugging messages. 44 Enable CCID-3 specific debugging messages.
72 45
73 When compiling CCID3 as a module, this debugging output can 46 The debugging output can additionally be toggled by setting the
74 additionally be toggled by setting the ccid3_debug module 47 ccid3_debug parameter to 0 or 1.
75 parameter to 0 or 1.
76 48
77 If in doubt, say N. 49 If in doubt, say N.
78 50
79config IP_DCCP_CCID3_RTO 51config IP_DCCP_CCID3_RTO
80 int "Use higher bound for nofeedback timer" 52 int "Use higher bound for nofeedback timer"
diff --git a/net/dccp/ccids/Makefile b/net/dccp/ccids/Makefile
index 438f20bccff7..cdaefffbb777 100644
--- a/net/dccp/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1 @@
1obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
2
3dccp_ccid3-y := ccid3.o
4
5obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
6
7dccp_ccid2-y := ccid2.o
8
9obj-y += lib/ obj-y += lib/
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index c9ea19a4d85e..d235294ace23 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -768,10 +768,9 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
768 } 768 }
769} 769}
770 770
771static struct ccid_operations ccid2 = { 771struct ccid_operations ccid2_ops = {
772 .ccid_id = DCCPC_CCID2, 772 .ccid_id = DCCPC_CCID2,
773 .ccid_name = "TCP-like", 773 .ccid_name = "TCP-like",
774 .ccid_owner = THIS_MODULE,
775 .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock), 774 .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
776 .ccid_hc_tx_init = ccid2_hc_tx_init, 775 .ccid_hc_tx_init = ccid2_hc_tx_init,
777 .ccid_hc_tx_exit = ccid2_hc_tx_exit, 776 .ccid_hc_tx_exit = ccid2_hc_tx_exit,
@@ -784,22 +783,5 @@ static struct ccid_operations ccid2 = {
784 783
785#ifdef CONFIG_IP_DCCP_CCID2_DEBUG 784#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
786module_param(ccid2_debug, bool, 0644); 785module_param(ccid2_debug, bool, 0644);
787MODULE_PARM_DESC(ccid2_debug, "Enable debug messages"); 786MODULE_PARM_DESC(ccid2_debug, "Enable CCID-2 debug messages");
788#endif 787#endif
789
790static __init int ccid2_module_init(void)
791{
792 return ccid_register(&ccid2);
793}
794module_init(ccid2_module_init);
795
796static __exit void ccid2_module_exit(void)
797{
798 ccid_unregister(&ccid2);
799}
800module_exit(ccid2_module_exit);
801
802MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
803MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
804MODULE_LICENSE("GPL");
805MODULE_ALIAS("net-dccp-ccid-2");
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 3b8bd7ca6761..a27b7f4c19c5 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -940,10 +940,9 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
940 return 0; 940 return 0;
941} 941}
942 942
943static struct ccid_operations ccid3 = { 943struct ccid_operations ccid3_ops = {
944 .ccid_id = DCCPC_CCID3, 944 .ccid_id = DCCPC_CCID3,
945 .ccid_name = "TCP-Friendly Rate Control", 945 .ccid_name = "TCP-Friendly Rate Control",
946 .ccid_owner = THIS_MODULE,
947 .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock), 946 .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock),
948 .ccid_hc_tx_init = ccid3_hc_tx_init, 947 .ccid_hc_tx_init = ccid3_hc_tx_init,
949 .ccid_hc_tx_exit = ccid3_hc_tx_exit, 948 .ccid_hc_tx_exit = ccid3_hc_tx_exit,
@@ -964,23 +963,5 @@ static struct ccid_operations ccid3 = {
964 963
965#ifdef CONFIG_IP_DCCP_CCID3_DEBUG 964#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
966module_param(ccid3_debug, bool, 0644); 965module_param(ccid3_debug, bool, 0644);
967MODULE_PARM_DESC(ccid3_debug, "Enable debug messages"); 966MODULE_PARM_DESC(ccid3_debug, "Enable CCID-3 debug messages");
968#endif 967#endif
969
970static __init int ccid3_module_init(void)
971{
972 return ccid_register(&ccid3);
973}
974module_init(ccid3_module_init);
975
976static __exit void ccid3_module_exit(void)
977{
978 ccid_unregister(&ccid3);
979}
980module_exit(ccid3_module_exit);
981
982MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
983 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
984MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
985MODULE_LICENSE("GPL");
986MODULE_ALIAS("net-dccp-ccid-3");
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 0bc4c9a02e19..f2230fc168e1 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -432,10 +432,8 @@ static inline int dccp_ack_pending(const struct sock *sk)
432{ 432{
433 const struct dccp_sock *dp = dccp_sk(sk); 433 const struct dccp_sock *dp = dccp_sk(sk);
434 return dp->dccps_timestamp_echo != 0 || 434 return dp->dccps_timestamp_echo != 0 ||
435#ifdef CONFIG_IP_DCCP_ACKVEC
436 (dp->dccps_hc_rx_ackvec != NULL && 435 (dp->dccps_hc_rx_ackvec != NULL &&
437 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || 436 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
438#endif
439 inet_csk_ack_scheduled(sk); 437 inet_csk_ack_scheduled(sk);
440} 438}
441 439
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 1747ccae8e8d..945b4d5d23b3 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1118,9 +1118,15 @@ static int __init dccp_init(void)
1118 if (rc) 1118 if (rc)
1119 goto out_ackvec_exit; 1119 goto out_ackvec_exit;
1120 1120
1121 rc = ccid_initialize_builtins();
1122 if (rc)
1123 goto out_sysctl_exit;
1124
1121 dccp_timestamping_init(); 1125 dccp_timestamping_init();
1122out: 1126out:
1123 return rc; 1127 return rc;
1128out_sysctl_exit:
1129 dccp_sysctl_exit();
1124out_ackvec_exit: 1130out_ackvec_exit:
1125 dccp_ackvec_exit(); 1131 dccp_ackvec_exit();
1126out_free_dccp_mib: 1132out_free_dccp_mib:
@@ -1143,6 +1149,7 @@ out_free_percpu:
1143 1149
1144static void __exit dccp_fini(void) 1150static void __exit dccp_fini(void)
1145{ 1151{
1152 ccid_cleanup_builtins();
1146 dccp_mib_exit(); 1153 dccp_mib_exit();
1147 free_pages((unsigned long)dccp_hashinfo.bhash, 1154 free_pages((unsigned long)dccp_hashinfo.bhash,
1148 get_order(dccp_hashinfo.bhash_size * 1155 get_order(dccp_hashinfo.bhash_size *