reassembly.c (787bea7748a76130566f881c2342a0be4127d182) reassembly.c (093ba72914b696521e4885756a68a3332782c8de)
1/*
2 * IPv6 fragment reassembly
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on: net/ipv4/ip_fragment.c

--- 114 unchanged lines hidden (view full) ---

123 fq->id = arg->id;
124 fq->user = arg->user;
125 fq->saddr = *arg->src;
126 fq->daddr = *arg->dst;
127 fq->ecn = arg->ecn;
128}
129EXPORT_SYMBOL(ip6_frag_init);
130
1/*
2 * IPv6 fragment reassembly
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on: net/ipv4/ip_fragment.c

--- 114 unchanged lines hidden (view full) ---

123 fq->id = arg->id;
124 fq->user = arg->user;
125 fq->saddr = *arg->src;
126 fq->daddr = *arg->dst;
127 fq->ecn = arg->ecn;
128}
129EXPORT_SYMBOL(ip6_frag_init);
130
131void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
132 struct inet_frags *frags)
131void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)
133{
134 struct net_device *dev = NULL;
135
136 spin_lock(&fq->q.lock);
137
138 if (fq->q.flags & INET_FRAG_COMPLETE)
139 goto out;
140
132{
133 struct net_device *dev = NULL;
134
135 spin_lock(&fq->q.lock);
136
137 if (fq->q.flags & INET_FRAG_COMPLETE)
138 goto out;
139
141 inet_frag_kill(&fq->q, frags);
140 inet_frag_kill(&fq->q);
142
143 rcu_read_lock();
144 dev = dev_get_by_index_rcu(net, fq->iif);
145 if (!dev)
146 goto out_rcu_unlock;
147
148 __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
149

--- 11 unchanged lines hidden (view full) ---

161 * pointer directly, device might already disappeared.
162 */
163 fq->q.fragments->dev = dev;
164 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
165out_rcu_unlock:
166 rcu_read_unlock();
167out:
168 spin_unlock(&fq->q.lock);
141
142 rcu_read_lock();
143 dev = dev_get_by_index_rcu(net, fq->iif);
144 if (!dev)
145 goto out_rcu_unlock;
146
147 __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
148

--- 11 unchanged lines hidden (view full) ---

160 * pointer directly, device might already disappeared.
161 */
162 fq->q.fragments->dev = dev;
163 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
164out_rcu_unlock:
165 rcu_read_unlock();
166out:
167 spin_unlock(&fq->q.lock);
169 inet_frag_put(&fq->q, frags);
168 inet_frag_put(&fq->q);
170}
171EXPORT_SYMBOL(ip6_expire_frag_queue);
172
173static void ip6_frag_expire(struct timer_list *t)
174{
175 struct inet_frag_queue *frag = from_timer(frag, t, timer);
176 struct frag_queue *fq;
177 struct net *net;
178
179 fq = container_of(frag, struct frag_queue, q);
180 net = container_of(fq->q.net, struct net, ipv6.frags);
181
169}
170EXPORT_SYMBOL(ip6_expire_frag_queue);
171
172static void ip6_frag_expire(struct timer_list *t)
173{
174 struct inet_frag_queue *frag = from_timer(frag, t, timer);
175 struct frag_queue *fq;
176 struct net *net;
177
178 fq = container_of(frag, struct frag_queue, q);
179 net = container_of(fq->q.net, struct net, ipv6.frags);
180
182 ip6_expire_frag_queue(net, fq, &ip6_frags);
181 ip6_expire_frag_queue(net, fq);
183}
184
185static struct frag_queue *
186fq_find(struct net *net, __be32 id, const struct in6_addr *src,
187 const struct in6_addr *dst, int iif, u8 ecn)
188{
189 struct inet_frag_queue *q;
190 struct ip6_create_arg arg;

--- 168 unchanged lines hidden (view full) ---

359 skb->_skb_refdst = orefdst;
360 return res;
361 }
362
363 skb_dst_drop(skb);
364 return -1;
365
366discard_fq:
182}
183
184static struct frag_queue *
185fq_find(struct net *net, __be32 id, const struct in6_addr *src,
186 const struct in6_addr *dst, int iif, u8 ecn)
187{
188 struct inet_frag_queue *q;
189 struct ip6_create_arg arg;

--- 168 unchanged lines hidden (view full) ---

358 skb->_skb_refdst = orefdst;
359 return res;
360 }
361
362 skb_dst_drop(skb);
363 return -1;
364
365discard_fq:
367 inet_frag_kill(&fq->q, &ip6_frags);
366 inet_frag_kill(&fq->q);
368err:
369 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
370 IPSTATS_MIB_REASMFAILS);
371 kfree_skb(skb);
372 return -1;
373}
374
375/*

--- 10 unchanged lines hidden (view full) ---

386{
387 struct net *net = container_of(fq->q.net, struct net, ipv6.frags);
388 struct sk_buff *fp, *head = fq->q.fragments;
389 int payload_len;
390 unsigned int nhoff;
391 int sum_truesize;
392 u8 ecn;
393
367err:
368 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
369 IPSTATS_MIB_REASMFAILS);
370 kfree_skb(skb);
371 return -1;
372}
373
374/*

--- 10 unchanged lines hidden (view full) ---

385{
386 struct net *net = container_of(fq->q.net, struct net, ipv6.frags);
387 struct sk_buff *fp, *head = fq->q.fragments;
388 int payload_len;
389 unsigned int nhoff;
390 int sum_truesize;
391 u8 ecn;
392
394 inet_frag_kill(&fq->q, &ip6_frags);
393 inet_frag_kill(&fq->q);
395
396 ecn = ip_frag_ecn_table[fq->ecn];
397 if (unlikely(ecn == 0xff))
398 goto out_fail;
399
400 /* Make the one we just received the head. */
401 if (prev) {
402 head = prev->next;

--- 161 unchanged lines hidden (view full) ---

564 if (fq) {
565 int ret;
566
567 spin_lock(&fq->q.lock);
568
569 ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
570
571 spin_unlock(&fq->q.lock);
394
395 ecn = ip_frag_ecn_table[fq->ecn];
396 if (unlikely(ecn == 0xff))
397 goto out_fail;
398
399 /* Make the one we just received the head. */
400 if (prev) {
401 head = prev->next;

--- 161 unchanged lines hidden (view full) ---

563 if (fq) {
564 int ret;
565
566 spin_lock(&fq->q.lock);
567
568 ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
569
570 spin_unlock(&fq->q.lock);
572 inet_frag_put(&fq->q, &ip6_frags);
571 inet_frag_put(&fq->q);
573 return ret;
574 }
575
576 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMFAILS);
577 kfree_skb(skb);
578 return -1;
579
580fail_hdr:

--- 130 unchanged lines hidden (view full) ---

711
712static int __net_init ipv6_frags_init_net(struct net *net)
713{
714 int res;
715
716 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
717 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
718 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
572 return ret;
573 }
574
575 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMFAILS);
576 kfree_skb(skb);
577 return -1;
578
579fail_hdr:

--- 130 unchanged lines hidden (view full) ---

710
711static int __net_init ipv6_frags_init_net(struct net *net)
712{
713 int res;
714
715 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
716 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
717 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
718 net->ipv6.frags.f = &ip6_frags;
719
720 res = inet_frags_init_net(&net->ipv6.frags);
721 if (res < 0)
722 return res;
723
724 res = ip6_frags_ns_sysctl_register(net);
725 if (res < 0)
719
720 res = inet_frags_init_net(&net->ipv6.frags);
721 if (res < 0)
722 return res;
723
724 res = ip6_frags_ns_sysctl_register(net);
725 if (res < 0)
726 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
726 inet_frags_exit_net(&net->ipv6.frags);
727 return res;
728}
729
730static void __net_exit ipv6_frags_exit_net(struct net *net)
731{
732 ip6_frags_ns_sysctl_unregister(net);
727 return res;
728}
729
730static void __net_exit ipv6_frags_exit_net(struct net *net)
731{
732 ip6_frags_ns_sysctl_unregister(net);
733 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
733 inet_frags_exit_net(&net->ipv6.frags);
734}
735
736static struct pernet_operations ip6_frags_ops = {
737 .init = ipv6_frags_init_net,
738 .exit = ipv6_frags_exit_net,
739};
740
741int __init ipv6_frag_init(void)

--- 42 unchanged lines hidden ---
734}
735
736static struct pernet_operations ip6_frags_ops = {
737 .init = ipv6_frags_init_net,
738 .exit = ipv6_frags_exit_net,
739};
740
741int __init ipv6_frag_init(void)

--- 42 unchanged lines hidden ---