diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-05 15:46:18 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-05 15:46:18 -0500 |
commit | 3fa04ecd72780da31ba8b329e148179bc24a9c7d (patch) | |
tree | f5d462fd4aee086952d18f159f737c450ab46b3b /net/ipv4/ip_fragment.c | |
parent | 180b62a3d837613fcac3ce89576526423926c3c3 (diff) | |
parent | 1cda707d52e51a6cafac0aef12d2bd7052d572e6 (diff) |
Merge branch 'writeback-for-2.6.34' into nfs-for-2.6.34
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r-- | net/ipv4/ip_fragment.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 86964b353c31..b59430bc041c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
33 | #include <linux/jhash.h> | 33 | #include <linux/jhash.h> |
34 | #include <linux/random.h> | 34 | #include <linux/random.h> |
35 | #include <net/route.h> | ||
36 | #include <net/dst.h> | ||
35 | #include <net/sock.h> | 37 | #include <net/sock.h> |
36 | #include <net/ip.h> | 38 | #include <net/ip.h> |
37 | #include <net/icmp.h> | 39 | #include <net/icmp.h> |
@@ -205,11 +207,34 @@ static void ip_expire(unsigned long arg) | |||
205 | if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { | 207 | if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { |
206 | struct sk_buff *head = qp->q.fragments; | 208 | struct sk_buff *head = qp->q.fragments; |
207 | 209 | ||
208 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ | ||
209 | rcu_read_lock(); | 210 | rcu_read_lock(); |
210 | head->dev = dev_get_by_index_rcu(net, qp->iif); | 211 | head->dev = dev_get_by_index_rcu(net, qp->iif); |
211 | if (head->dev) | 212 | if (!head->dev) |
212 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); | 213 | goto out_rcu_unlock; |
214 | |||
215 | /* | ||
216 | * Only search router table for the head fragment, | ||
217 | * when defraging timeout at PRE_ROUTING HOOK. | ||
218 | */ | ||
219 | if (qp->user == IP_DEFRAG_CONNTRACK_IN && !skb_dst(head)) { | ||
220 | const struct iphdr *iph = ip_hdr(head); | ||
221 | int err = ip_route_input(head, iph->daddr, iph->saddr, | ||
222 | iph->tos, head->dev); | ||
223 | if (unlikely(err)) | ||
224 | goto out_rcu_unlock; | ||
225 | |||
226 | /* | ||
227 | * Only an end host needs to send an ICMP | ||
228 | * "Fragment Reassembly Timeout" message, per RFC792. | ||
229 | */ | ||
230 | if (skb_rtable(head)->rt_type != RTN_LOCAL) | ||
231 | goto out_rcu_unlock; | ||
232 | |||
233 | } | ||
234 | |||
235 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ | ||
236 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); | ||
237 | out_rcu_unlock: | ||
213 | rcu_read_unlock(); | 238 | rcu_read_unlock(); |
214 | } | 239 | } |
215 | out: | 240 | out: |
@@ -646,7 +671,7 @@ static struct ctl_table ip4_frags_ctl_table[] = { | |||
646 | { } | 671 | { } |
647 | }; | 672 | }; |
648 | 673 | ||
649 | static int ip4_frags_ns_ctl_register(struct net *net) | 674 | static int __net_init ip4_frags_ns_ctl_register(struct net *net) |
650 | { | 675 | { |
651 | struct ctl_table *table; | 676 | struct ctl_table *table; |
652 | struct ctl_table_header *hdr; | 677 | struct ctl_table_header *hdr; |
@@ -676,7 +701,7 @@ err_alloc: | |||
676 | return -ENOMEM; | 701 | return -ENOMEM; |
677 | } | 702 | } |
678 | 703 | ||
679 | static void ip4_frags_ns_ctl_unregister(struct net *net) | 704 | static void __net_exit ip4_frags_ns_ctl_unregister(struct net *net) |
680 | { | 705 | { |
681 | struct ctl_table *table; | 706 | struct ctl_table *table; |
682 | 707 | ||
@@ -704,7 +729,7 @@ static inline void ip4_frags_ctl_register(void) | |||
704 | } | 729 | } |
705 | #endif | 730 | #endif |
706 | 731 | ||
707 | static int ipv4_frags_init_net(struct net *net) | 732 | static int __net_init ipv4_frags_init_net(struct net *net) |
708 | { | 733 | { |
709 | /* | 734 | /* |
710 | * Fragment cache limits. We will commit 256K at one time. Should we | 735 | * Fragment cache limits. We will commit 256K at one time. Should we |
@@ -726,7 +751,7 @@ static int ipv4_frags_init_net(struct net *net) | |||
726 | return ip4_frags_ns_ctl_register(net); | 751 | return ip4_frags_ns_ctl_register(net); |
727 | } | 752 | } |
728 | 753 | ||
729 | static void ipv4_frags_exit_net(struct net *net) | 754 | static void __net_exit ipv4_frags_exit_net(struct net *net) |
730 | { | 755 | { |
731 | ip4_frags_ns_ctl_unregister(net); | 756 | ip4_frags_ns_ctl_unregister(net); |
732 | inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); | 757 | inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); |