diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2013-01-05 11:10:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-07 00:09:56 -0500 |
commit | 5d134f1c1f36166e8a738de92c4d2f4c262ff91b (patch) | |
tree | 6d1504359c7f1ade1c79da0e468a2a409af5c56c /net | |
parent | 71bcdba06db91ceaaffe019b6c958b5faf06012a (diff) |
tcp: make sysctl_tcp_ecn namespace aware
As per suggestion from Eric Dumazet this patch makes tcp_ecn sysctl
namespace aware. The reason behind this patch is to ease the testing
of ecn problems on the internet and allows applications to tune their
own use of ecn.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/syncookies.c | 7 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 16 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 2 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 2 |
7 files changed, 18 insertions, 16 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b236ef04914f..ef54377fb11c 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -232,7 +232,8 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, | |||
232 | * | 232 | * |
233 | * return false if we decode an option that should not be. | 233 | * return false if we decode an option that should not be. |
234 | */ | 234 | */ |
235 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok) | 235 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, |
236 | struct net *net, bool *ecn_ok) | ||
236 | { | 237 | { |
237 | /* echoed timestamp, lowest bits contain options */ | 238 | /* echoed timestamp, lowest bits contain options */ |
238 | u32 options = tcp_opt->rcv_tsecr & TSMASK; | 239 | u32 options = tcp_opt->rcv_tsecr & TSMASK; |
@@ -247,7 +248,7 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok) | |||
247 | 248 | ||
248 | tcp_opt->sack_ok = (options & (1 << 4)) ? TCP_SACK_SEEN : 0; | 249 | tcp_opt->sack_ok = (options & (1 << 4)) ? TCP_SACK_SEEN : 0; |
249 | *ecn_ok = (options >> 5) & 1; | 250 | *ecn_ok = (options >> 5) & 1; |
250 | if (*ecn_ok && !sysctl_tcp_ecn) | 251 | if (*ecn_ok && !net->ipv4.sysctl_tcp_ecn) |
251 | return false; | 252 | return false; |
252 | 253 | ||
253 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) | 254 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) |
@@ -295,7 +296,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
295 | memset(&tcp_opt, 0, sizeof(tcp_opt)); | 296 | memset(&tcp_opt, 0, sizeof(tcp_opt)); |
296 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); | 297 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); |
297 | 298 | ||
298 | if (!cookie_check_timestamp(&tcp_opt, &ecn_ok)) | 299 | if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) |
299 | goto out; | 300 | goto out; |
300 | 301 | ||
301 | ret = NULL; | 302 | ret = NULL; |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 7547a6d238a2..a25e1d286b99 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -538,13 +538,6 @@ static struct ctl_table ipv4_table[] = { | |||
538 | .proc_handler = proc_dointvec | 538 | .proc_handler = proc_dointvec |
539 | }, | 539 | }, |
540 | { | 540 | { |
541 | .procname = "tcp_ecn", | ||
542 | .data = &sysctl_tcp_ecn, | ||
543 | .maxlen = sizeof(int), | ||
544 | .mode = 0644, | ||
545 | .proc_handler = proc_dointvec | ||
546 | }, | ||
547 | { | ||
548 | .procname = "tcp_dsack", | 541 | .procname = "tcp_dsack", |
549 | .data = &sysctl_tcp_dsack, | 542 | .data = &sysctl_tcp_dsack, |
550 | .maxlen = sizeof(int), | 543 | .maxlen = sizeof(int), |
@@ -850,6 +843,13 @@ static struct ctl_table ipv4_net_table[] = { | |||
850 | .proc_handler = ipv4_ping_group_range, | 843 | .proc_handler = ipv4_ping_group_range, |
851 | }, | 844 | }, |
852 | { | 845 | { |
846 | .procname = "tcp_ecn", | ||
847 | .data = &init_net.ipv4.sysctl_tcp_ecn, | ||
848 | .maxlen = sizeof(int), | ||
849 | .mode = 0644, | ||
850 | .proc_handler = proc_dointvec | ||
851 | }, | ||
852 | { | ||
853 | .procname = "tcp_mem", | 853 | .procname = "tcp_mem", |
854 | .maxlen = sizeof(init_net.ipv4.sysctl_tcp_mem), | 854 | .maxlen = sizeof(init_net.ipv4.sysctl_tcp_mem), |
855 | .mode = 0644, | 855 | .mode = 0644, |
@@ -882,6 +882,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) | |||
882 | &net->ipv4.sysctl_icmp_ratemask; | 882 | &net->ipv4.sysctl_icmp_ratemask; |
883 | table[6].data = | 883 | table[6].data = |
884 | &net->ipv4.sysctl_ping_group_range; | 884 | &net->ipv4.sysctl_ping_group_range; |
885 | table[7].data = | ||
886 | &net->ipv4.sysctl_tcp_ecn; | ||
885 | 887 | ||
886 | /* Don't export sysctls to unprivileged users */ | 888 | /* Don't export sysctls to unprivileged users */ |
887 | if (net->user_ns != &init_user_ns) | 889 | if (net->user_ns != &init_user_ns) |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a28e4db8a952..38e11841be09 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -81,8 +81,6 @@ int sysctl_tcp_sack __read_mostly = 1; | |||
81 | int sysctl_tcp_fack __read_mostly = 1; | 81 | int sysctl_tcp_fack __read_mostly = 1; |
82 | int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; | 82 | int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; |
83 | EXPORT_SYMBOL(sysctl_tcp_reordering); | 83 | EXPORT_SYMBOL(sysctl_tcp_reordering); |
84 | int sysctl_tcp_ecn __read_mostly = 2; | ||
85 | EXPORT_SYMBOL(sysctl_tcp_ecn); | ||
86 | int sysctl_tcp_dsack __read_mostly = 1; | 84 | int sysctl_tcp_dsack __read_mostly = 1; |
87 | int sysctl_tcp_app_win __read_mostly = 31; | 85 | int sysctl_tcp_app_win __read_mostly = 31; |
88 | int sysctl_tcp_adv_win_scale __read_mostly = 1; | 86 | int sysctl_tcp_adv_win_scale __read_mostly = 1; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 54139fa514e6..c6ce9ca98d23 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1568,7 +1568,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1568 | goto drop_and_free; | 1568 | goto drop_and_free; |
1569 | 1569 | ||
1570 | if (!want_cookie || tmp_opt.tstamp_ok) | 1570 | if (!want_cookie || tmp_opt.tstamp_ok) |
1571 | TCP_ECN_create_request(req, skb); | 1571 | TCP_ECN_create_request(req, skb, sock_net(sk)); |
1572 | 1572 | ||
1573 | if (want_cookie) { | 1573 | if (want_cookie) { |
1574 | isn = cookie_v4_init_sequence(sk, skb, &req->mss); | 1574 | isn = cookie_v4_init_sequence(sk, skb, &req->mss); |
@@ -2888,6 +2888,7 @@ EXPORT_SYMBOL(tcp_prot); | |||
2888 | 2888 | ||
2889 | static int __net_init tcp_sk_init(struct net *net) | 2889 | static int __net_init tcp_sk_init(struct net *net) |
2890 | { | 2890 | { |
2891 | net->ipv4.sysctl_tcp_ecn = 2; | ||
2891 | return 0; | 2892 | return 0; |
2892 | } | 2893 | } |
2893 | 2894 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5d451593ef16..667a6adfccf8 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -314,7 +314,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb) | |||
314 | struct tcp_sock *tp = tcp_sk(sk); | 314 | struct tcp_sock *tp = tcp_sk(sk); |
315 | 315 | ||
316 | tp->ecn_flags = 0; | 316 | tp->ecn_flags = 0; |
317 | if (sysctl_tcp_ecn == 1) { | 317 | if (sock_net(sk)->ipv4.sysctl_tcp_ecn == 1) { |
318 | TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; | 318 | TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; |
319 | tp->ecn_flags = TCP_ECN_OK; | 319 | tp->ecn_flags = TCP_ECN_OK; |
320 | } | 320 | } |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 40161977f7cf..8a0848b60b35 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -179,7 +179,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
179 | memset(&tcp_opt, 0, sizeof(tcp_opt)); | 179 | memset(&tcp_opt, 0, sizeof(tcp_opt)); |
180 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); | 180 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); |
181 | 181 | ||
182 | if (!cookie_check_timestamp(&tcp_opt, &ecn_ok)) | 182 | if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) |
183 | goto out; | 183 | goto out; |
184 | 184 | ||
185 | ret = NULL; | 185 | ret = NULL; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 93825dd3a7c0..3164ad272a74 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1027,7 +1027,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1027 | treq->rmt_addr = ipv6_hdr(skb)->saddr; | 1027 | treq->rmt_addr = ipv6_hdr(skb)->saddr; |
1028 | treq->loc_addr = ipv6_hdr(skb)->daddr; | 1028 | treq->loc_addr = ipv6_hdr(skb)->daddr; |
1029 | if (!want_cookie || tmp_opt.tstamp_ok) | 1029 | if (!want_cookie || tmp_opt.tstamp_ok) |
1030 | TCP_ECN_create_request(req, skb); | 1030 | TCP_ECN_create_request(req, skb, sock_net(sk)); |
1031 | 1031 | ||
1032 | treq->iif = sk->sk_bound_dev_if; | 1032 | treq->iif = sk->sk_bound_dev_if; |
1033 | 1033 | ||