diff options
-rw-r--r-- | include/net/netns/ipv4.h | 2 | ||||
-rw-r--r-- | include/net/tcp.h | 9 | ||||
-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 |
9 files changed, 25 insertions, 20 deletions
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 2ae2b8372cfd..9b78862014a4 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h | |||
@@ -61,6 +61,8 @@ struct netns_ipv4 { | |||
61 | int sysctl_icmp_ratemask; | 61 | int sysctl_icmp_ratemask; |
62 | int sysctl_icmp_errors_use_inbound_ifaddr; | 62 | int sysctl_icmp_errors_use_inbound_ifaddr; |
63 | 63 | ||
64 | int sysctl_tcp_ecn; | ||
65 | |||
64 | kgid_t sysctl_ping_group_range[2]; | 66 | kgid_t sysctl_ping_group_range[2]; |
65 | long sysctl_tcp_mem[3]; | 67 | long sysctl_tcp_mem[3]; |
66 | 68 | ||
diff --git a/include/net/tcp.h b/include/net/tcp.h index aed42c785153..614af8b7758e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -266,7 +266,6 @@ extern int sysctl_tcp_abort_on_overflow; | |||
266 | extern int sysctl_tcp_max_orphans; | 266 | extern int sysctl_tcp_max_orphans; |
267 | extern int sysctl_tcp_fack; | 267 | extern int sysctl_tcp_fack; |
268 | extern int sysctl_tcp_reordering; | 268 | extern int sysctl_tcp_reordering; |
269 | extern int sysctl_tcp_ecn; | ||
270 | extern int sysctl_tcp_dsack; | 269 | extern int sysctl_tcp_dsack; |
271 | extern int sysctl_tcp_wmem[3]; | 270 | extern int sysctl_tcp_wmem[3]; |
272 | extern int sysctl_tcp_rmem[3]; | 271 | extern int sysctl_tcp_rmem[3]; |
@@ -504,7 +503,8 @@ static inline __u32 cookie_v4_init_sequence(struct sock *sk, | |||
504 | #endif | 503 | #endif |
505 | 504 | ||
506 | extern __u32 cookie_init_timestamp(struct request_sock *req); | 505 | extern __u32 cookie_init_timestamp(struct request_sock *req); |
507 | extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *); | 506 | extern bool cookie_check_timestamp(struct tcp_options_received *opt, |
507 | struct net *net, bool *ecn_ok); | ||
508 | 508 | ||
509 | /* From net/ipv6/syncookies.c */ | 509 | /* From net/ipv6/syncookies.c */ |
510 | extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); | 510 | extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); |
@@ -728,11 +728,12 @@ struct tcp_skb_cb { | |||
728 | * notifications, we disable TCP ECN negociation. | 728 | * notifications, we disable TCP ECN negociation. |
729 | */ | 729 | */ |
730 | static inline void | 730 | static inline void |
731 | TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb) | 731 | TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb, |
732 | struct net *net) | ||
732 | { | 733 | { |
733 | const struct tcphdr *th = tcp_hdr(skb); | 734 | const struct tcphdr *th = tcp_hdr(skb); |
734 | 735 | ||
735 | if (sysctl_tcp_ecn && th->ece && th->cwr && | 736 | if (net->ipv4.sysctl_tcp_ecn && th->ece && th->cwr && |
736 | INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield)) | 737 | INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield)) |
737 | inet_rsk(req)->ecn_ok = 1; | 738 | inet_rsk(req)->ecn_ok = 1; |
738 | } | 739 | } |
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 | ||