Skip to content

Commit

Permalink
tcp: make sysctl_tcp_ecn namespace aware
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Hannes Frederic Sowa authored and David S. Miller committed Jan 7, 2013
1 parent 71bcdba commit 5d134f1
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 20 deletions.
2 changes: 2 additions & 0 deletions include/net/netns/ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct netns_ipv4 {
int sysctl_icmp_ratemask;
int sysctl_icmp_errors_use_inbound_ifaddr;

int sysctl_tcp_ecn;

kgid_t sysctl_ping_group_range[2];
long sysctl_tcp_mem[3];

Expand Down
9 changes: 5 additions & 4 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ extern int sysctl_tcp_abort_on_overflow;
extern int sysctl_tcp_max_orphans;
extern int sysctl_tcp_fack;
extern int sysctl_tcp_reordering;
extern int sysctl_tcp_ecn;
extern int sysctl_tcp_dsack;
extern int sysctl_tcp_wmem[3];
extern int sysctl_tcp_rmem[3];
Expand Down Expand Up @@ -504,7 +503,8 @@ static inline __u32 cookie_v4_init_sequence(struct sock *sk,
#endif

extern __u32 cookie_init_timestamp(struct request_sock *req);
extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *);
extern bool cookie_check_timestamp(struct tcp_options_received *opt,
struct net *net, bool *ecn_ok);

/* From net/ipv6/syncookies.c */
extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb);
Expand Down Expand Up @@ -728,11 +728,12 @@ struct tcp_skb_cb {
* notifications, we disable TCP ECN negociation.
*/
static inline void
TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb)
TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb,
struct net *net)
{
const struct tcphdr *th = tcp_hdr(skb);

if (sysctl_tcp_ecn && th->ece && th->cwr &&
if (net->ipv4.sysctl_tcp_ecn && th->ece && th->cwr &&
INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield))
inet_rsk(req)->ecn_ok = 1;
}
Expand Down
7 changes: 4 additions & 3 deletions net/ipv4/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
*
* return false if we decode an option that should not be.
*/
bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok)
bool cookie_check_timestamp(struct tcp_options_received *tcp_opt,
struct net *net, bool *ecn_ok)
{
/* echoed timestamp, lowest bits contain options */
u32 options = tcp_opt->rcv_tsecr & TSMASK;
Expand All @@ -247,7 +248,7 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok)

tcp_opt->sack_ok = (options & (1 << 4)) ? TCP_SACK_SEEN : 0;
*ecn_ok = (options >> 5) & 1;
if (*ecn_ok && !sysctl_tcp_ecn)
if (*ecn_ok && !net->ipv4.sysctl_tcp_ecn)
return false;

if (tcp_opt->sack_ok && !sysctl_tcp_sack)
Expand Down Expand Up @@ -295,7 +296,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
memset(&tcp_opt, 0, sizeof(tcp_opt));
tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL);

if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok))
goto out;

ret = NULL;
Expand Down
16 changes: 9 additions & 7 deletions net/ipv4/sysctl_net_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,13 +537,6 @@ static struct ctl_table ipv4_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_ecn",
.data = &sysctl_tcp_ecn,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_dsack",
.data = &sysctl_tcp_dsack,
Expand Down Expand Up @@ -849,6 +842,13 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644,
.proc_handler = ipv4_ping_group_range,
},
{
.procname = "tcp_ecn",
.data = &init_net.ipv4.sysctl_tcp_ecn,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_mem",
.maxlen = sizeof(init_net.ipv4.sysctl_tcp_mem),
Expand Down Expand Up @@ -882,6 +882,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
&net->ipv4.sysctl_icmp_ratemask;
table[6].data =
&net->ipv4.sysctl_ping_group_range;
table[7].data =
&net->ipv4.sysctl_tcp_ecn;

/* Don't export sysctls to unprivileged users */
if (net->user_ns != &init_user_ns)
Expand Down
2 changes: 0 additions & 2 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ int sysctl_tcp_sack __read_mostly = 1;
int sysctl_tcp_fack __read_mostly = 1;
int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
EXPORT_SYMBOL(sysctl_tcp_reordering);
int sysctl_tcp_ecn __read_mostly = 2;
EXPORT_SYMBOL(sysctl_tcp_ecn);
int sysctl_tcp_dsack __read_mostly = 1;
int sysctl_tcp_app_win __read_mostly = 31;
int sysctl_tcp_adv_win_scale __read_mostly = 1;
Expand Down
3 changes: 2 additions & 1 deletion net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1568,7 +1568,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop_and_free;

if (!want_cookie || tmp_opt.tstamp_ok)
TCP_ECN_create_request(req, skb);
TCP_ECN_create_request(req, skb, sock_net(sk));

if (want_cookie) {
isn = cookie_v4_init_sequence(sk, skb, &req->mss);
Expand Down Expand Up @@ -2888,6 +2888,7 @@ EXPORT_SYMBOL(tcp_prot);

static int __net_init tcp_sk_init(struct net *net)
{
net->ipv4.sysctl_tcp_ecn = 2;
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
struct tcp_sock *tp = tcp_sk(sk);

tp->ecn_flags = 0;
if (sysctl_tcp_ecn == 1) {
if (sock_net(sk)->ipv4.sysctl_tcp_ecn == 1) {
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR;
tp->ecn_flags = TCP_ECN_OK;
}
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
memset(&tcp_opt, 0, sizeof(tcp_opt));
tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL);

if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok))
goto out;

ret = NULL;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
treq->rmt_addr = ipv6_hdr(skb)->saddr;
treq->loc_addr = ipv6_hdr(skb)->daddr;
if (!want_cookie || tmp_opt.tstamp_ok)
TCP_ECN_create_request(req, skb);
TCP_ECN_create_request(req, skb, sock_net(sk));

treq->iif = sk->sk_bound_dev_if;

Expand Down

0 comments on commit 5d134f1

Please sign in to comment.