diff options
Diffstat (limited to 'net/ipv6/reassembly.c')
-rw-r--r-- | net/ipv6/reassembly.c | 50 |
1 files changed, 19 insertions, 31 deletions
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index ce8734028d94..11fffe791fc4 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -155,6 +155,18 @@ int ip6_frag_equal(struct inet_frag_queue *q1, struct inet_frag_queue *q2) | |||
155 | } | 155 | } |
156 | EXPORT_SYMBOL(ip6_frag_equal); | 156 | EXPORT_SYMBOL(ip6_frag_equal); |
157 | 157 | ||
158 | int ip6_frag_match(struct inet_frag_queue *q, void *a) | ||
159 | { | ||
160 | struct frag_queue *fq; | ||
161 | struct ip6_create_arg *arg = a; | ||
162 | |||
163 | fq = container_of(q, struct frag_queue, q); | ||
164 | return (fq->id == arg->id && | ||
165 | ipv6_addr_equal(&fq->saddr, arg->src) && | ||
166 | ipv6_addr_equal(&fq->daddr, arg->dst)); | ||
167 | } | ||
168 | EXPORT_SYMBOL(ip6_frag_match); | ||
169 | |||
158 | /* Memory Tracking Functions. */ | 170 | /* Memory Tracking Functions. */ |
159 | static inline void frag_kfree_skb(struct sk_buff *skb, int *work) | 171 | static inline void frag_kfree_skb(struct sk_buff *skb, int *work) |
160 | { | 172 | { |
@@ -245,20 +257,20 @@ out: | |||
245 | fq_put(fq); | 257 | fq_put(fq); |
246 | } | 258 | } |
247 | 259 | ||
248 | /* Creation primitives. */ | 260 | static __inline__ struct frag_queue * |
249 | 261 | fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst, | |
250 | static struct frag_queue * | 262 | struct inet6_dev *idev) |
251 | ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, | ||
252 | struct inet6_dev *idev, unsigned int hash) | ||
253 | { | 263 | { |
254 | struct inet_frag_queue *q; | 264 | struct inet_frag_queue *q; |
255 | struct ip6_create_arg arg; | 265 | struct ip6_create_arg arg; |
266 | unsigned int hash; | ||
256 | 267 | ||
257 | arg.id = id; | 268 | arg.id = id; |
258 | arg.src = src; | 269 | arg.src = src; |
259 | arg.dst = dst; | 270 | arg.dst = dst; |
271 | hash = ip6qhashfn(id, src, dst); | ||
260 | 272 | ||
261 | q = inet_frag_create(&ip6_frags, &arg, hash); | 273 | q = inet_frag_find(&ip6_frags, &arg, hash); |
262 | if (q == NULL) | 274 | if (q == NULL) |
263 | goto oom; | 275 | goto oom; |
264 | 276 | ||
@@ -269,31 +281,6 @@ oom: | |||
269 | return NULL; | 281 | return NULL; |
270 | } | 282 | } |
271 | 283 | ||
272 | static __inline__ struct frag_queue * | ||
273 | fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst, | ||
274 | struct inet6_dev *idev) | ||
275 | { | ||
276 | struct frag_queue *fq; | ||
277 | struct hlist_node *n; | ||
278 | unsigned int hash; | ||
279 | |||
280 | read_lock(&ip6_frags.lock); | ||
281 | hash = ip6qhashfn(id, src, dst); | ||
282 | hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) { | ||
283 | if (fq->id == id && | ||
284 | ipv6_addr_equal(src, &fq->saddr) && | ||
285 | ipv6_addr_equal(dst, &fq->daddr)) { | ||
286 | atomic_inc(&fq->q.refcnt); | ||
287 | read_unlock(&ip6_frags.lock); | ||
288 | return fq; | ||
289 | } | ||
290 | } | ||
291 | read_unlock(&ip6_frags.lock); | ||
292 | |||
293 | return ip6_frag_create(id, src, dst, idev, hash); | ||
294 | } | ||
295 | |||
296 | |||
297 | static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | 284 | static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, |
298 | struct frag_hdr *fhdr, int nhoff) | 285 | struct frag_hdr *fhdr, int nhoff) |
299 | { | 286 | { |
@@ -673,6 +660,7 @@ void __init ipv6_frag_init(void) | |||
673 | ip6_frags.destructor = ip6_frag_free; | 660 | ip6_frags.destructor = ip6_frag_free; |
674 | ip6_frags.skb_free = NULL; | 661 | ip6_frags.skb_free = NULL; |
675 | ip6_frags.qsize = sizeof(struct frag_queue); | 662 | ip6_frags.qsize = sizeof(struct frag_queue); |
663 | ip6_frags.match = ip6_frag_match; | ||
676 | ip6_frags.equal = ip6_frag_equal; | 664 | ip6_frags.equal = ip6_frag_equal; |
677 | ip6_frags.frag_expire = ip6_frag_expire; | 665 | ip6_frags.frag_expire = ip6_frag_expire; |
678 | inet_frags_init(&ip6_frags); | 666 | inet_frags_init(&ip6_frags); |