[RHEL7,COMMIT] ms/ipv4: Namespaceify tcp_fastopen knob

Submitted by Vasily Averin on Aug. 29, 2020, 7:20 a.m.

Details

Message ID 202008290720.07T7K6oH012831@vz7build.vvs.sw.ru
State New
Series "ms/ipv4: Namespaceify tcp_fastopen knob"
Headers show

Commit Message

Vasily Averin Aug. 29, 2020, 7:20 a.m.
The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.14
------>
commit d1eaa6976909f93abc21541ff2aa6c4d42aff1d7
Author: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
Date:   Sat Aug 29 10:20:06 2020 +0300

    ms/ipv4: Namespaceify tcp_fastopen knob
    
    Different namespace application might require enable TCP Fast Open
    feature independently of the host.
    
    This patch series continues making more of the TCP Fast Open related
    sysctl knobs be per net-namespace.
    
    Reported-by: Luca BRUNO <lucab@debian.org>
    Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    
    (cherry picked from commit e1cfcbe82b4534bd0f99fef92a6d33843fd85e0e)
    https://jira.sw.ru/browse/PSBM-107100
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
    
    Backport notice:
    - dropped hunk in TCP_FASTOPEN_CONNECT case in do_tcp_setsockopt()
      (no case TCP_FASTOPEN_CONNECT)
    - dropped hunk in tcp_fastopen_cookie_check(), no function,
      it appears later by 065263f40f09 ("net/tcp-fastopen: refactor cookie
      check logic")
    - added a hunk in tcp_send_syn_data() instead
    - after mainstream commit default tcp_fastopen value changed 0->1.
      We preserve native RHEL7 default - 0.
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 include/net/netns/ipv4.h   |  2 ++
 include/net/tcp.h          |  1 -
 net/ipv4/af_inet.c         | 11 ++++++-----
 net/ipv4/sysctl_net_ipv4.c | 14 +++++++-------
 net/ipv4/tcp.c             |  2 +-
 net/ipv4/tcp_fastopen.c    |  9 ++++-----
 net/ipv4/tcp_ipv4.c        |  3 +++
 net/ipv4/tcp_output.c      |  2 +-
 8 files changed, 24 insertions(+), 20 deletions(-)

Patch hide | download patch | download mbox

diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 1cb305e..69ccdb6 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -76,6 +76,8 @@  struct netns_ipv4 {
 	kgid_t sysctl_ping_group_range[2];
 	long sysctl_tcp_mem[3];
 
+	int sysctl_tcp_fastopen;
+
 	atomic_t dev_addr_genid;
 	RH_KABI_FILL_HOLE(unsigned int	fib_seq)	/* protected by rtnl_mutex */
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 174b8cd..892432f 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -249,7 +249,6 @@  extern int sysctl_tcp_retries1;
 extern int sysctl_tcp_retries2;
 extern int sysctl_tcp_orphan_retries;
 extern int sysctl_tcp_syncookies;
-extern int sysctl_tcp_fastopen;
 extern int sysctl_tcp_retrans_collapse;
 extern int sysctl_tcp_stdurg;
 extern int sysctl_tcp_rfc1337;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 01f0a37..81efc14 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -193,7 +193,7 @@  int inet_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	unsigned char old_state;
-	int err;
+	int err, tcp_fastopen;
 
 	lock_sock(sk);
 
@@ -216,14 +216,15 @@  int inet_listen(struct socket *sock, int backlog)
 		 * socket was in TCP_LISTEN state previously but was
 		 * shutdown() (rather than close()).
 		 */
-		if ((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) != 0 &&
+		tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
+		if ((tcp_fastopen & TFO_SERVER_ENABLE) != 0 &&
 		    inet_csk(sk)->icsk_accept_queue.fastopenq == NULL) {
-			if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) != 0)
+			if ((tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) != 0)
 				err = fastopen_init_queue(sk, backlog);
-			else if ((sysctl_tcp_fastopen &
+			else if ((tcp_fastopen &
 				  TFO_SERVER_WO_SOCKOPT2) != 0)
 				err = fastopen_init_queue(sk,
-				    ((uint)sysctl_tcp_fastopen) >> 16);
+				    ((uint)tcp_fastopen) >> 16);
 			else
 				err = 0;
 			if (err)
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index d6fa49d..f53f7d4 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -426,13 +426,6 @@  static struct ctl_table ipv4_table[] = {
 	},
 #endif
 	{
-		.procname	= "tcp_fastopen",
-		.data		= &sysctl_tcp_fastopen,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-	},
-	{
 		.procname	= "tcp_fastopen_key",
 		.mode		= 0600,
 		.maxlen		= ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10),
@@ -974,6 +967,13 @@  static struct ctl_table ipv4_net_table[] = {
 		.extra1		= &tcp_min_snd_mss_min,
 		.extra2		= &tcp_min_snd_mss_max,
 	},
+	{
+		.procname	= "tcp_fastopen",
+		.data		= &init_net.ipv4.sysctl_tcp_fastopen,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
 	{ }
 };
 
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index edc80e6..e263e71 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1054,7 +1054,7 @@  static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
 	struct tcp_sock *tp = tcp_sk(sk);
 	int err, flags;
 
-	if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE))
+	if (!(sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE))
 		return -EOPNOTSUPP;
 	if (tp->fastopen_req != NULL)
 		return -EALREADY; /* Another Fast Open is in progress */
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index e08fffa..75a3bb2 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -8,8 +8,6 @@ 
 #include <net/inetpeer.h>
 #include <net/tcp.h>
 
-int sysctl_tcp_fastopen __read_mostly;
-
 struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
 
 static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
@@ -285,20 +283,21 @@  bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
 		      struct tcp_fastopen_cookie *foc,
 		      struct dst_entry *dst)
 {
-	struct tcp_fastopen_cookie valid_foc = { .len = -1 };
 	bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
+	int tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
+	struct tcp_fastopen_cookie valid_foc = { .len = -1 };
 
 	if (foc->len == 0) /* Client requests a cookie */
 		NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENCOOKIEREQD);
 
-	if (!((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) &&
+	if (!((tcp_fastopen & TFO_SERVER_ENABLE) &&
 	      (syn_data || foc->len >= 0) &&
 	      tcp_fastopen_queue_check(sk))) {
 		foc->len = -1;
 		return false;
 	}
 
-	if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
+	if (syn_data && (tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
 		goto fastopen;
 
 	if (foc->len >= 0 &&  /* Client presents or requests a cookie */
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f788d27..428ac33 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2532,6 +2532,9 @@  static int __net_init tcp_sk_init(struct net *net)
 	net->ipv4_sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES;
 	net->ipv4_sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
 
+	/* preserve RHEL7 default tcp_fastopen sysctl value */
+	net->ipv4.sysctl_tcp_fastopen = 0;
+
 	return 0;
 
 fail:
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 8f7ec5e..86e1d588 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3102,7 +3102,7 @@  static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 		goto fallback;
 	}
 
-	if (sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE)
+	if (sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE)
 		fo->cookie.len = -1;
 	else if (fo->cookie.len <= 0)
 		goto fallback;