aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/ipv4.h2
-rw-r--r--include/net/tcp.h9
-rw-r--r--net/ipv4/syncookies.c7
-rw-r--r--net/ipv4/sysctl_net_ipv4.c16
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv4/tcp_ipv4.c3
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv6/syncookies.c2
-rw-r--r--net/ipv6/tcp_ipv6.c2
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;
266extern int sysctl_tcp_max_orphans; 266extern int sysctl_tcp_max_orphans;
267extern int sysctl_tcp_fack; 267extern int sysctl_tcp_fack;
268extern int sysctl_tcp_reordering; 268extern int sysctl_tcp_reordering;
269extern int sysctl_tcp_ecn;
270extern int sysctl_tcp_dsack; 269extern int sysctl_tcp_dsack;
271extern int sysctl_tcp_wmem[3]; 270extern int sysctl_tcp_wmem[3];
272extern int sysctl_tcp_rmem[3]; 271extern 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
506extern __u32 cookie_init_timestamp(struct request_sock *req); 505extern __u32 cookie_init_timestamp(struct request_sock *req);
507extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *); 506extern 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 */
510extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); 510extern 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 */
730static inline void 730static inline void
731TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb) 731TCP_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 */
235bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok) 235bool 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;
81int sysctl_tcp_fack __read_mostly = 1; 81int sysctl_tcp_fack __read_mostly = 1;
82int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; 82int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
83EXPORT_SYMBOL(sysctl_tcp_reordering); 83EXPORT_SYMBOL(sysctl_tcp_reordering);
84int sysctl_tcp_ecn __read_mostly = 2;
85EXPORT_SYMBOL(sysctl_tcp_ecn);
86int sysctl_tcp_dsack __read_mostly = 1; 84int sysctl_tcp_dsack __read_mostly = 1;
87int sysctl_tcp_app_win __read_mostly = 31; 85int sysctl_tcp_app_win __read_mostly = 31;
88int sysctl_tcp_adv_win_scale __read_mostly = 1; 86int 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
2889static int __net_init tcp_sk_init(struct net *net) 2889static 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