aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2006-03-20 22:21:44 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 22:21:44 -0500
commit91f0ebf7b6d5cb2b6e818d48587566144821babe (patch)
tree505c66f36bd72014d7eacb7a04ea011bae2e9a3a
parentf38c39d6ce8226519455a6dfe91c2ad84f363f6f (diff)
[DCCP] CCID: Improve CCID infrastructure
1. No need for ->ccid_init nor ->ccid_exit, this is what module_{init,exit} does and anynways neither ccid2 nor ccid3 were using it. 2. Rename struct ccid to struct ccid_operations and introduce struct ccid with a pointer to ccid_operations and rigth after it the rx or tx private state. 3. Remove the pointer to the state of the half connections from struct dccp_sock, now its derived thru ccid_priv() from the ccid pointer. Now we also can implement the setsockopt for changing the CCID easily as no ccid init routines can affect struct dccp_sock in any way that prevents other CCIDs from working if a CCID switch operation is asked by apps. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/dccp.h2
-rw-r--r--net/dccp/ccid.c188
-rw-r--r--net/dccp/ccid.h115
-rw-r--r--net/dccp/ccids/ccid2.c55
-rw-r--r--net/dccp/ccids/ccid2.h16
-rw-r--r--net/dccp/ccids/ccid3.c34
-rw-r--r--net/dccp/ccids/ccid3.h5
-rw-r--r--net/dccp/input.c8
-rw-r--r--net/dccp/ipv4.c24
-rw-r--r--net/dccp/minisocks.c25
10 files changed, 260 insertions, 212 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index a70d1a27e7fc..bdd756cc60b1 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -478,8 +478,6 @@ struct dccp_sock {
478 __u32 dccps_mss_cache; 478 __u32 dccps_mss_cache;
479 struct dccp_options dccps_options; 479 struct dccp_options dccps_options;
480 struct dccp_ackvec *dccps_hc_rx_ackvec; 480 struct dccp_ackvec *dccps_hc_rx_ackvec;
481 void *dccps_hc_rx_ccid_private;
482 void *dccps_hc_tx_ccid_private;
483 struct ccid *dccps_hc_rx_ccid; 481 struct ccid *dccps_hc_rx_ccid;
484 struct ccid *dccps_hc_tx_ccid; 482 struct ccid *dccps_hc_tx_ccid;
485 struct dccp_options_received dccps_options_received; 483 struct dccp_options_received dccps_options_received;
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index 06b191a5740b..ff05e59043cd 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,7 +13,7 @@
13 13
14#include "ccid.h" 14#include "ccid.h"
15 15
16static struct ccid *ccids[CCID_MAX]; 16static struct ccid_operations *ccids[CCID_MAX];
17#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) 17#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
18static atomic_t ccids_lockct = ATOMIC_INIT(0); 18static atomic_t ccids_lockct = ATOMIC_INIT(0);
19static DEFINE_SPINLOCK(ccids_lock); 19static DEFINE_SPINLOCK(ccids_lock);
@@ -55,82 +55,202 @@ static inline void ccids_read_unlock(void)
55#define ccids_read_unlock() do { } while(0) 55#define ccids_read_unlock() do { } while(0)
56#endif 56#endif
57 57
58int ccid_register(struct ccid *ccid) 58static kmem_cache_t *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
59{ 59{
60 int err; 60 kmem_cache_t *slab;
61 char slab_name_fmt[32], *slab_name;
62 va_list args;
63
64 va_start(args, fmt);
65 vsnprintf(slab_name_fmt, sizeof(slab_name_fmt), fmt, args);
66 va_end(args);
67
68 slab_name = kstrdup(slab_name_fmt, GFP_KERNEL);
69 if (slab_name == NULL)
70 return NULL;
71 slab = kmem_cache_create(slab_name, sizeof(struct ccid) + obj_size, 0,
72 SLAB_HWCACHE_ALIGN, NULL, NULL);
73 if (slab == NULL)
74 kfree(slab_name);
75 return slab;
76}
77
78static void ccid_kmem_cache_destroy(kmem_cache_t *slab)
79{
80 if (slab != NULL) {
81 const char *name = kmem_cache_name(slab);
82
83 kmem_cache_destroy(slab);
84 kfree(name);
85 }
86}
87
88int ccid_register(struct ccid_operations *ccid_ops)
89{
90 int err = -ENOBUFS;
91
92 ccid_ops->ccid_hc_rx_slab =
93 ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
94 "%s_hc_rx_sock",
95 ccid_ops->ccid_name);
96 if (ccid_ops->ccid_hc_rx_slab == NULL)
97 goto out;
98
99 ccid_ops->ccid_hc_tx_slab =
100 ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
101 "%s_hc_tx_sock",
102 ccid_ops->ccid_name);
103 if (ccid_ops->ccid_hc_tx_slab == NULL)
104 goto out_free_rx_slab;
61 105
62 ccids_write_lock(); 106 ccids_write_lock();
63 err = -EEXIST; 107 err = -EEXIST;
64 if (ccids[ccid->ccid_id] == NULL) { 108 if (ccids[ccid_ops->ccid_id] == NULL) {
65 ccids[ccid->ccid_id] = ccid; 109 ccids[ccid_ops->ccid_id] = ccid_ops;
66 err = 0; 110 err = 0;
67 } 111 }
68 ccids_write_unlock(); 112 ccids_write_unlock();
69 if (err == 0) 113 if (err != 0)
70 pr_info("CCID: Registered CCID %d (%s)\n", 114 goto out_free_tx_slab;
71 ccid->ccid_id, ccid->ccid_name); 115
116 pr_info("CCID: Registered CCID %d (%s)\n",
117 ccid_ops->ccid_id, ccid_ops->ccid_name);
118out:
72 return err; 119 return err;
120out_free_tx_slab:
121 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
122 ccid_ops->ccid_hc_tx_slab = NULL;
123 goto out;
124out_free_rx_slab:
125 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
126 ccid_ops->ccid_hc_rx_slab = NULL;
127 goto out;
73} 128}
74 129
75EXPORT_SYMBOL_GPL(ccid_register); 130EXPORT_SYMBOL_GPL(ccid_register);
76 131
77int ccid_unregister(struct ccid *ccid) 132int ccid_unregister(struct ccid_operations *ccid_ops)
78{ 133{
79 ccids_write_lock(); 134 ccids_write_lock();
80 ccids[ccid->ccid_id] = NULL; 135 ccids[ccid_ops->ccid_id] = NULL;
81 ccids_write_unlock(); 136 ccids_write_unlock();
137
138 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
139 ccid_ops->ccid_hc_tx_slab = NULL;
140 ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
141 ccid_ops->ccid_hc_rx_slab = NULL;
142
82 pr_info("CCID: Unregistered CCID %d (%s)\n", 143 pr_info("CCID: Unregistered CCID %d (%s)\n",
83 ccid->ccid_id, ccid->ccid_name); 144 ccid_ops->ccid_id, ccid_ops->ccid_name);
84 return 0; 145 return 0;
85} 146}
86 147
87EXPORT_SYMBOL_GPL(ccid_unregister); 148EXPORT_SYMBOL_GPL(ccid_unregister);
88 149
89struct ccid *ccid_init(unsigned char id, struct sock *sk) 150struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
90{ 151{
91 struct ccid *ccid; 152 struct ccid_operations *ccid_ops;
153 struct ccid *ccid = NULL;
92 154
155 ccids_read_lock();
93#ifdef CONFIG_KMOD 156#ifdef CONFIG_KMOD
94 if (ccids[id] == NULL) 157 if (ccids[id] == NULL) {
158 /* We only try to load if in process context */
159 ccids_read_unlock();
160 if (gfp & GFP_ATOMIC)
161 goto out;
95 request_module("net-dccp-ccid-%d", id); 162 request_module("net-dccp-ccid-%d", id);
163 ccids_read_lock();
164 }
96#endif 165#endif
97 ccids_read_lock(); 166 ccid_ops = ccids[id];
167 if (ccid_ops == NULL)
168 goto out_unlock;
98 169
99 ccid = ccids[id]; 170 if (!try_module_get(ccid_ops->ccid_owner))
100 if (ccid == NULL) 171 goto out_unlock;
101 goto out;
102 172
103 if (!try_module_get(ccid->ccid_owner)) 173 ccids_read_unlock();
104 goto out_err;
105 174
106 if (ccid->ccid_init != NULL && ccid->ccid_init(sk) != 0) 175 ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
176 ccid_ops->ccid_hc_tx_slab, gfp);
177 if (ccid == NULL)
107 goto out_module_put; 178 goto out_module_put;
179 ccid->ccid_ops = ccid_ops;
180 if (rx) {
181 memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
182 if (ccid->ccid_ops->ccid_hc_rx_init != NULL &&
183 ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0)
184 goto out_free_ccid;
185 } else {
186 memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size);
187 if (ccid->ccid_ops->ccid_hc_tx_init != NULL &&
188 ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
189 goto out_free_ccid;
190 }
108out: 191out:
109 ccids_read_unlock();
110 return ccid; 192 return ccid;
111out_module_put: 193out_unlock:
112 module_put(ccid->ccid_owner); 194 ccids_read_unlock();
113out_err: 195 goto out;
196out_free_ccid:
197 kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
198 ccid_ops->ccid_hc_tx_slab, ccid);
114 ccid = NULL; 199 ccid = NULL;
200out_module_put:
201 module_put(ccid_ops->ccid_owner);
115 goto out; 202 goto out;
116} 203}
117 204
118EXPORT_SYMBOL_GPL(ccid_init); 205EXPORT_SYMBOL_GPL(ccid_new);
119 206
120void ccid_exit(struct ccid *ccid, struct sock *sk) 207struct ccid *ccid_hc_rx_new(unsigned char id, struct sock *sk, gfp_t gfp)
121{ 208{
209 return ccid_new(id, sk, 1, gfp);
210}
211
212EXPORT_SYMBOL_GPL(ccid_hc_rx_new);
213
214struct ccid *ccid_hc_tx_new(unsigned char id,struct sock *sk, gfp_t gfp)
215{
216 return ccid_new(id, sk, 0, gfp);
217}
218
219EXPORT_SYMBOL_GPL(ccid_hc_tx_new);
220
221static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
222{
223 struct ccid_operations *ccid_ops;
224
122 if (ccid == NULL) 225 if (ccid == NULL)
123 return; 226 return;
124 227
228 ccid_ops = ccid->ccid_ops;
229 if (rx) {
230 if (ccid_ops->ccid_hc_rx_exit != NULL)
231 ccid_ops->ccid_hc_rx_exit(sk);
232 kmem_cache_free(ccid_ops->ccid_hc_rx_slab, ccid);
233 } else {
234 if (ccid_ops->ccid_hc_tx_exit != NULL)
235 ccid_ops->ccid_hc_tx_exit(sk);
236 kmem_cache_free(ccid_ops->ccid_hc_tx_slab, ccid);
237 }
125 ccids_read_lock(); 238 ccids_read_lock();
239 if (ccids[ccid_ops->ccid_id] != NULL)
240 module_put(ccid_ops->ccid_owner);
241 ccids_read_unlock();
242}
126 243
127 if (ccids[ccid->ccid_id] != NULL) { 244void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
128 if (ccid->ccid_exit != NULL) 245{
129 ccid->ccid_exit(sk); 246 ccid_delete(ccid, sk, 1);
130 module_put(ccid->ccid_owner); 247}
131 }
132 248
133 ccids_read_unlock(); 249EXPORT_SYMBOL_GPL(ccid_hc_rx_delete);
250
251void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk)
252{
253 ccid_delete(ccid, sk, 0);
134} 254}
135 255
136EXPORT_SYMBOL_GPL(ccid_exit); 256EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index de681c6ad081..3dec50d49731 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -23,14 +23,16 @@
23 23
24struct tcp_info; 24struct tcp_info;
25 25
26struct ccid { 26struct ccid_operations {
27 unsigned char ccid_id; 27 unsigned char ccid_id;
28 const char *ccid_name; 28 const char *ccid_name;
29 struct module *ccid_owner; 29 struct module *ccid_owner;
30 int (*ccid_init)(struct sock *sk); 30 kmem_cache_t *ccid_hc_rx_slab;
31 void (*ccid_exit)(struct sock *sk); 31 __u32 ccid_hc_rx_obj_size;
32 int (*ccid_hc_rx_init)(struct sock *sk); 32 kmem_cache_t *ccid_hc_tx_slab;
33 int (*ccid_hc_tx_init)(struct sock *sk); 33 __u32 ccid_hc_tx_obj_size;
34 int (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk);
35 int (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk);
34 void (*ccid_hc_rx_exit)(struct sock *sk); 36 void (*ccid_hc_rx_exit)(struct sock *sk);
35 void (*ccid_hc_tx_exit)(struct sock *sk); 37 void (*ccid_hc_tx_exit)(struct sock *sk);
36 void (*ccid_hc_rx_packet_recv)(struct sock *sk, 38 void (*ccid_hc_rx_packet_recv)(struct sock *sk,
@@ -67,75 +69,58 @@ struct ccid {
67 int __user *optlen); 69 int __user *optlen);
68}; 70};
69 71
70extern int ccid_register(struct ccid *ccid); 72extern int ccid_register(struct ccid_operations *ccid_ops);
71extern int ccid_unregister(struct ccid *ccid); 73extern int ccid_unregister(struct ccid_operations *ccid_ops);
72 74
73extern struct ccid *ccid_init(unsigned char id, struct sock *sk); 75struct ccid {
74extern void ccid_exit(struct ccid *ccid, struct sock *sk); 76 struct ccid_operations *ccid_ops;
77 char ccid_priv[0];
78};
75 79
76static inline void __ccid_get(struct ccid *ccid) 80static inline void *ccid_priv(const struct ccid *ccid)
77{ 81{
78 __module_get(ccid->ccid_owner); 82 return (void *)ccid->ccid_priv;
79} 83}
80 84
85extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
86 gfp_t gfp);
87
88extern struct ccid *ccid_hc_rx_new(unsigned char id, struct sock *sk,
89 gfp_t gfp);
90extern struct ccid *ccid_hc_tx_new(unsigned char id, struct sock *sk,
91 gfp_t gfp);
92
93extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk);
94extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk);
95
81static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, 96static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
82 struct sk_buff *skb, int len) 97 struct sk_buff *skb, int len)
83{ 98{
84 int rc = 0; 99 int rc = 0;
85 if (ccid->ccid_hc_tx_send_packet != NULL) 100 if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL)
86 rc = ccid->ccid_hc_tx_send_packet(sk, skb, len); 101 rc = ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb, len);
87 return rc; 102 return rc;
88} 103}
89 104
90static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, 105static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk,
91 int more, int len) 106 int more, int len)
92{ 107{
93 if (ccid->ccid_hc_tx_packet_sent != NULL) 108 if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL)
94 ccid->ccid_hc_tx_packet_sent(sk, more, len); 109 ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len);
95}
96
97static inline int ccid_hc_rx_init(struct ccid *ccid, struct sock *sk)
98{
99 int rc = 0;
100 if (ccid->ccid_hc_rx_init != NULL)
101 rc = ccid->ccid_hc_rx_init(sk);
102 return rc;
103}
104
105static inline int ccid_hc_tx_init(struct ccid *ccid, struct sock *sk)
106{
107 int rc = 0;
108 if (ccid->ccid_hc_tx_init != NULL)
109 rc = ccid->ccid_hc_tx_init(sk);
110 return rc;
111}
112
113static inline void ccid_hc_rx_exit(struct ccid *ccid, struct sock *sk)
114{
115 if (ccid != NULL && ccid->ccid_hc_rx_exit != NULL &&
116 dccp_sk(sk)->dccps_hc_rx_ccid_private != NULL)
117 ccid->ccid_hc_rx_exit(sk);
118}
119
120static inline void ccid_hc_tx_exit(struct ccid *ccid, struct sock *sk)
121{
122 if (ccid != NULL && ccid->ccid_hc_tx_exit != NULL &&
123 dccp_sk(sk)->dccps_hc_tx_ccid_private != NULL)
124 ccid->ccid_hc_tx_exit(sk);
125} 110}
126 111
127static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk, 112static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk,
128 struct sk_buff *skb) 113 struct sk_buff *skb)
129{ 114{
130 if (ccid->ccid_hc_rx_packet_recv != NULL) 115 if (ccid->ccid_ops->ccid_hc_rx_packet_recv != NULL)
131 ccid->ccid_hc_rx_packet_recv(sk, skb); 116 ccid->ccid_ops->ccid_hc_rx_packet_recv(sk, skb);
132} 117}
133 118
134static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk, 119static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
135 struct sk_buff *skb) 120 struct sk_buff *skb)
136{ 121{
137 if (ccid->ccid_hc_tx_packet_recv != NULL) 122 if (ccid->ccid_ops->ccid_hc_tx_packet_recv != NULL)
138 ccid->ccid_hc_tx_packet_recv(sk, skb); 123 ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
139} 124}
140 125
141static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, 126static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
@@ -144,8 +129,8 @@ static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
144 unsigned char* value) 129 unsigned char* value)
145{ 130{
146 int rc = 0; 131 int rc = 0;
147 if (ccid->ccid_hc_tx_parse_options != NULL) 132 if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL)
148 rc = ccid->ccid_hc_tx_parse_options(sk, option, len, idx, 133 rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx,
149 value); 134 value);
150 return rc; 135 return rc;
151} 136}
@@ -156,37 +141,37 @@ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
156 unsigned char* value) 141 unsigned char* value)
157{ 142{
158 int rc = 0; 143 int rc = 0;
159 if (ccid->ccid_hc_rx_parse_options != NULL) 144 if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL)
160 rc = ccid->ccid_hc_rx_parse_options(sk, option, len, idx, value); 145 rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value);
161 return rc; 146 return rc;
162} 147}
163 148
164static inline void ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk, 149static inline void ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk,
165 struct sk_buff *skb) 150 struct sk_buff *skb)
166{ 151{
167 if (ccid->ccid_hc_tx_insert_options != NULL) 152 if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL)
168 ccid->ccid_hc_tx_insert_options(sk, skb); 153 ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb);
169} 154}
170 155
171static inline void ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, 156static inline void ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
172 struct sk_buff *skb) 157 struct sk_buff *skb)
173{ 158{
174 if (ccid->ccid_hc_rx_insert_options != NULL) 159 if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL)
175 ccid->ccid_hc_rx_insert_options(sk, skb); 160 ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb);
176} 161}
177 162
178static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk, 163static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
179 struct tcp_info *info) 164 struct tcp_info *info)
180{ 165{
181 if (ccid->ccid_hc_rx_get_info != NULL) 166 if (ccid->ccid_ops->ccid_hc_rx_get_info != NULL)
182 ccid->ccid_hc_rx_get_info(sk, info); 167 ccid->ccid_ops->ccid_hc_rx_get_info(sk, info);
183} 168}
184 169
185static inline void ccid_hc_tx_get_info(struct ccid *ccid, struct sock *sk, 170static inline void ccid_hc_tx_get_info(struct ccid *ccid, struct sock *sk,
186 struct tcp_info *info) 171 struct tcp_info *info)
187{ 172{
188 if (ccid->ccid_hc_tx_get_info != NULL) 173 if (ccid->ccid_ops->ccid_hc_tx_get_info != NULL)
189 ccid->ccid_hc_tx_get_info(sk, info); 174 ccid->ccid_ops->ccid_hc_tx_get_info(sk, info);
190} 175}
191 176
192static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk, 177static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
@@ -194,8 +179,8 @@ static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
194 u32 __user *optval, int __user *optlen) 179 u32 __user *optval, int __user *optlen)
195{ 180{
196 int rc = -ENOPROTOOPT; 181 int rc = -ENOPROTOOPT;
197 if (ccid->ccid_hc_rx_getsockopt != NULL) 182 if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
198 rc = ccid->ccid_hc_rx_getsockopt(sk, optname, len, 183 rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len,
199 optval, optlen); 184 optval, optlen);
200 return rc; 185 return rc;
201} 186}
@@ -205,8 +190,8 @@ static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk,
205 u32 __user *optval, int __user *optlen) 190 u32 __user *optval, int __user *optlen)
206{ 191{
207 int rc = -ENOPROTOOPT; 192 int rc = -ENOPROTOOPT;
208 if (ccid->ccid_hc_tx_getsockopt != NULL) 193 if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
209 rc = ccid->ccid_hc_tx_getsockopt(sk, optname, len, 194 rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len,
210 optval, optlen); 195 optval, optlen);
211 return rc; 196 return rc;
212} 197}
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 3328d23c4be7..b40c4569a820 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -52,16 +52,6 @@ static int ccid2_debug;
52 52
53static const int ccid2_seq_len = 128; 53static const int ccid2_seq_len = 128;
54 54
55static inline struct ccid2_hc_tx_sock *ccid2_hc_tx_sk(const struct sock *sk)
56{
57 return dccp_sk(sk)->dccps_hc_tx_ccid_private;
58}
59
60static inline struct ccid2_hc_rx_sock *ccid2_hc_rx_sk(const struct sock *sk)
61{
62 return dccp_sk(sk)->dccps_hc_rx_ccid_private;
63}
64
65#ifdef CCID2_DEBUG 55#ifdef CCID2_DEBUG
66static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) 56static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
67{ 57{
@@ -707,19 +697,12 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
707 ccid2_hc_tx_check_sanity(hctx); 697 ccid2_hc_tx_check_sanity(hctx);
708} 698}
709 699
710static int ccid2_hc_tx_init(struct sock *sk) 700static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
711{ 701{
712 struct dccp_sock *dp = dccp_sk(sk); 702 struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
713 struct ccid2_hc_tx_sock *hctx;
714 int seqcount = ccid2_seq_len; 703 int seqcount = ccid2_seq_len;
715 int i; 704 int i;
716 705
717 dp->dccps_hc_tx_ccid_private = kzalloc(sizeof(*hctx), gfp_any());
718 if (dp->dccps_hc_tx_ccid_private == NULL)
719 return -ENOMEM;
720
721 hctx = ccid2_hc_tx_sk(sk);
722
723 /* XXX init variables with proper values */ 706 /* XXX init variables with proper values */
724 hctx->ccid2hctx_cwnd = 1; 707 hctx->ccid2hctx_cwnd = 1;
725 hctx->ccid2hctx_ssthresh = 10; 708 hctx->ccid2hctx_ssthresh = 10;
@@ -728,11 +711,9 @@ static int ccid2_hc_tx_init(struct sock *sk)
728 /* XXX init ~ to window size... */ 711 /* XXX init ~ to window size... */
729 hctx->ccid2hctx_seqbuf = kmalloc(sizeof(*hctx->ccid2hctx_seqbuf) * 712 hctx->ccid2hctx_seqbuf = kmalloc(sizeof(*hctx->ccid2hctx_seqbuf) *
730 seqcount, gfp_any()); 713 seqcount, gfp_any());
731 if (hctx->ccid2hctx_seqbuf == NULL) { 714 if (hctx->ccid2hctx_seqbuf == NULL)
732 kfree(dp->dccps_hc_tx_ccid_private);
733 dp->dccps_hc_tx_ccid_private = NULL;
734 return -ENOMEM; 715 return -ENOMEM;
735 } 716
736 for (i = 0; i < (seqcount - 1); i++) { 717 for (i = 0; i < (seqcount - 1); i++) {
737 hctx->ccid2hctx_seqbuf[i].ccid2s_next = 718 hctx->ccid2hctx_seqbuf[i].ccid2s_next =
738 &hctx->ccid2hctx_seqbuf[i + 1]; 719 &hctx->ccid2hctx_seqbuf[i + 1];
@@ -763,15 +744,11 @@ static int ccid2_hc_tx_init(struct sock *sk)
763 744
764static void ccid2_hc_tx_exit(struct sock *sk) 745static void ccid2_hc_tx_exit(struct sock *sk)
765{ 746{
766 struct dccp_sock *dp = dccp_sk(sk);
767 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); 747 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
768 748
769 ccid2_hc_tx_kill_rto_timer(sk); 749 ccid2_hc_tx_kill_rto_timer(sk);
770
771 kfree(hctx->ccid2hctx_seqbuf); 750 kfree(hctx->ccid2hctx_seqbuf);
772 751 hctx->ccid2hctx_seqbuf = NULL;
773 kfree(dp->dccps_hc_tx_ccid_private);
774 dp->dccps_hc_tx_ccid_private = NULL;
775} 752}
776 753
777static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 754static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -791,33 +768,17 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
791 } 768 }
792} 769}
793 770
794static int ccid2_hc_rx_init(struct sock *sk) 771static struct ccid_operations ccid2 = {
795{
796 struct dccp_sock *dp = dccp_sk(sk);
797 dp->dccps_hc_rx_ccid_private = kzalloc(sizeof(struct ccid2_hc_rx_sock),
798 gfp_any());
799 return dp->dccps_hc_rx_ccid_private == NULL ? -ENOMEM : 0;
800}
801
802static void ccid2_hc_rx_exit(struct sock *sk)
803{
804 struct dccp_sock *dp = dccp_sk(sk);
805
806 kfree(dp->dccps_hc_rx_ccid_private);
807 dp->dccps_hc_rx_ccid_private = NULL;
808}
809
810static struct ccid ccid2 = {
811 .ccid_id = 2, 772 .ccid_id = 2,
812 .ccid_name = "ccid2", 773 .ccid_name = "ccid2",
813 .ccid_owner = THIS_MODULE, 774 .ccid_owner = THIS_MODULE,
775 .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
814 .ccid_hc_tx_init = ccid2_hc_tx_init, 776 .ccid_hc_tx_init = ccid2_hc_tx_init,
815 .ccid_hc_tx_exit = ccid2_hc_tx_exit, 777 .ccid_hc_tx_exit = ccid2_hc_tx_exit,
816 .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet, 778 .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet,
817 .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent, 779 .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent,
818 .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv, 780 .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv,
819 .ccid_hc_rx_init = ccid2_hc_rx_init, 781 .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock),
820 .ccid_hc_rx_exit = ccid2_hc_rx_exit,
821 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, 782 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
822}; 783};
823 784
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h
index 0b08c90955a9..451a87464fa5 100644
--- a/net/dccp/ccids/ccid2.h
+++ b/net/dccp/ccids/ccid2.h
@@ -20,6 +20,13 @@
20#ifndef _DCCP_CCID2_H_ 20#ifndef _DCCP_CCID2_H_
21#define _DCCP_CCID2_H_ 21#define _DCCP_CCID2_H_
22 22
23#include <linux/dccp.h>
24#include <linux/timer.h>
25#include <linux/types.h>
26#include "../ccid.h"
27
28struct sock;
29
23struct ccid2_seq { 30struct ccid2_seq {
24 u64 ccid2s_seq; 31 u64 ccid2s_seq;
25 unsigned long ccid2s_sent; 32 unsigned long ccid2s_sent;
@@ -66,4 +73,13 @@ struct ccid2_hc_rx_sock {
66 int ccid2hcrx_data; 73 int ccid2hcrx_data;
67}; 74};
68 75
76static inline struct ccid2_hc_tx_sock *ccid2_hc_tx_sk(const struct sock *sk)
77{
78 return ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid);
79}
80
81static inline struct ccid2_hc_rx_sock *ccid2_hc_rx_sk(const struct sock *sk)
82{
83 return ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
84}
69#endif /* _DCCP_CCID2_H_ */ 85#endif /* _DCCP_CCID2_H_ */
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index f9e16db09bef..0587f52e4af1 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -647,17 +647,10 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
647 return rc; 647 return rc;
648} 648}
649 649
650static int ccid3_hc_tx_init(struct sock *sk) 650static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
651{ 651{
652 struct dccp_sock *dp = dccp_sk(sk); 652 struct dccp_sock *dp = dccp_sk(sk);
653 struct ccid3_hc_tx_sock *hctx; 653 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
654
655 dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
656 if (dp->dccps_hc_tx_ccid_private == NULL)
657 return -ENOMEM;
658
659 hctx = ccid3_hc_tx_sk(sk);
660 memset(hctx, 0, sizeof(*hctx));
661 654
662 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 655 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
663 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 656 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
@@ -680,7 +673,6 @@ static int ccid3_hc_tx_init(struct sock *sk)
680 673
681static void ccid3_hc_tx_exit(struct sock *sk) 674static void ccid3_hc_tx_exit(struct sock *sk)
682{ 675{
683 struct dccp_sock *dp = dccp_sk(sk);
684 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 676 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
685 677
686 BUG_ON(hctx == NULL); 678 BUG_ON(hctx == NULL);
@@ -690,9 +682,6 @@ static void ccid3_hc_tx_exit(struct sock *sk)
690 682
691 /* Empty packet history */ 683 /* Empty packet history */
692 dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist); 684 dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
693
694 kfree(dp->dccps_hc_tx_ccid_private);
695 dp->dccps_hc_tx_ccid_private = NULL;
696} 685}
697 686
698/* 687/*
@@ -1039,20 +1028,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1039 } 1028 }
1040} 1029}
1041 1030
1042static int ccid3_hc_rx_init(struct sock *sk) 1031static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1043{ 1032{
1044 struct dccp_sock *dp = dccp_sk(sk); 1033 struct dccp_sock *dp = dccp_sk(sk);
1045 struct ccid3_hc_rx_sock *hcrx; 1034 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1046 1035
1047 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1036 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1048 1037
1049 dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
1050 if (dp->dccps_hc_rx_ccid_private == NULL)
1051 return -ENOMEM;
1052
1053 hcrx = ccid3_hc_rx_sk(sk);
1054 memset(hcrx, 0, sizeof(*hcrx));
1055
1056 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 1038 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
1057 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 1039 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
1058 hcrx->ccid3hcrx_s = dp->dccps_packet_size; 1040 hcrx->ccid3hcrx_s = dp->dccps_packet_size;
@@ -1071,7 +1053,6 @@ static int ccid3_hc_rx_init(struct sock *sk)
1071static void ccid3_hc_rx_exit(struct sock *sk) 1053static void ccid3_hc_rx_exit(struct sock *sk)
1072{ 1054{
1073 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 1055 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1074 struct dccp_sock *dp = dccp_sk(sk);
1075 1056
1076 BUG_ON(hcrx == NULL); 1057 BUG_ON(hcrx == NULL);
1077 1058
@@ -1082,9 +1063,6 @@ static void ccid3_hc_rx_exit(struct sock *sk)
1082 1063
1083 /* Empty loss interval history */ 1064 /* Empty loss interval history */
1084 dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist); 1065 dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
1085
1086 kfree(dp->dccps_hc_rx_ccid_private);
1087 dp->dccps_hc_rx_ccid_private = NULL;
1088} 1066}
1089 1067
1090static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 1068static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -1170,10 +1148,11 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
1170 return 0; 1148 return 0;
1171} 1149}
1172 1150
1173static struct ccid ccid3 = { 1151static struct ccid_operations ccid3 = {
1174 .ccid_id = 3, 1152 .ccid_id = 3,
1175 .ccid_name = "ccid3", 1153 .ccid_name = "ccid3",
1176 .ccid_owner = THIS_MODULE, 1154 .ccid_owner = THIS_MODULE,
1155 .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock),
1177 .ccid_hc_tx_init = ccid3_hc_tx_init, 1156 .ccid_hc_tx_init = ccid3_hc_tx_init,
1178 .ccid_hc_tx_exit = ccid3_hc_tx_exit, 1157 .ccid_hc_tx_exit = ccid3_hc_tx_exit,
1179 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet, 1158 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet,
@@ -1181,6 +1160,7 @@ static struct ccid ccid3 = {
1181 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv, 1160 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv,
1182 .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options, 1161 .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
1183 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options, 1162 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options,
1163 .ccid_hc_rx_obj_size = sizeof(struct ccid3_hc_rx_sock),
1184 .ccid_hc_rx_init = ccid3_hc_rx_init, 1164 .ccid_hc_rx_init = ccid3_hc_rx_init,
1185 .ccid_hc_rx_exit = ccid3_hc_rx_exit, 1165 .ccid_hc_rx_exit = ccid3_hc_rx_exit,
1186 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options, 1166 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 0bde4583d091..f18b96d4e5a2 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -41,6 +41,7 @@
41#include <linux/time.h> 41#include <linux/time.h>
42#include <linux/types.h> 42#include <linux/types.h>
43#include <linux/tfrc.h> 43#include <linux/tfrc.h>
44#include "../ccid.h"
44 45
45#define TFRC_MIN_PACKET_SIZE 16 46#define TFRC_MIN_PACKET_SIZE 16
46#define TFRC_STD_PACKET_SIZE 256 47#define TFRC_STD_PACKET_SIZE 256
@@ -135,12 +136,12 @@ struct ccid3_hc_rx_sock {
135 136
136static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) 137static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
137{ 138{
138 return dccp_sk(sk)->dccps_hc_tx_ccid_private; 139 return ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid);
139} 140}
140 141
141static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk) 142static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
142{ 143{
143 return dccp_sk(sk)->dccps_hc_rx_ccid_private; 144 return ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
144} 145}
145 146
146#endif /* _DCCP_CCID3_H_ */ 147#endif /* _DCCP_CCID3_H_ */
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 4b6d43d8b920..67691a0592af 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -324,14 +324,6 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
324 dccp_set_seqno(&dp->dccps_swl, 324 dccp_set_seqno(&dp->dccps_swl,
325 max48(dp->dccps_swl, dp->dccps_isr)); 325 max48(dp->dccps_swl, dp->dccps_isr));
326 326
327 if (ccid_hc_rx_init(dp->dccps_hc_rx_ccid, sk) != 0 ||
328 ccid_hc_tx_init(dp->dccps_hc_tx_ccid, sk) != 0) {
329 ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
330 ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
331 /* FIXME: send appropriate RESET code */
332 goto out_invalid_packet;
333 }
334
335 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); 327 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
336 328
337 /* 329 /*
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index fcfb486f90c2..aa7708fed32e 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1058,14 +1058,16 @@ int dccp_v4_init_sock(struct sock *sk)
1058 if (dp->dccps_hc_rx_ackvec == NULL) 1058 if (dp->dccps_hc_rx_ackvec == NULL)
1059 return -ENOMEM; 1059 return -ENOMEM;
1060 } 1060 }
1061 dp->dccps_hc_rx_ccid = ccid_init(dp->dccps_options.dccpo_rx_ccid, 1061 dp->dccps_hc_rx_ccid =
1062 sk); 1062 ccid_hc_rx_new(dp->dccps_options.dccpo_rx_ccid,
1063 dp->dccps_hc_tx_ccid = ccid_init(dp->dccps_options.dccpo_tx_ccid, 1063 sk, GFP_KERNEL);
1064 sk); 1064 dp->dccps_hc_tx_ccid =
1065 if (dp->dccps_hc_rx_ccid == NULL || 1065 ccid_hc_tx_new(dp->dccps_options.dccpo_tx_ccid,
1066 dp->dccps_hc_tx_ccid == NULL) { 1066 sk, GFP_KERNEL);
1067 ccid_exit(dp->dccps_hc_rx_ccid, sk); 1067 if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
1068 ccid_exit(dp->dccps_hc_tx_ccid, sk); 1068 dp->dccps_hc_tx_ccid == NULL)) {
1069 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
1070 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
1069 if (dp->dccps_options.dccpo_send_ack_vector) { 1071 if (dp->dccps_options.dccpo_send_ack_vector) {
1070 dccp_ackvec_free(dp->dccps_hc_rx_ackvec); 1072 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
1071 dp->dccps_hc_rx_ackvec = NULL; 1073 dp->dccps_hc_rx_ackvec = NULL;
@@ -1120,14 +1122,12 @@ int dccp_v4_destroy_sock(struct sock *sk)
1120 kfree(dp->dccps_service_list); 1122 kfree(dp->dccps_service_list);
1121 dp->dccps_service_list = NULL; 1123 dp->dccps_service_list = NULL;
1122 1124
1123 ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
1124 ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
1125 if (dp->dccps_options.dccpo_send_ack_vector) { 1125 if (dp->dccps_options.dccpo_send_ack_vector) {
1126 dccp_ackvec_free(dp->dccps_hc_rx_ackvec); 1126 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
1127 dp->dccps_hc_rx_ackvec = NULL; 1127 dp->dccps_hc_rx_ackvec = NULL;
1128 } 1128 }
1129 ccid_exit(dp->dccps_hc_rx_ccid, sk); 1129 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
1130 ccid_exit(dp->dccps_hc_tx_ccid, sk); 1130 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
1131 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL; 1131 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
1132 1132
1133 /* clean up feature negotiation state */ 1133 /* clean up feature negotiation state */
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 9e1de5919ee5..5324fcacb34d 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -121,23 +121,21 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
121 if (newdp->dccps_options.dccpo_send_ack_vector) { 121 if (newdp->dccps_options.dccpo_send_ack_vector) {
122 newdp->dccps_hc_rx_ackvec = 122 newdp->dccps_hc_rx_ackvec =
123 dccp_ackvec_alloc(GFP_ATOMIC); 123 dccp_ackvec_alloc(GFP_ATOMIC);
124 /*
125 * XXX: We're using the same CCIDs set on the parent,
126 * i.e. sk_clone copied the master sock and left the
127 * CCID pointers for this child, that is why we do the
128 * __ccid_get calls.
129 */
130 if (unlikely(newdp->dccps_hc_rx_ackvec == NULL)) 124 if (unlikely(newdp->dccps_hc_rx_ackvec == NULL))
131 goto out_free; 125 goto out_free;
132 } 126 }
133 127
134 if (unlikely(ccid_hc_rx_init(newdp->dccps_hc_rx_ccid, 128 newdp->dccps_hc_rx_ccid =
135 newsk) != 0 || 129 ccid_hc_rx_new(newdp->dccps_options.dccpo_rx_ccid,
136 ccid_hc_tx_init(newdp->dccps_hc_tx_ccid, 130 newsk, GFP_ATOMIC);
137 newsk) != 0)) { 131 newdp->dccps_hc_tx_ccid =
132 ccid_hc_tx_new(newdp->dccps_options.dccpo_tx_ccid,
133 newsk, GFP_ATOMIC);
134 if (unlikely(newdp->dccps_hc_rx_ccid == NULL ||
135 newdp->dccps_hc_tx_ccid == NULL)) {
138 dccp_ackvec_free(newdp->dccps_hc_rx_ackvec); 136 dccp_ackvec_free(newdp->dccps_hc_rx_ackvec);
139 ccid_hc_rx_exit(newdp->dccps_hc_rx_ccid, newsk); 137 ccid_hc_rx_delete(newdp->dccps_hc_rx_ccid, newsk);
140 ccid_hc_tx_exit(newdp->dccps_hc_tx_ccid, newsk); 138 ccid_hc_tx_delete(newdp->dccps_hc_tx_ccid, newsk);
141out_free: 139out_free:
142 /* It is still raw copy of parent, so invalidate 140 /* It is still raw copy of parent, so invalidate
143 * destructor and make plain sk_free() */ 141 * destructor and make plain sk_free() */
@@ -146,9 +144,6 @@ out_free:
146 return NULL; 144 return NULL;
147 } 145 }
148 146
149 __ccid_get(newdp->dccps_hc_rx_ccid);
150 __ccid_get(newdp->dccps_hc_tx_ccid);
151
152 /* 147 /*
153 * Step 3: Process LISTEN state 148 * Step 3: Process LISTEN state
154 * 149 *