aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorHaishuang Yan <yanhaishuang@cmss.chinamobile.com>2016-12-28 04:52:32 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-29 11:38:31 -0500
commit1946e672c173559155a3e210fe95dbf8b7b8ddf7 (patch)
tree0d794dc28150aac130c2e6dd0024cb3a4a5ec594 /net/ipv4/tcp_ipv4.c
parent801822d1beea4f11a38df991b420ca917f6a917b (diff)
ipv4: Namespaceify tcp_tw_recycle and tcp_max_tw_buckets knob
Different namespace application might require fast recycling TIME-WAIT sockets independently of the host. Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fe9da4fb96bf..56b5f49e3f97 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -146,6 +146,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
146 struct rtable *rt; 146 struct rtable *rt;
147 int err; 147 int err;
148 struct ip_options_rcu *inet_opt; 148 struct ip_options_rcu *inet_opt;
149 struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row;
149 150
150 if (addr_len < sizeof(struct sockaddr_in)) 151 if (addr_len < sizeof(struct sockaddr_in))
151 return -EINVAL; 152 return -EINVAL;
@@ -196,7 +197,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
196 tp->write_seq = 0; 197 tp->write_seq = 0;
197 } 198 }
198 199
199 if (tcp_death_row.sysctl_tw_recycle && 200 if (tcp_death_row->sysctl_tw_recycle &&
200 !tp->rx_opt.ts_recent_stamp && fl4->daddr == daddr) 201 !tp->rx_opt.ts_recent_stamp && fl4->daddr == daddr)
201 tcp_fetch_timewait_stamp(sk, &rt->dst); 202 tcp_fetch_timewait_stamp(sk, &rt->dst);
202 203
@@ -215,7 +216,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
215 * complete initialization after this. 216 * complete initialization after this.
216 */ 217 */
217 tcp_set_state(sk, TCP_SYN_SENT); 218 tcp_set_state(sk, TCP_SYN_SENT);
218 err = inet_hash_connect(&tcp_death_row, sk); 219 err = inet_hash_connect(tcp_death_row, sk);
219 if (err) 220 if (err)
220 goto failure; 221 goto failure;
221 222
@@ -2457,6 +2458,10 @@ static int __net_init tcp_sk_init(struct net *net)
2457 net->ipv4.sysctl_tcp_notsent_lowat = UINT_MAX; 2458 net->ipv4.sysctl_tcp_notsent_lowat = UINT_MAX;
2458 net->ipv4.sysctl_tcp_tw_reuse = 0; 2459 net->ipv4.sysctl_tcp_tw_reuse = 0;
2459 2460
2461 net->ipv4.tcp_death_row.sysctl_tw_recycle = 0;
2462 net->ipv4.tcp_death_row.sysctl_max_tw_buckets = (tcp_hashinfo.ehash_mask + 1) / 2;
2463 net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo;
2464
2460 return 0; 2465 return 0;
2461fail: 2466fail:
2462 tcp_sk_exit(net); 2467 tcp_sk_exit(net);
@@ -2466,7 +2471,7 @@ fail:
2466 2471
2467static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list) 2472static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list)
2468{ 2473{
2469 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET); 2474 inet_twsk_purge(&tcp_hashinfo, AF_INET);
2470} 2475}
2471 2476
2472static struct pernet_operations __net_initdata tcp_sk_ops = { 2477static struct pernet_operations __net_initdata tcp_sk_ops = {
@@ -2477,7 +2482,6 @@ static struct pernet_operations __net_initdata tcp_sk_ops = {
2477 2482
2478void __init tcp_v4_init(void) 2483void __init tcp_v4_init(void)
2479{ 2484{
2480 inet_hashinfo_init(&tcp_hashinfo);
2481 if (register_pernet_subsys(&tcp_sk_ops)) 2485 if (register_pernet_subsys(&tcp_sk_ops))
2482 panic("Failed to create the TCP control socket.\n"); 2486 panic("Failed to create the TCP control socket.\n");
2483} 2487}