Commit 4156afaf authored by David S. Miller's avatar David S. Miller

Merge branch 'tcp-keepalive-namespaceify'

Nikolay Borisov says:

====================
Namespaceify tcp keepalive machinery

The following patch series enables the tcp keepalive mechanism
to be configured per net namespace. This is especially useful
if you have multiple containers hosted on one node and one of
them is under DoS-  in such situations one thing which could
be done is to configure the tcp keepalive settings such that
connections for that particular container are being reset
faster.

Another scenario where not being able to control those knob
comes per container is problematic is occurs the value of
net.netfilter.nf_conntrack_tcp_timeout_established is set
below the keepalive interval, in such situations the server won't
send an RST packet resulting in applications not trying to
reconnect and stale connection waiting. Changing the global
keepalive value is a possible solution but it might interfere
with other containers.

The three patches gradually convert each of the affected knobs
to be per netns. I thought it would be easier for review than
put everything in one patch. If people deem it more appropriate
to squash everything in one patch (maybe after review) I'd
be more than happy to do it.

The patches have been compile-tested on 4.4 and functionally
tested on 3.12 and they work as expected.

These are based off 4.4-rc8
====================
Acked-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d3517f19 b840d15d
...@@ -94,6 +94,10 @@ struct netns_ipv4 { ...@@ -94,6 +94,10 @@ struct netns_ipv4 {
int sysctl_tcp_probe_threshold; int sysctl_tcp_probe_threshold;
u32 sysctl_tcp_probe_interval; u32 sysctl_tcp_probe_interval;
int sysctl_tcp_keepalive_time;
int sysctl_tcp_keepalive_probes;
int sysctl_tcp_keepalive_intvl;
struct ping_group_range ping_group_range; struct ping_group_range ping_group_range;
atomic_t dev_addr_genid; atomic_t dev_addr_genid;
......
...@@ -240,9 +240,6 @@ extern int sysctl_tcp_timestamps; ...@@ -240,9 +240,6 @@ extern int sysctl_tcp_timestamps;
extern int sysctl_tcp_window_scaling; extern int sysctl_tcp_window_scaling;
extern int sysctl_tcp_sack; extern int sysctl_tcp_sack;
extern int sysctl_tcp_fin_timeout; extern int sysctl_tcp_fin_timeout;
extern int sysctl_tcp_keepalive_time;
extern int sysctl_tcp_keepalive_probes;
extern int sysctl_tcp_keepalive_intvl;
extern int sysctl_tcp_syn_retries; extern int sysctl_tcp_syn_retries;
extern int sysctl_tcp_synack_retries; extern int sysctl_tcp_synack_retries;
extern int sysctl_tcp_retries1; extern int sysctl_tcp_retries1;
...@@ -1225,17 +1222,23 @@ void tcp_enter_memory_pressure(struct sock *sk); ...@@ -1225,17 +1222,23 @@ void tcp_enter_memory_pressure(struct sock *sk);
static inline int keepalive_intvl_when(const struct tcp_sock *tp) static inline int keepalive_intvl_when(const struct tcp_sock *tp)
{ {
return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl; struct net *net = sock_net((struct sock *)tp);
return tp->keepalive_intvl ? : net->ipv4.sysctl_tcp_keepalive_intvl;
} }
static inline int keepalive_time_when(const struct tcp_sock *tp) static inline int keepalive_time_when(const struct tcp_sock *tp)
{ {
return tp->keepalive_time ? : sysctl_tcp_keepalive_time; struct net *net = sock_net((struct sock *)tp);
return tp->keepalive_time ? : net->ipv4.sysctl_tcp_keepalive_time;
} }
static inline int keepalive_probes(const struct tcp_sock *tp) static inline int keepalive_probes(const struct tcp_sock *tp)
{ {
return tp->keepalive_probes ? : sysctl_tcp_keepalive_probes; struct net *net = sock_net((struct sock *)tp);
return tp->keepalive_probes ? : net->ipv4.sysctl_tcp_keepalive_probes;
} }
static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
......
...@@ -336,27 +336,6 @@ static struct ctl_table ipv4_table[] = { ...@@ -336,27 +336,6 @@ static struct ctl_table ipv4_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec .proc_handler = proc_dointvec
}, },
{
.procname = "tcp_keepalive_time",
.data = &sysctl_tcp_keepalive_time,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{
.procname = "tcp_keepalive_probes",
.data = &sysctl_tcp_keepalive_probes,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_keepalive_intvl",
.data = &sysctl_tcp_keepalive_intvl,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{ {
.procname = "tcp_retries1", .procname = "tcp_retries1",
.data = &sysctl_tcp_retries1, .data = &sysctl_tcp_retries1,
...@@ -961,6 +940,27 @@ static struct ctl_table ipv4_net_table[] = { ...@@ -961,6 +940,27 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec .proc_handler = proc_dointvec
}, },
{
.procname = "tcp_keepalive_time",
.data = &init_net.ipv4.sysctl_tcp_keepalive_time,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{
.procname = "tcp_keepalive_probes",
.data = &init_net.ipv4.sysctl_tcp_keepalive_probes,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_keepalive_intvl",
.data = &init_net.ipv4.sysctl_tcp_keepalive_intvl,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{ } { }
}; };
......
...@@ -2385,6 +2385,10 @@ static int __net_init tcp_sk_init(struct net *net) ...@@ -2385,6 +2385,10 @@ static int __net_init tcp_sk_init(struct net *net)
net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD;
net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL;
net->ipv4.sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME;
net->ipv4.sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES;
net->ipv4.sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
return 0; return 0;
fail: fail:
tcp_sk_exit(net); tcp_sk_exit(net);
......
...@@ -24,9 +24,6 @@ ...@@ -24,9 +24,6 @@
int sysctl_tcp_syn_retries __read_mostly = TCP_SYN_RETRIES; int sysctl_tcp_syn_retries __read_mostly = TCP_SYN_RETRIES;
int sysctl_tcp_synack_retries __read_mostly = TCP_SYNACK_RETRIES; int sysctl_tcp_synack_retries __read_mostly = TCP_SYNACK_RETRIES;
int sysctl_tcp_keepalive_time __read_mostly = TCP_KEEPALIVE_TIME;
int sysctl_tcp_keepalive_probes __read_mostly = TCP_KEEPALIVE_PROBES;
int sysctl_tcp_keepalive_intvl __read_mostly = TCP_KEEPALIVE_INTVL;
int sysctl_tcp_retries1 __read_mostly = TCP_RETR1; int sysctl_tcp_retries1 __read_mostly = TCP_RETR1;
int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; int sysctl_tcp_retries2 __read_mostly = TCP_RETR2;
int sysctl_tcp_orphan_retries __read_mostly; int sysctl_tcp_orphan_retries __read_mostly;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment