diff options
Diffstat (limited to 'net/ipv6/reassembly.c')
-rw-r--r-- | net/ipv6/reassembly.c | 45 |
1 files changed, 20 insertions, 25 deletions
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); |