From: Geliang Tang <tanggeliang@kylinos.cn>
Allow MPTCP sockets to set the TCP_ULP socket option to enable TLS.
Add mptcp_setsockopt_tcp_ulp() which validates the socket state (must
not be CLOSE or LISTEN), only accepts "tls" as the ULP name, and then
calls tcp_set_ulp().
Include TCP_ULP in the list of supported options in supported_sockopt(),
and handle it in setsockopt_sol_tcp() instead of returning -EOPNOTSUPP.
Call tcp_cleanup_ulp() in mptcp_destroy_common() to release ULP module's
reference count.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 1 +
net/mptcp/sockopt.c | 35 ++++++++++++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index d780989679a1..59fdc12f35c9 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3422,6 +3422,7 @@ static void mptcp_destroy_common(struct mptcp_sock *msk)
__mptcp_clear_xmit(sk);
mptcp_backlog_purge(sk);
+ tcp_cleanup_ulp(sk);
/* join list will be eventually flushed (with rst) at sock lock release time */
mptcp_for_each_subflow_safe(msk, subflow, tmp)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 59742c956154..4282b47faed7 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -12,6 +12,7 @@
#include <net/protocol.h>
#include <net/tcp.h>
#include <net/mptcp.h>
+#include <net/tls.h>
#include "protocol.h"
#define MIN_INFO_OPTLEN_SIZE 16
@@ -567,6 +568,7 @@ static bool mptcp_supported_sockopt(int level, int optname)
case TCP_FASTOPEN_CONNECT:
case TCP_FASTOPEN_KEY:
case TCP_FASTOPEN_NO_COOKIE:
+ case TCP_ULP:
return true;
}
@@ -815,6 +817,37 @@ static int mptcp_setsockopt_all_sf(struct mptcp_sock *msk, int level,
return ret;
}
+static int mptcp_setsockopt_tcp_ulp(struct sock *sk, sockptr_t optval,
+ unsigned int optlen)
+{
+ char name[TCP_ULP_NAME_MAX];
+ int err = 0;
+ size_t len;
+ int val;
+
+ if (optlen < 1)
+ return -EINVAL;
+
+ len = min_t(long, TCP_ULP_NAME_MAX - 1, optlen);
+ val = strncpy_from_sockptr(name, optval, len);
+ if (val < 0)
+ return -EFAULT;
+ name[val] = 0;
+
+ if (strcmp(name, "tls"))
+ return -EOPNOTSUPP;
+
+ sockopt_lock_sock(sk);
+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) {
+ err = -ENOTCONN;
+ goto out;
+ }
+ err = tcp_set_ulp(sk, name);
+out:
+ sockopt_release_sock(sk);
+ return err;
+}
+
static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
sockptr_t optval, unsigned int optlen)
{
@@ -823,7 +856,7 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
switch (optname) {
case TCP_ULP:
- return -EOPNOTSUPP;
+ return mptcp_setsockopt_tcp_ulp(sk, optval, optlen);
case TCP_CONGESTION:
return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen);
case TCP_DEFER_ACCEPT:
--
2.51.0