aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_frag.h4
-rw-r--r--net/ipv4/inet_fragment.c2
-rw-r--r--net/ipv4/ip_fragment.c26
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c12
-rw-r--r--net/ipv6/reassembly.c15
5 files changed, 29 insertions, 30 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index f56e296e6227..de4135925490 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -7,6 +7,8 @@ struct netns_frags {
7 7
8 /* sysctls */ 8 /* sysctls */
9 int timeout; 9 int timeout;
10 int high_thresh;
11 int low_thresh;
10}; 12};
11 13
12struct inet_frag_queue { 14struct inet_frag_queue {
@@ -30,8 +32,6 @@ struct inet_frag_queue {
30#define INETFRAGS_HASHSZ 64 32#define INETFRAGS_HASHSZ 64
31 33
32struct inet_frags_ctl { 34struct inet_frags_ctl {
33 int high_thresh;
34 int low_thresh;
35 int secret_interval; 35 int secret_interval;
36}; 36};
37 37
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 9da96792fffb..5ab399c15282 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -153,7 +153,7 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f)
153 struct inet_frag_queue *q; 153 struct inet_frag_queue *q;
154 int work, evicted = 0; 154 int work, evicted = 0;
155 155
156 work = atomic_read(&nf->mem) - f->ctl->low_thresh; 156 work = atomic_read(&nf->mem) - nf->low_thresh;
157 while (work > 0) { 157 while (work > 0) {
158 read_lock(&f->lock); 158 read_lock(&f->lock);
159 if (list_empty(&f->lru_list)) { 159 if (list_empty(&f->lru_list)) {
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 70d241c8d2a8..80c2c19196cd 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -75,14 +75,6 @@ struct ipq {
75}; 75};
76 76
77static struct inet_frags_ctl ip4_frags_ctl __read_mostly = { 77static struct inet_frags_ctl ip4_frags_ctl __read_mostly = {
78 /*
79 * Fragment cache limits. We will commit 256K at one time. Should we
80 * cross that limit we will prune down to 192K. This should cope with
81 * even the most extreme cases without allowing an attacker to
82 * measurably harm machine performance.
83 */
84 .high_thresh = 256 * 1024,
85 .low_thresh = 192 * 1024,
86 .secret_interval = 10 * 60 * HZ, 78 .secret_interval = 10 * 60 * HZ,
87}; 79};
88 80
@@ -582,7 +574,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
582 574
583 net = skb->dev->nd_net; 575 net = skb->dev->nd_net;
584 /* Start by cleaning up the memory. */ 576 /* Start by cleaning up the memory. */
585 if (atomic_read(&net->ipv4.frags.mem) > ip4_frags_ctl.high_thresh) 577 if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
586 ip_evictor(net); 578 ip_evictor(net);
587 579
588 /* Lookup (or create) queue header */ 580 /* Lookup (or create) queue header */
@@ -610,7 +602,7 @@ static struct ctl_table ip4_frags_ctl_table[] = {
610 { 602 {
611 .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, 603 .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH,
612 .procname = "ipfrag_high_thresh", 604 .procname = "ipfrag_high_thresh",
613 .data = &ip4_frags_ctl.high_thresh, 605 .data = &init_net.ipv4.frags.high_thresh,
614 .maxlen = sizeof(int), 606 .maxlen = sizeof(int),
615 .mode = 0644, 607 .mode = 0644,
616 .proc_handler = &proc_dointvec 608 .proc_handler = &proc_dointvec
@@ -618,7 +610,7 @@ static struct ctl_table ip4_frags_ctl_table[] = {
618 { 610 {
619 .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH, 611 .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH,
620 .procname = "ipfrag_low_thresh", 612 .procname = "ipfrag_low_thresh",
621 .data = &ip4_frags_ctl.low_thresh, 613 .data = &init_net.ipv4.frags.low_thresh,
622 .maxlen = sizeof(int), 614 .maxlen = sizeof(int),
623 .mode = 0644, 615 .mode = 0644,
624 .proc_handler = &proc_dointvec 616 .proc_handler = &proc_dointvec
@@ -663,8 +655,8 @@ static int ip4_frags_ctl_register(struct net *net)
663 if (table == NULL) 655 if (table == NULL)
664 goto err_alloc; 656 goto err_alloc;
665 657
666 table[0].mode &= ~0222; 658 table[0].data = &net->ipv4.frags.high_thresh;
667 table[1].mode &= ~0222; 659 table[1].data = &net->ipv4.frags.low_thresh;
668 table[2].data = &net->ipv4.frags.timeout; 660 table[2].data = &net->ipv4.frags.timeout;
669 table[3].mode &= ~0222; 661 table[3].mode &= ~0222;
670 table[4].mode &= ~0222; 662 table[4].mode &= ~0222;
@@ -706,6 +698,14 @@ static inline void ip4_frags_ctl_unregister(struct net *net)
706static int ipv4_frags_init_net(struct net *net) 698static int ipv4_frags_init_net(struct net *net)
707{ 699{
708 /* 700 /*
701 * Fragment cache limits. We will commit 256K at one time. Should we
702 * cross that limit we will prune down to 192K. This should cope with
703 * even the most extreme cases without allowing an attacker to
704 * measurably harm machine performance.
705 */
706 net->ipv4.frags.high_thresh = 256 * 1024;
707 net->ipv4.frags.low_thresh = 192 * 1024;
708 /*
709 * Important NOTE! Fragment queue must be destroyed before MSL expires. 709 * Important NOTE! Fragment queue must be destroyed before MSL expires.
710 * RFC791 is wrong proposing to prolongate timer each fragment arrival 710 * RFC791 is wrong proposing to prolongate timer each fragment arrival
711 * by TTL. 711 * by TTL.
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 92a311ff79c7..c75ac17e3945 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -71,8 +71,6 @@ struct nf_ct_frag6_queue
71}; 71};
72 72
73static struct inet_frags_ctl nf_frags_ctl __read_mostly = { 73static struct inet_frags_ctl nf_frags_ctl __read_mostly = {
74 .high_thresh = 256 * 1024,
75 .low_thresh = 192 * 1024,
76 .secret_interval = 10 * 60 * HZ, 74 .secret_interval = 10 * 60 * HZ,
77}; 75};
78 76
@@ -91,7 +89,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
91 { 89 {
92 .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH, 90 .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
93 .procname = "nf_conntrack_frag6_low_thresh", 91 .procname = "nf_conntrack_frag6_low_thresh",
94 .data = &nf_frags_ctl.low_thresh, 92 .data = &nf_init_frags.low_thresh,
95 .maxlen = sizeof(unsigned int), 93 .maxlen = sizeof(unsigned int),
96 .mode = 0644, 94 .mode = 0644,
97 .proc_handler = &proc_dointvec, 95 .proc_handler = &proc_dointvec,
@@ -99,7 +97,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
99 { 97 {
100 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, 98 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
101 .procname = "nf_conntrack_frag6_high_thresh", 99 .procname = "nf_conntrack_frag6_high_thresh",
102 .data = &nf_frags_ctl.high_thresh, 100 .data = &nf_init_frags.high_thresh,
103 .maxlen = sizeof(unsigned int), 101 .maxlen = sizeof(unsigned int),
104 .mode = 0644, 102 .mode = 0644,
105 .proc_handler = &proc_dointvec, 103 .proc_handler = &proc_dointvec,
@@ -632,7 +630,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
632 goto ret_orig; 630 goto ret_orig;
633 } 631 }
634 632
635 if (atomic_read(&nf_init_frags.mem) > nf_frags_ctl.high_thresh) 633 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
636 nf_ct_frag6_evictor(); 634 nf_ct_frag6_evictor();
637 635
638 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); 636 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
@@ -712,6 +710,8 @@ int nf_ct_frag6_init(void)
712 nf_frags.match = ip6_frag_match; 710 nf_frags.match = ip6_frag_match;
713 nf_frags.frag_expire = nf_ct_frag6_expire; 711 nf_frags.frag_expire = nf_ct_frag6_expire;
714 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT; 712 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
713 nf_init_frags.high_thresh = 256 * 1024;
714 nf_init_frags.low_thresh = 192 * 1024;
715 inet_frags_init_net(&nf_init_frags); 715 inet_frags_init_net(&nf_init_frags);
716 inet_frags_init(&nf_frags); 716 inet_frags_init(&nf_frags);
717 717
@@ -722,6 +722,6 @@ void nf_ct_frag6_cleanup(void)
722{ 722{
723 inet_frags_fini(&nf_frags); 723 inet_frags_fini(&nf_frags);
724 724
725 nf_frags_ctl.low_thresh = 0; 725 nf_init_frags.low_thresh = 0;
726 nf_ct_frag6_evictor(); 726 nf_ct_frag6_evictor();
727} 727}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 91761365b181..85f3fa382230 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -601,8 +601,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
601 } 601 }
602 602
603 net = skb->dev->nd_net; 603 net = skb->dev->nd_net;
604 if (atomic_read(&net->ipv6.frags.mem) > 604 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
605 init_net.ipv6.sysctl.frags.high_thresh)
606 ip6_evictor(net, ip6_dst_idev(skb->dst)); 605 ip6_evictor(net, ip6_dst_idev(skb->dst));
607 606
608 if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, 607 if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
@@ -634,7 +633,7 @@ static struct ctl_table ip6_frags_ctl_table[] = {
634 { 633 {
635 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, 634 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
636 .procname = "ip6frag_high_thresh", 635 .procname = "ip6frag_high_thresh",
637 .data = &init_net.ipv6.sysctl.frags.high_thresh, 636 .data = &init_net.ipv6.frags.high_thresh,
638 .maxlen = sizeof(int), 637 .maxlen = sizeof(int),
639 .mode = 0644, 638 .mode = 0644,
640 .proc_handler = &proc_dointvec 639 .proc_handler = &proc_dointvec
@@ -642,7 +641,7 @@ static struct ctl_table ip6_frags_ctl_table[] = {
642 { 641 {
643 .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, 642 .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH,
644 .procname = "ip6frag_low_thresh", 643 .procname = "ip6frag_low_thresh",
645 .data = &init_net.ipv6.sysctl.frags.low_thresh, 644 .data = &init_net.ipv6.frags.low_thresh,
646 .maxlen = sizeof(int), 645 .maxlen = sizeof(int),
647 .mode = 0644, 646 .mode = 0644,
648 .proc_handler = &proc_dointvec 647 .proc_handler = &proc_dointvec
@@ -679,8 +678,8 @@ static int ip6_frags_sysctl_register(struct net *net)
679 if (table == NULL) 678 if (table == NULL)
680 goto err_alloc; 679 goto err_alloc;
681 680
682 table[0].mode &= ~0222; 681 table[0].data = &net->ipv6.frags.high_thresh;
683 table[1].mode &= ~0222; 682 table[1].data = &net->ipv6.frags.low_thresh;
684 table[2].data = &net->ipv6.frags.timeout; 683 table[2].data = &net->ipv6.frags.timeout;
685 table[3].mode &= ~0222; 684 table[3].mode &= ~0222;
686 } 685 }
@@ -722,8 +721,8 @@ static int ipv6_frags_init_net(struct net *net)
722{ 721{
723 ip6_frags.ctl = &net->ipv6.sysctl.frags; 722 ip6_frags.ctl = &net->ipv6.sysctl.frags;
724 723
725 net->ipv6.sysctl.frags.high_thresh = 256 * 1024; 724 net->ipv6.frags.high_thresh = 256 * 1024;
726 net->ipv6.sysctl.frags.low_thresh = 192 * 1024; 725 net->ipv6.frags.low_thresh = 192 * 1024;
727 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; 726 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
728 net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; 727 net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ;
729 728