diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2007-10-17 22:46:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-10-17 22:46:47 -0400 |
commit | c6fda282294da882f8d8cc4c513940277dd380f5 (patch) | |
tree | 29ef5fbc59320851c8db28e7f2c0a8c3fd85c231 | |
parent | e521db9d790aaa60ae8920e21cb7faedc280fc36 (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.h | 7 | ||||
-rw-r--r-- | include/net/ipv6.h | 8 | ||||
-rw-r--r-- | net/ipv4/inet_fragment.c | 20 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 54 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 39 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 45 |
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); | |||
53 | void inet_frag_destroy(struct inet_frag_queue *q, | 55 | void inet_frag_destroy(struct inet_frag_queue *q, |
54 | struct inet_frags *f, int *work); | 56 | struct inet_frags *f, int *work); |
55 | int inet_frag_evictor(struct inet_frags *f); | 57 | int inet_frag_evictor(struct inet_frags *f); |
56 | struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *q, | 58 | struct 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); |
58 | struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f); | ||
59 | 60 | ||
60 | static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) | 61 | static 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, | |||
380 | struct inet_frag_queue; | 380 | struct inet_frag_queue; |
381 | int ip6_frag_equal(struct inet_frag_queue *q1, struct inet_frag_queue *q2); | 381 | int ip6_frag_equal(struct inet_frag_queue *q1, struct inet_frag_queue *q2); |
382 | 382 | ||
383 | struct ip6_create_arg { | ||
384 | __be32 id; | ||
385 | struct in6_addr *src; | ||
386 | struct in6_addr *dst; | ||
387 | }; | ||
388 | |||
389 | void ip6_frag_init(struct inet_frag_queue *q, void *a); | ||
390 | |||
383 | static inline int ipv6_addr_any(const struct in6_addr *a) | 391 | static 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 | } |
174 | EXPORT_SYMBOL(inet_frag_evictor); | 174 | EXPORT_SYMBOL(inet_frag_evictor); |
175 | 175 | ||
176 | struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, | 176 | static 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 | } |
211 | EXPORT_SYMBOL(inet_frag_intern); | ||
212 | 211 | ||
213 | struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f) | 212 | static 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 | } |
228 | EXPORT_SYMBOL(inet_frag_alloc); | 228 | |
229 | struct 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 | } | ||
240 | EXPORT_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) | |||
108 | static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | 108 | static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, |
109 | struct net_device *dev); | 109 | struct net_device *dev); |
110 | 110 | ||
111 | struct ip4_create_arg { | ||
112 | struct iphdr *iph; | ||
113 | u32 user; | ||
114 | }; | ||
115 | |||
111 | static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) | 116 | static 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 | ||
154 | static 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 | |||
149 | static __inline__ void ip4_frag_free(struct inet_frag_queue *q) | 168 | static __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 | ||
159 | static __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 | ||
229 | static 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. */ |
238 | static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) | 241 | static 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 | ||
254 | out_nomem: | 255 | out_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 | ||
138 | static 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 | ||
148 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) | 140 | static __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 | ||
187 | static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, | 179 | static struct nf_ct_frag6_queue * |
188 | struct nf_ct_frag6_queue *fq_in) | 180 | nf_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 | |||
197 | static struct nf_ct_frag6_queue * | ||
198 | nf_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 | ||
213 | oom: | 196 | oom: |
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 | ||
167 | static void ip6_frag_free(struct inet_frag_queue *fq) | 167 | void 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 | } |
176 | EXPORT_SYMBOL(ip6_frag_init); | ||
171 | 177 | ||
172 | static inline struct frag_queue *frag_alloc_queue(void) | 178 | static 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 | |||
248 | static 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 | |||
258 | static struct frag_queue * | 250 | static struct frag_queue * |
259 | ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, | 251 | ip6_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 | ||
273 | oom: | 267 | oom: |
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); |