diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ip_fragment.c | 47 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 9 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 7 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 29 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 25 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 9 |
6 files changed, 68 insertions, 58 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 321e694b72e..0dd9a31df21 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -50,21 +50,8 @@ * as well. Or notify me, at least. --ANK */ -/* Fragment cache limits. We will commit 256K at one time. Should we - * cross that limit we will prune down to 192K. This should cope with - * even the most extreme cases without allowing an attacker to measurably - * harm machine performance. - */ -int sysctl_ipfrag_high_thresh __read_mostly = 256*1024; -int sysctl_ipfrag_low_thresh __read_mostly = 192*1024; - int sysctl_ipfrag_max_dist __read_mostly = 64; -/* Important NOTE! Fragment queue must be destroyed before MSL expires. - * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL. - */ -int sysctl_ipfrag_time __read_mostly = IP_FRAG_TIME; - struct ipfrag_skb_cb { struct inet_skb_parm h; @@ -87,6 +74,25 @@ struct ipq { struct inet_peer *peer; }; +struct inet_frags_ctl ip4_frags_ctl __read_mostly = { + /* + * Fragment cache limits. We will commit 256K at one time. Should we + * cross that limit we will prune down to 192K. This should cope with + * even the most extreme cases without allowing an attacker to + * measurably harm machine performance. + */ + .high_thresh = 256 * 1024, + .low_thresh = 192 * 1024, + + /* + * Important NOTE! Fragment queue must be destroyed before MSL expires. + * RFC791 is wrong proposing to prolongate timer each fragment arrival + * by TTL. + */ + .timeout = IP_FRAG_TIME, + .secret_interval = 10 * 60 * HZ, +}; + static struct inet_frags ip4_frags; int ip_frag_nqueues(void) @@ -123,8 +129,6 @@ static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) ip4_frags.rnd) & (INETFRAGS_HASHSZ - 1); } -int sysctl_ipfrag_secret_interval __read_mostly = 10 * 60 * HZ; - static void ipfrag_secret_rebuild(unsigned long dummy) { unsigned long now = jiffies; @@ -150,7 +154,7 @@ static void ipfrag_secret_rebuild(unsigned long dummy) } write_unlock(&ip4_frags.lock); - mod_timer(&ip4_frags.secret_timer, now + sysctl_ipfrag_secret_interval); + mod_timer(&ip4_frags.secret_timer, now + ip4_frags_ctl.secret_interval); } /* Memory Tracking Functions. */ @@ -237,7 +241,7 @@ static void ip_evictor(void) struct list_head *tmp; int work; - work = atomic_read(&ip4_frags.mem) - sysctl_ipfrag_low_thresh; + work = atomic_read(&ip4_frags.mem) - ip4_frags_ctl.low_thresh; if (work <= 0) return; @@ -326,7 +330,7 @@ static struct ipq *ip_frag_intern(struct ipq *qp_in) #endif qp = qp_in; - if (!mod_timer(&qp->q.timer, jiffies + sysctl_ipfrag_time)) + if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout)) atomic_inc(&qp->q.refcnt); atomic_inc(&qp->q.refcnt); @@ -432,7 +436,7 @@ static int ip_frag_reinit(struct ipq *qp) { struct sk_buff *fp; - if (!mod_timer(&qp->q.timer, jiffies + sysctl_ipfrag_time)) { + if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout)) { atomic_inc(&qp->q.refcnt); return -ETIMEDOUT; } @@ -733,7 +737,7 @@ int ip_defrag(struct sk_buff *skb, u32 user) IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS); /* Start by cleaning up the memory. */ - if (atomic_read(&ip4_frags.mem) > sysctl_ipfrag_high_thresh) + if (atomic_read(&ip4_frags.mem) > ip4_frags_ctl.high_thresh) ip_evictor(); /* Lookup (or create) queue header */ @@ -758,9 +762,10 @@ void __init ipfrag_init(void) { init_timer(&ip4_frags.secret_timer); ip4_frags.secret_timer.function = ipfrag_secret_rebuild; - ip4_frags.secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval; + ip4_frags.secret_timer.expires = jiffies + ip4_frags_ctl.secret_interval; add_timer(&ip4_frags.secret_timer); + ip4_frags.ctl = &ip4_frags_ctl; inet_frags_init(&ip4_frags); } diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index eb286abcf5d..c98ef16effd 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -19,6 +19,7 @@ #include <net/route.h> #include <net/tcp.h> #include <net/cipso_ipv4.h> +#include <net/inet_frag.h> /* From af_inet.c */ extern int sysctl_ip_nonlocal_bind; @@ -357,7 +358,7 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, .procname = "ipfrag_high_thresh", - .data = &sysctl_ipfrag_high_thresh, + .data = &ip4_frags_ctl.high_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -365,7 +366,7 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH, .procname = "ipfrag_low_thresh", - .data = &sysctl_ipfrag_low_thresh, + .data = &ip4_frags_ctl.low_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -381,7 +382,7 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_IPV4_IPFRAG_TIME, .procname = "ipfrag_time", - .data = &sysctl_ipfrag_time, + .data = &ip4_frags_ctl.timeout, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -732,7 +733,7 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, .procname = "ipfrag_secret_interval", - .data = &sysctl_ipfrag_secret_interval, + .data = &ip4_frags_ctl.secret_interval, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index e9369dc0238..0e40948f4fc 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -18,6 +18,7 @@ #include <linux/icmp.h> #include <linux/sysctl.h> #include <net/ipv6.h> +#include <net/inet_frag.h> #include <linux/netfilter_ipv6.h> #include <net/netfilter/nf_conntrack.h> @@ -307,7 +308,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = { { .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT, .procname = "nf_conntrack_frag6_timeout", - .data = &nf_ct_frag6_timeout, + .data = &nf_frags_ctl.timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -315,7 +316,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = { { .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH, .procname = "nf_conntrack_frag6_low_thresh", - .data = &nf_ct_frag6_low_thresh, + .data = &nf_frags_ctl.low_thresh, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec, @@ -323,7 +324,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = { { .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, .procname = "nf_conntrack_frag6_high_thresh", - .data = &nf_ct_frag6_high_thresh, + .data = &nf_frags_ctl.high_thresh, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec, diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index eb2ca1b7dda..966a8884840 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -49,10 +49,6 @@ #define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */ #define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT -unsigned int nf_ct_frag6_high_thresh __read_mostly = 256*1024; -unsigned int nf_ct_frag6_low_thresh __read_mostly = 192*1024; -unsigned long nf_ct_frag6_timeout __read_mostly = IPV6_FRAG_TIMEOUT; - struct nf_ct_frag6_skb_cb { struct inet6_skb_parm h; @@ -74,6 +70,13 @@ struct nf_ct_frag6_queue __u16 nhoffset; }; +struct inet_frags_ctl nf_frags_ctl __read_mostly = { + .high_thresh = 256 * 1024, + .low_thresh = 192 * 1024, + .timeout = IPV6_FRAG_TIMEOUT, + .secret_interval = 10 * 60 * HZ, +}; + static struct inet_frags nf_frags; static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) @@ -117,8 +120,6 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, return c & (INETFRAGS_HASHSZ - 1); } -int nf_ct_frag6_secret_interval = 10 * 60 * HZ; - static void nf_ct_frag6_secret_rebuild(unsigned long dummy) { unsigned long now = jiffies; @@ -144,7 +145,7 @@ static void nf_ct_frag6_secret_rebuild(unsigned long dummy) } write_unlock(&nf_frags.lock); - mod_timer(&nf_frags.secret_timer, now + nf_ct_frag6_secret_interval); + mod_timer(&nf_frags.secret_timer, now + nf_frags_ctl.secret_interval); } /* Memory Tracking Functions. */ @@ -229,10 +230,10 @@ static void nf_ct_frag6_evictor(void) unsigned int work; work = atomic_read(&nf_frags.mem); - if (work <= nf_ct_frag6_low_thresh) + if (work <= nf_frags_ctl.low_thresh) return; - work -= nf_ct_frag6_low_thresh; + work -= nf_frags_ctl.low_thresh; while (work > 0) { read_lock(&nf_frags.lock); if (list_empty(&nf_frags.lru_list)) { @@ -296,7 +297,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, #endif fq = fq_in; - if (!mod_timer(&fq->q.timer, jiffies + nf_ct_frag6_timeout)) + if (!mod_timer(&fq->q.timer, jiffies + nf_frags_ctl.timeout)) atomic_inc(&fq->q.refcnt); atomic_inc(&fq->q.refcnt); @@ -766,7 +767,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) goto ret_orig; } - if (atomic_read(&nf_frags.mem) > nf_ct_frag6_high_thresh) + if (atomic_read(&nf_frags.mem) > nf_frags_ctl.high_thresh) nf_ct_frag6_evictor(); fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); @@ -838,10 +839,10 @@ int nf_ct_frag6_kfree_frags(struct sk_buff *skb) int nf_ct_frag6_init(void) { setup_timer(&nf_frags.secret_timer, nf_ct_frag6_secret_rebuild, 0); - nf_frags.secret_timer.expires = jiffies - + nf_ct_frag6_secret_interval; + nf_frags.secret_timer.expires = jiffies + nf_frags_ctl.secret_interval; add_timer(&nf_frags.secret_timer); + nf_frags.ctl = &nf_frags_ctl; inet_frags_init(&nf_frags); return 0; @@ -852,6 +853,6 @@ void nf_ct_frag6_cleanup(void) inet_frags_fini(&nf_frags); del_timer(&nf_frags.secret_timer); - nf_ct_frag6_low_thresh = 0; + nf_frags_ctl.low_thresh = 0; nf_ct_frag6_evictor(); } diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index ecf340047cd..ced1a5f5b77 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -56,11 +56,6 @@ #include <net/addrconf.h> #include <net/inet_frag.h> -int sysctl_ip6frag_high_thresh __read_mostly = 256*1024; -int sysctl_ip6frag_low_thresh __read_mostly = 192*1024; - -int sysctl_ip6frag_time __read_mostly = IPV6_FRAG_TIMEOUT; - struct ip6frag_skb_cb { struct inet6_skb_parm h; @@ -87,6 +82,13 @@ struct frag_queue __u16 nhoffset; }; +struct inet_frags_ctl ip6_frags_ctl __read_mostly = { + .high_thresh = 256 * 1024, + .low_thresh = 192 * 1024, + .timeout = IPV6_FRAG_TIMEOUT, + .secret_interval = 10 * 60 * HZ, +}; + static struct inet_frags ip6_frags; int ip6_frag_nqueues(void) @@ -147,8 +149,6 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, return c & (INETFRAGS_HASHSZ - 1); } -int sysctl_ip6frag_secret_interval __read_mostly = 10 * 60 * HZ; - static void ip6_frag_secret_rebuild(unsigned long dummy) { unsigned long now = jiffies; @@ -177,7 +177,7 @@ static void ip6_frag_secret_rebuild(unsigned long dummy) } write_unlock(&ip6_frags.lock); - mod_timer(&ip6_frags.secret_timer, now + sysctl_ip6frag_secret_interval); + mod_timer(&ip6_frags.secret_timer, now + ip6_frags_ctl.secret_interval); } /* Memory Tracking Functions. */ @@ -256,7 +256,7 @@ static void ip6_evictor(struct inet6_dev *idev) struct list_head *tmp; int work; - work = atomic_read(&ip6_frags.mem) - sysctl_ip6frag_low_thresh; + work = atomic_read(&ip6_frags.mem) - ip6_frags_ctl.low_thresh; if (work <= 0) return; @@ -348,7 +348,7 @@ static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in) #endif fq = fq_in; - if (!mod_timer(&fq->q.timer, jiffies + sysctl_ip6frag_time)) + if (!mod_timer(&fq->q.timer, jiffies + ip6_frags_ctl.timeout)) atomic_inc(&fq->q.refcnt); atomic_inc(&fq->q.refcnt); @@ -754,7 +754,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp) return 1; } - if (atomic_read(&ip6_frags.mem) > sysctl_ip6frag_high_thresh) + if (atomic_read(&ip6_frags.mem) > ip6_frags_ctl.high_thresh) ip6_evictor(ip6_dst_idev(skb->dst)); if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr, @@ -788,8 +788,9 @@ void __init ipv6_frag_init(void) init_timer(&ip6_frags.secret_timer); ip6_frags.secret_timer.function = ip6_frag_secret_rebuild; - ip6_frags.secret_timer.expires = jiffies + sysctl_ip6frag_secret_interval; + ip6_frags.secret_timer.expires = jiffies + ip6_frags_ctl.secret_interval; add_timer(&ip6_frags.secret_timer); + ip6_frags.ctl = &ip6_frags_ctl; inet_frags_init(&ip6_frags); } diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 3fb44277207..68bb2548e46 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -12,6 +12,7 @@ #include <net/ndisc.h> #include <net/ipv6.h> #include <net/addrconf.h> +#include <net/inet_frag.h> #ifdef CONFIG_SYSCTL @@ -41,7 +42,7 @@ static ctl_table ipv6_table[] = { { .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, .procname = "ip6frag_high_thresh", - .data = &sysctl_ip6frag_high_thresh, + .data = &ip6_frags_ctl.high_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -49,7 +50,7 @@ static ctl_table ipv6_table[] = { { .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, .procname = "ip6frag_low_thresh", - .data = &sysctl_ip6frag_low_thresh, + .data = &ip6_frags_ctl.low_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -57,7 +58,7 @@ static ctl_table ipv6_table[] = { { .ctl_name = NET_IPV6_IP6FRAG_TIME, .procname = "ip6frag_time", - .data = &sysctl_ip6frag_time, + .data = &ip6_frags_ctl.timeout, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -66,7 +67,7 @@ static ctl_table ipv6_table[] = { { .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, .procname = "ip6frag_secret_interval", - .data = &sysctl_ip6frag_secret_interval, + .data = &ip6_frags_ctl.secret_interval, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, |