[Devel] [PATCH rh7] ms/ipv4: Namespaceify tcp_fastopen knob

Konstantin Khorenko khorenko at virtuozzo.com
Fri Aug 28 12:02:55 MSK 2020


From: Haishuang Yan <yanhaishuang at cmss.chinamobile.com>

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 at debian.org>
Signed-off-by: Haishuang Yan <yanhaishuang at cmss.chinamobile.com>
Signed-off-by: David S. Miller <davem at davemloft.net>

(cherry picked from commit e1cfcbe82b4534bd0f99fef92a6d33843fd85e0e)
https://jira.sw.ru/browse/PSBM-107100

Signed-off-by: Konstantin Khorenko <khorenko at 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 at 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(-)

diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 1cb305e450f4..69ccdb6c6ca7 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 174b8cd80ca8..892432f49bb6 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 01f0a374847b..81efc146b6ef 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 d6fa49df1ef0..f53f7d476208 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -425,13 +425,6 @@ static struct ctl_table ipv4_table[] = {
 		.proc_handler	= proc_dointvec_immutable,
 	},
 #endif
-	{
-		.procname	= "tcp_fastopen",
-		.data		= &sysctl_tcp_fastopen,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-	},
 	{
 		.procname	= "tcp_fastopen_key",
 		.mode		= 0600,
@@ -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 edc80e6b056a..e263e7188173 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 e08fffa568bc..75a3bb2d54a3 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 f788d27369ab..428ac33ea1b6 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 8f7ec5eb7b6b..86e1d5880d2c 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;
-- 
2.24.3



More information about the Devel mailing list