diff options
-rw-r--r-- | include/net/inet_frag.h | 4 | ||||
-rw-r--r-- | net/ipv4/inet_fragment.c | 2 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 26 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 12 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 15 |
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 | ||
12 | struct inet_frag_queue { | 14 | struct inet_frag_queue { |
@@ -30,8 +32,6 @@ struct inet_frag_queue { | |||
30 | #define INETFRAGS_HASHSZ 64 | 32 | #define INETFRAGS_HASHSZ 64 |
31 | 33 | ||
32 | struct inet_frags_ctl { | 34 | struct 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 | ||
77 | static struct inet_frags_ctl ip4_frags_ctl __read_mostly = { | 77 | static 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) | |||
706 | static int ipv4_frags_init_net(struct net *net) | 698 | static 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 | ||
73 | static struct inet_frags_ctl nf_frags_ctl __read_mostly = { | 73 | static 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 | ||