[PATCH mptcp-next v5 2/8] mptcp: setsockopt support for TCP_MD5SIG

Geliang Tang posted 8 patches 1 month, 1 week ago
[PATCH mptcp-next v5 2/8] mptcp: setsockopt support for TCP_MD5SIG
Posted by Geliang Tang 1 month, 1 week ago
From: Geliang Tang <tanggeliang@kylinos.cn>

Supporting TCP_MD5 socket option is required when MPTCP is used by
default when creating a socket, to keep the same behaviour as with
TCP. TCP_MD5 is not compatible with MPTCP, and it will cause a
fallback to TCP at the connection request, if MPTCP was requested.
This then fixes a "regression" compared to TCP.

This patch adds setsockopt support for TCP_MD5SIG and TCP_MD5SIG_EXT
options. The implementation:
 - Allow setting these options (getsockopt remains unsupported)
 - Apply them only to the first subflow
 - Trigger fallback to TCP to maintain MD5 compatibility
 - Check if fallback has already occurred in subflow_check_req(). If so,
return immediately

Note that getsockopt for these options remains unsupported, consistent
with TCP.

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/575
Fixes: d9e4c1291810 ("mptcp: only admit explicitly supported sockopt")
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/sockopt.c | 14 ++++++++++++--
 net/mptcp/subflow.c |  3 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index b264185b810d..f2f0b475c8d6 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -13,6 +13,7 @@
 #include <net/tcp.h>
 #include <net/mptcp.h>
 #include "protocol.h"
+#include "mib.h"
 
 #define MIN_INFO_OPTLEN_SIZE		16
 #define MIN_FULL_INFO_OPTLEN_SIZE	40
@@ -567,11 +568,12 @@ static bool mptcp_supported_sockopt(int level, int optname)
 		case TCP_FASTOPEN_CONNECT:
 		case TCP_FASTOPEN_KEY:
 		case TCP_FASTOPEN_NO_COOKIE:
+		/* MD5 will force a fallback to TCP: OK to set while not connected */
+		case TCP_MD5SIG:
+		case TCP_MD5SIG_EXT:
 			return true;
 		}
 
-		/* TCP_MD5SIG, TCP_MD5SIG_EXT are not supported, MD5 is not compatible with MPTCP */
-
 		/* TCP_REPAIR, TCP_REPAIR_QUEUE, TCP_QUEUE_SEQ, TCP_REPAIR_OPTIONS,
 		 * TCP_REPAIR_WINDOW are not supported, better avoid this mess
 		 */
@@ -836,6 +838,14 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
 	case TCP_FASTOPEN_NO_COOKIE:
 		return mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname,
 						      optval, optlen);
+	case TCP_MD5SIG:
+	case TCP_MD5SIG_EXT:
+		ret = mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname,
+						     optval, optlen);
+		if (ret == 0)
+			WARN_ON_ONCE(!__mptcp_try_fallback(msk,
+							   MPTCP_MIB_MD5SIGFALLBACK));
+		return ret;
 	}
 
 	ret = mptcp_get_int_option(msk, optval, optlen, &val);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 3f1b62a9fe88..3c8bbd5d8bf5 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -155,6 +155,9 @@ static int subflow_check_req(struct request_sock *req,
 
 	pr_debug("subflow_req=%p, listener=%p\n", subflow_req, listener);
 
+	if (__mptcp_check_fallback(mptcp_sk(listener->conn)))
+		return 0;
+
 #ifdef CONFIG_TCP_MD5SIG
 	/* no MPTCP if MD5SIG is enabled on this socket or we may run out of
 	 * TCP option space.
-- 
2.48.1