aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_fragment.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-21 11:19:50 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-21 11:19:50 -0400
commiteb6a12c2428d21a9f3e0f1a50e927d5fd80fc3d0 (patch)
tree5ac6f43899648abeab1d43aad3107f664e7f13d5 /net/ipv4/ip_fragment.c
parentc4762aba0b1f72659aae9ce37b772ca8bd8f06f4 (diff)
parent14b395e35d1afdd8019d11b92e28041fad591b71 (diff)
Merge branch 'linus' into cpus4096-for-linus
Conflicts: net/sunrpc/svc.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r--net/ipv4/ip_fragment.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 37221f659159..38d38f058018 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The IP fragmentation functionality. 6 * The IP fragmentation functionality.
7 * 7 *
8 * Version: $Id: ip_fragment.c,v 1.59 2002/01/12 07:54:56 davem Exp $
9 *
10 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> 8 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
11 * Alan Cox <Alan.Cox@linux.org> 9 * Alan Cox <Alan.Cox@linux.org>
12 * 10 *
@@ -180,7 +178,7 @@ static void ip_evictor(struct net *net)
180 178
181 evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags); 179 evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
182 if (evicted) 180 if (evicted)
183 IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted); 181 IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
184} 182}
185 183
186/* 184/*
@@ -189,8 +187,10 @@ static void ip_evictor(struct net *net)
189static void ip_expire(unsigned long arg) 187static void ip_expire(unsigned long arg)
190{ 188{
191 struct ipq *qp; 189 struct ipq *qp;
190 struct net *net;
192 191
193 qp = container_of((struct inet_frag_queue *) arg, struct ipq, q); 192 qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
193 net = container_of(qp->q.net, struct net, ipv4.frags);
194 194
195 spin_lock(&qp->q.lock); 195 spin_lock(&qp->q.lock);
196 196
@@ -199,14 +199,12 @@ static void ip_expire(unsigned long arg)
199 199
200 ipq_kill(qp); 200 ipq_kill(qp);
201 201
202 IP_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT); 202 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT);
203 IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 203 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
204 204
205 if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { 205 if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) {
206 struct sk_buff *head = qp->q.fragments; 206 struct sk_buff *head = qp->q.fragments;
207 struct net *net;
208 207
209 net = container_of(qp->q.net, struct net, ipv4.frags);
210 /* Send an ICMP "Fragment Reassembly Timeout" message. */ 208 /* Send an ICMP "Fragment Reassembly Timeout" message. */
211 if ((head->dev = dev_get_by_index(net, qp->iif)) != NULL) { 209 if ((head->dev = dev_get_by_index(net, qp->iif)) != NULL) {
212 icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); 210 icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
@@ -263,7 +261,10 @@ static inline int ip_frag_too_far(struct ipq *qp)
263 rc = qp->q.fragments && (end - start) > max; 261 rc = qp->q.fragments && (end - start) > max;
264 262
265 if (rc) { 263 if (rc) {
266 IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 264 struct net *net;
265
266 net = container_of(qp->q.net, struct net, ipv4.frags);
267 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
267 } 268 }
268 269
269 return rc; 270 return rc;
@@ -547,7 +548,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
547 iph = ip_hdr(head); 548 iph = ip_hdr(head);
548 iph->frag_off = 0; 549 iph->frag_off = 0;
549 iph->tot_len = htons(len); 550 iph->tot_len = htons(len);
550 IP_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 551 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMOKS);
551 qp->q.fragments = NULL; 552 qp->q.fragments = NULL;
552 return 0; 553 return 0;
553 554
@@ -562,7 +563,7 @@ out_oversize:
562 "Oversized IP packet from " NIPQUAD_FMT ".\n", 563 "Oversized IP packet from " NIPQUAD_FMT ".\n",
563 NIPQUAD(qp->saddr)); 564 NIPQUAD(qp->saddr));
564out_fail: 565out_fail:
565 IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 566 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS);
566 return err; 567 return err;
567} 568}
568 569
@@ -572,9 +573,9 @@ int ip_defrag(struct sk_buff *skb, u32 user)
572 struct ipq *qp; 573 struct ipq *qp;
573 struct net *net; 574 struct net *net;
574 575
575 IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);
576
577 net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev); 576 net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev);
577 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
578
578 /* Start by cleaning up the memory. */ 579 /* Start by cleaning up the memory. */
579 if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh) 580 if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
580 ip_evictor(net); 581 ip_evictor(net);
@@ -592,7 +593,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
592 return ret; 593 return ret;
593 } 594 }
594 595
595 IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 596 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
596 kfree_skb(skb); 597 kfree_skb(skb);
597 return -ENOMEM; 598 return -ENOMEM;
598} 599}
@@ -600,7 +601,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
600#ifdef CONFIG_SYSCTL 601#ifdef CONFIG_SYSCTL
601static int zero; 602static int zero;
602 603
603static struct ctl_table ip4_frags_ctl_table[] = { 604static struct ctl_table ip4_frags_ns_ctl_table[] = {
604 { 605 {
605 .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, 606 .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH,
606 .procname = "ipfrag_high_thresh", 607 .procname = "ipfrag_high_thresh",
@@ -626,6 +627,10 @@ static struct ctl_table ip4_frags_ctl_table[] = {
626 .proc_handler = &proc_dointvec_jiffies, 627 .proc_handler = &proc_dointvec_jiffies,
627 .strategy = &sysctl_jiffies 628 .strategy = &sysctl_jiffies
628 }, 629 },
630 { }
631};
632
633static struct ctl_table ip4_frags_ctl_table[] = {
629 { 634 {
630 .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, 635 .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL,
631 .procname = "ipfrag_secret_interval", 636 .procname = "ipfrag_secret_interval",
@@ -646,22 +651,20 @@ static struct ctl_table ip4_frags_ctl_table[] = {
646 { } 651 { }
647}; 652};
648 653
649static int ip4_frags_ctl_register(struct net *net) 654static int ip4_frags_ns_ctl_register(struct net *net)
650{ 655{
651 struct ctl_table *table; 656 struct ctl_table *table;
652 struct ctl_table_header *hdr; 657 struct ctl_table_header *hdr;
653 658
654 table = ip4_frags_ctl_table; 659 table = ip4_frags_ns_ctl_table;
655 if (net != &init_net) { 660 if (net != &init_net) {
656 table = kmemdup(table, sizeof(ip4_frags_ctl_table), GFP_KERNEL); 661 table = kmemdup(table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL);
657 if (table == NULL) 662 if (table == NULL)
658 goto err_alloc; 663 goto err_alloc;
659 664
660 table[0].data = &net->ipv4.frags.high_thresh; 665 table[0].data = &net->ipv4.frags.high_thresh;
661 table[1].data = &net->ipv4.frags.low_thresh; 666 table[1].data = &net->ipv4.frags.low_thresh;
662 table[2].data = &net->ipv4.frags.timeout; 667 table[2].data = &net->ipv4.frags.timeout;
663 table[3].mode &= ~0222;
664 table[4].mode &= ~0222;
665 } 668 }
666 669
667 hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table); 670 hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table);
@@ -678,7 +681,7 @@ err_alloc:
678 return -ENOMEM; 681 return -ENOMEM;
679} 682}
680 683
681static void ip4_frags_ctl_unregister(struct net *net) 684static void ip4_frags_ns_ctl_unregister(struct net *net)
682{ 685{
683 struct ctl_table *table; 686 struct ctl_table *table;
684 687
@@ -686,13 +689,22 @@ static void ip4_frags_ctl_unregister(struct net *net)
686 unregister_net_sysctl_table(net->ipv4.frags_hdr); 689 unregister_net_sysctl_table(net->ipv4.frags_hdr);
687 kfree(table); 690 kfree(table);
688} 691}
692
693static void ip4_frags_ctl_register(void)
694{
695 register_net_sysctl_rotable(net_ipv4_ctl_path, ip4_frags_ctl_table);
696}
689#else 697#else
690static inline int ip4_frags_ctl_register(struct net *net) 698static inline int ip4_frags_ns_ctl_register(struct net *net)
691{ 699{
692 return 0; 700 return 0;
693} 701}
694 702
695static inline void ip4_frags_ctl_unregister(struct net *net) 703static inline void ip4_frags_ns_ctl_unregister(struct net *net)
704{
705}
706
707static inline void ip4_frags_ctl_register(void)
696{ 708{
697} 709}
698#endif 710#endif
@@ -716,12 +728,12 @@ static int ipv4_frags_init_net(struct net *net)
716 728
717 inet_frags_init_net(&net->ipv4.frags); 729 inet_frags_init_net(&net->ipv4.frags);
718 730
719 return ip4_frags_ctl_register(net); 731 return ip4_frags_ns_ctl_register(net);
720} 732}
721 733
722static void ipv4_frags_exit_net(struct net *net) 734static void ipv4_frags_exit_net(struct net *net)
723{ 735{
724 ip4_frags_ctl_unregister(net); 736 ip4_frags_ns_ctl_unregister(net);
725 inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); 737 inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
726} 738}
727 739
@@ -732,6 +744,7 @@ static struct pernet_operations ip4_frags_ops = {
732 744
733void __init ipfrag_init(void) 745void __init ipfrag_init(void)
734{ 746{
747 ip4_frags_ctl_register();
735 register_pernet_subsys(&ip4_frags_ops); 748 register_pernet_subsys(&ip4_frags_ops);
736 ip4_frags.hashfn = ip4_hashfn; 749 ip4_frags.hashfn = ip4_hashfn;
737 ip4_frags.constructor = ip4_frag_init; 750 ip4_frags.constructor = ip4_frag_init;