227
228
229 fq->q.fragments->dev = dev;
230 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev);
231out:
232 if (dev)
233 dev_put(dev);
234 spin_unlock(&fq->q.lock);
235 fq_put(fq);
236}
237
238static __inline__ struct frag_queue *
239fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
240 struct inet6_dev *idev)
241{
242 struct inet_frag_queue *q;
243 struct ip6_create_arg arg;
244 unsigned int hash;
245
246 arg.id = id;
247 arg.src = src;
248 arg.dst = dst;
249
250 read_lock(&ip6_frags.lock);
251 hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
252
253 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
254 if (q == NULL)
255 goto oom;
256
257 return container_of(q, struct frag_queue, q);
258
259oom:
260 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS);
261 return NULL;
262}
263
264static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
265 struct frag_hdr *fhdr, int nhoff)
266{
267 struct sk_buff *prev, *next;