aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-17 22:46:47 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-17 22:46:47 -0400
commitc6fda282294da882f8d8cc4c513940277dd380f5 (patch)
tree29ef5fbc59320851c8db28e7f2c0a8c3fd85c231
parente521db9d790aaa60ae8920e21cb7faedc280fc36 (diff)
[INET]: Consolidate xxx_frag_create()
This one uses the xxx_frag_intern() and xxx_frag_alloc() routines, which are already consolidated, so remove them from protocol code (as promised). The ->constructor callback is used to init the rest of the frag queue and it is the same for netfilter and ipv6. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/inet_frag.h7
-rw-r--r--include/net/ipv6.h8
-rw-r--r--net/ipv4/inet_fragment.c20
-rw-r--r--net/ipv4/ip_fragment.c54
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c39
-rw-r--r--net/ipv6/reassembly.c45
6 files changed, 88 insertions, 85 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 412b8582a616..e33072b9fd91 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -39,6 +39,8 @@ struct inet_frags {
39 struct inet_frags_ctl *ctl; 39 struct inet_frags_ctl *ctl;
40 40
41 unsigned int (*hashfn)(struct inet_frag_queue *); 41 unsigned int (*hashfn)(struct inet_frag_queue *);
42 void (*constructor)(struct inet_frag_queue *q,
43 void *arg);
42 void (*destructor)(struct inet_frag_queue *); 44 void (*destructor)(struct inet_frag_queue *);
43 void (*skb_free)(struct sk_buff *); 45 void (*skb_free)(struct sk_buff *);
44 int (*equal)(struct inet_frag_queue *q1, 46 int (*equal)(struct inet_frag_queue *q1,
@@ -53,9 +55,8 @@ void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
53void inet_frag_destroy(struct inet_frag_queue *q, 55void inet_frag_destroy(struct inet_frag_queue *q,
54 struct inet_frags *f, int *work); 56 struct inet_frags *f, int *work);
55int inet_frag_evictor(struct inet_frags *f); 57int inet_frag_evictor(struct inet_frags *f);
56struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *q, 58struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
57 struct inet_frags *f, unsigned int hash); 59 void *create_arg, unsigned int hash);
58struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f);
59 60
60static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) 61static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
61{ 62{
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ff1269713462..9dc99bf5cf0e 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -380,6 +380,14 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
380struct inet_frag_queue; 380struct inet_frag_queue;
381int ip6_frag_equal(struct inet_frag_queue *q1, struct inet_frag_queue *q2); 381int ip6_frag_equal(struct inet_frag_queue *q1, struct inet_frag_queue *q2);
382 382
383struct ip6_create_arg {
384 __be32 id;
385 struct in6_addr *src;
386 struct in6_addr *dst;
387};
388
389void ip6_frag_init(struct inet_frag_queue *q, void *a);
390
383static inline int ipv6_addr_any(const struct in6_addr *a) 391static inline int ipv6_addr_any(const struct in6_addr *a)
384{ 392{
385 return ((a->s6_addr32[0] | a->s6_addr32[1] | 393 return ((a->s6_addr32[0] | a->s6_addr32[1] |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 57e15fa307dc..b531f803cda4 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -173,7 +173,7 @@ int inet_frag_evictor(struct inet_frags *f)
173} 173}
174EXPORT_SYMBOL(inet_frag_evictor); 174EXPORT_SYMBOL(inet_frag_evictor);
175 175
176struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, 176static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
177 struct inet_frags *f, unsigned int hash) 177 struct inet_frags *f, unsigned int hash)
178{ 178{
179 struct inet_frag_queue *qp; 179 struct inet_frag_queue *qp;
@@ -208,9 +208,8 @@ struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
208 write_unlock(&f->lock); 208 write_unlock(&f->lock);
209 return qp; 209 return qp;
210} 210}
211EXPORT_SYMBOL(inet_frag_intern);
212 211
213struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f) 212static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
214{ 213{
215 struct inet_frag_queue *q; 214 struct inet_frag_queue *q;
216 215
@@ -218,6 +217,7 @@ struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f)
218 if (q == NULL) 217 if (q == NULL)
219 return NULL; 218 return NULL;
220 219
220 f->constructor(q, arg);
221 atomic_add(f->qsize, &f->mem); 221 atomic_add(f->qsize, &f->mem);
222 setup_timer(&q->timer, f->frag_expire, (unsigned long)q); 222 setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
223 spin_lock_init(&q->lock); 223 spin_lock_init(&q->lock);
@@ -225,4 +225,16 @@ struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f)
225 225
226 return q; 226 return q;
227} 227}
228EXPORT_SYMBOL(inet_frag_alloc); 228
229struct inet_frag_queue *inet_frag_create(struct inet_frags *f, void *arg,
230 unsigned int hash)
231{
232 struct inet_frag_queue *q;
233
234 q = inet_frag_alloc(f, arg);
235 if (q == NULL)
236 return NULL;
237
238 return inet_frag_intern(q, f, hash);
239}
240EXPORT_SYMBOL(inet_frag_create);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index fc0d530df522..0d6cff1de5a3 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -108,6 +108,11 @@ int ip_frag_mem(void)
108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, 108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
109 struct net_device *dev); 109 struct net_device *dev);
110 110
111struct ip4_create_arg {
112 struct iphdr *iph;
113 u32 user;
114};
115
111static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) 116static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
112{ 117{
113 return jhash_3words((__force u32)id << 16 | prot, 118 return jhash_3words((__force u32)id << 16 | prot,
@@ -146,6 +151,20 @@ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
146 kfree_skb(skb); 151 kfree_skb(skb);
147} 152}
148 153
154static void ip4_frag_init(struct inet_frag_queue *q, void *a)
155{
156 struct ipq *qp = container_of(q, struct ipq, q);
157 struct ip4_create_arg *arg = a;
158
159 qp->protocol = arg->iph->protocol;
160 qp->id = arg->iph->id;
161 qp->saddr = arg->iph->saddr;
162 qp->daddr = arg->iph->daddr;
163 qp->user = arg->user;
164 qp->peer = sysctl_ipfrag_max_dist ?
165 inet_getpeer(arg->iph->saddr, 1) : NULL;
166}
167
149static __inline__ void ip4_frag_free(struct inet_frag_queue *q) 168static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
150{ 169{
151 struct ipq *qp; 170 struct ipq *qp;
@@ -156,14 +175,6 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
156 kfree(qp); 175 kfree(qp);
157} 176}
158 177
159static __inline__ struct ipq *frag_alloc_queue(void)
160{
161 struct inet_frag_queue *q;
162
163 q = inet_frag_alloc(&ip4_frags);
164 return q ? container_of(q, struct ipq, q) : NULL;
165}
166
167 178
168/* Destruction primitives. */ 179/* Destruction primitives. */
169 180
@@ -226,30 +237,20 @@ out:
226 237
227/* Creation primitives. */ 238/* Creation primitives. */
228 239
229static struct ipq *ip_frag_intern(struct ipq *qp_in, unsigned int hash)
230{
231 struct inet_frag_queue *q;
232
233 q = inet_frag_intern(&qp_in->q, &ip4_frags, hash);
234 return container_of(q, struct ipq, q);
235}
236
237/* Add an entry to the 'ipq' queue for a newly received IP datagram. */ 240/* Add an entry to the 'ipq' queue for a newly received IP datagram. */
238static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) 241static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h)
239{ 242{
240 struct ipq *qp; 243 struct inet_frag_queue *q;
244 struct ip4_create_arg arg;
241 245
242 if ((qp = frag_alloc_queue()) == NULL) 246 arg.iph = iph;
243 goto out_nomem; 247 arg.user = user;
244 248
245 qp->protocol = iph->protocol; 249 q = inet_frag_create(&ip4_frags, &arg, h);
246 qp->id = iph->id; 250 if (q == NULL)
247 qp->saddr = iph->saddr; 251 goto out_nomem;
248 qp->daddr = iph->daddr;
249 qp->user = user;
250 qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
251 252
252 return ip_frag_intern(qp, h); 253 return container_of(q, struct ipq, q);
253 254
254out_nomem: 255out_nomem:
255 LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); 256 LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
@@ -642,6 +643,7 @@ void __init ipfrag_init(void)
642{ 643{
643 ip4_frags.ctl = &ip4_frags_ctl; 644 ip4_frags.ctl = &ip4_frags_ctl;
644 ip4_frags.hashfn = ip4_hashfn; 645 ip4_frags.hashfn = ip4_hashfn;
646 ip4_frags.constructor = ip4_frag_init;
645 ip4_frags.destructor = ip4_frag_free; 647 ip4_frags.destructor = ip4_frag_free;
646 ip4_frags.skb_free = NULL; 648 ip4_frags.skb_free = NULL;
647 ip4_frags.qsize = sizeof(struct ipq); 649 ip4_frags.qsize = sizeof(struct ipq);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 3f8c16b3301e..127d1d842786 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -135,14 +135,6 @@ static void nf_frag_free(struct inet_frag_queue *q)
135 kfree(container_of(q, struct nf_ct_frag6_queue, q)); 135 kfree(container_of(q, struct nf_ct_frag6_queue, q));
136} 136}
137 137
138static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
139{
140 struct inet_frag_queue *q;
141
142 q = inet_frag_alloc(&nf_frags);
143 return q ? container_of(q, struct nf_ct_frag6_queue, q) : NULL;
144}
145
146/* Destruction primitives. */ 138/* Destruction primitives. */
147 139
148static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) 140static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
@@ -184,33 +176,25 @@ out:
184 176
185/* Creation primitives. */ 177/* Creation primitives. */
186 178
187static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, 179static struct nf_ct_frag6_queue *
188 struct nf_ct_frag6_queue *fq_in) 180nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src,
181 struct in6_addr *dst)
189{ 182{
190 struct inet_frag_queue *q; 183 struct inet_frag_queue *q;
184 struct ip6_create_arg arg;
191 185
192 q = inet_frag_intern(&fq_in->q, &nf_frags, hash); 186 arg.id = id;
193 return container_of(q, struct nf_ct_frag6_queue, q); 187 arg.src = src;
194} 188 arg.dst = dst;
195
196
197static struct nf_ct_frag6_queue *
198nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, struct in6_addr *dst)
199{
200 struct nf_ct_frag6_queue *fq;
201 189
202 if ((fq = frag_alloc_queue()) == NULL) { 190 q = inet_frag_create(&nf_frags, &arg, hash);
203 pr_debug("Can't alloc new queue\n"); 191 if (q == NULL)
204 goto oom; 192 goto oom;
205 }
206 193
207 fq->id = id; 194 return container_of(q, struct nf_ct_frag6_queue, q);
208 ipv6_addr_copy(&fq->saddr, src);
209 ipv6_addr_copy(&fq->daddr, dst);
210
211 return nf_ct_frag6_intern(hash, fq);
212 195
213oom: 196oom:
197 pr_debug("Can't alloc new queue\n");
214 return NULL; 198 return NULL;
215} 199}
216 200
@@ -718,6 +702,7 @@ int nf_ct_frag6_init(void)
718{ 702{
719 nf_frags.ctl = &nf_frags_ctl; 703 nf_frags.ctl = &nf_frags_ctl;
720 nf_frags.hashfn = nf_hashfn; 704 nf_frags.hashfn = nf_hashfn;
705 nf_frags.constructor = ip6_frag_init;
721 nf_frags.destructor = nf_frag_free; 706 nf_frags.destructor = nf_frag_free;
722 nf_frags.skb_free = nf_skb_free; 707 nf_frags.skb_free = nf_skb_free;
723 nf_frags.qsize = sizeof(struct nf_ct_frag6_queue); 708 nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 21913c78f053..ce8734028d94 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -164,17 +164,20 @@ static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
164 kfree_skb(skb); 164 kfree_skb(skb);
165} 165}
166 166
167static void ip6_frag_free(struct inet_frag_queue *fq) 167void ip6_frag_init(struct inet_frag_queue *q, void *a)
168{ 168{
169 kfree(container_of(fq, struct frag_queue, q)); 169 struct frag_queue *fq = container_of(q, struct frag_queue, q);
170 struct ip6_create_arg *arg = a;
171
172 fq->id = arg->id;
173 ipv6_addr_copy(&fq->saddr, arg->src);
174 ipv6_addr_copy(&fq->daddr, arg->dst);
170} 175}
176EXPORT_SYMBOL(ip6_frag_init);
171 177
172static inline struct frag_queue *frag_alloc_queue(void) 178static void ip6_frag_free(struct inet_frag_queue *fq)
173{ 179{
174 struct inet_frag_queue *q; 180 kfree(container_of(fq, struct frag_queue, q));
175
176 q = inet_frag_alloc(&ip6_frags);
177 return q ? container_of(q, struct frag_queue, q) : NULL;
178} 181}
179 182
180/* Destruction primitives. */ 183/* Destruction primitives. */
@@ -244,31 +247,22 @@ out:
244 247
245/* Creation primitives. */ 248/* Creation primitives. */
246 249
247
248static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in,
249 unsigned int hash)
250{
251 struct inet_frag_queue *q;
252
253 q = inet_frag_intern(&fq_in->q, &ip6_frags, hash);
254 return container_of(q, struct frag_queue, q);
255}
256
257
258static struct frag_queue * 250static struct frag_queue *
259ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, 251ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
260 struct inet6_dev *idev, unsigned int hash) 252 struct inet6_dev *idev, unsigned int hash)
261{ 253{
262 struct frag_queue *fq; 254 struct inet_frag_queue *q;
255 struct ip6_create_arg arg;
263 256
264 if ((fq = frag_alloc_queue()) == NULL) 257 arg.id = id;
265 goto oom; 258 arg.src = src;
259 arg.dst = dst;
266 260
267 fq->id = id; 261 q = inet_frag_create(&ip6_frags, &arg, hash);
268 ipv6_addr_copy(&fq->saddr, src); 262 if (q == NULL)
269 ipv6_addr_copy(&fq->daddr, dst); 263 goto oom;
270 264
271 return ip6_frag_intern(fq, hash); 265 return container_of(q, struct frag_queue, q);
272 266
273oom: 267oom:
274 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS); 268 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
@@ -675,6 +669,7 @@ void __init ipv6_frag_init(void)
675 669
676 ip6_frags.ctl = &ip6_frags_ctl; 670 ip6_frags.ctl = &ip6_frags_ctl;
677 ip6_frags.hashfn = ip6_hashfn; 671 ip6_frags.hashfn = ip6_hashfn;
672 ip6_frags.constructor = ip6_frag_init;
678 ip6_frags.destructor = ip6_frag_free; 673 ip6_frags.destructor = ip6_frag_free;
679 ip6_frags.skb_free = NULL; 674 ip6_frags.skb_free = NULL;
680 ip6_frags.qsize = sizeof(struct frag_queue); 675 ip6_frags.qsize = sizeof(struct frag_queue);