* [RFC mptcp-next v3 1/8] selftests: mptcp: sockopt: add protocol arguments
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 2/8] selftests: mptcp: sockopt: enhance compatibility with TCP tests Geliang Tang
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
Add -t and -r options to specify tx/rx protocols (TCP/MPTCP). This
increases testing flexibility by allowing explicit protocol selection
for both transmission and reception paths.
These codes are from mptcp_inq.c.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 29 +++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 286164f7246e..e4752f848f08 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -27,6 +27,8 @@
#include <linux/tcp.h>
static int pf = AF_INET;
+static int proto_tx = IPPROTO_MPTCP;
+static int proto_rx = IPPROTO_MPTCP;
#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
@@ -135,7 +137,7 @@ static void die_perror(const char *msg)
static void die_usage(int r)
{
- fprintf(stderr, "Usage: mptcp_sockopt [-6]\n");
+ fprintf(stderr, "Usage: mptcp_sockopt [-6] [-t tcp|mptcp] [-r tcp|mptcp]\n");
exit(r);
}
@@ -201,7 +203,7 @@ static int sock_listen_mptcp(const char * const listenaddr,
hints.ai_family = pf;
for (a = addr; a; a = a->ai_next) {
- sock = socket(a->ai_family, a->ai_socktype, IPPROTO_MPTCP);
+ sock = socket(a->ai_family, a->ai_socktype, proto_rx);
if (sock < 0)
continue;
@@ -259,11 +261,22 @@ static int sock_connect_mptcp(const char * const remoteaddr,
return sock;
}
+static int protostr_to_num(const char *s)
+{
+ if (strcasecmp(s, "tcp") == 0)
+ return IPPROTO_TCP;
+ if (strcasecmp(s, "mptcp") == 0)
+ return IPPROTO_MPTCP;
+
+ die_usage(1);
+ return 0;
+}
+
static void parse_opts(int argc, char **argv)
{
int c;
- while ((c = getopt(argc, argv, "h6")) != -1) {
+ while ((c = getopt(argc, argv, "h6t:r:")) != -1) {
switch (c) {
case 'h':
die_usage(0);
@@ -271,6 +284,12 @@ static void parse_opts(int argc, char **argv)
case '6':
pf = AF_INET6;
break;
+ case 't':
+ proto_tx = protostr_to_num(optarg);
+ break;
+ case 'r':
+ proto_rx = protostr_to_num(optarg);
+ break;
default:
die_usage(1);
break;
@@ -776,10 +795,10 @@ static int client(int pipefd)
switch (pf) {
case AF_INET:
- fd = sock_connect_mptcp("127.0.0.1", "15432", IPPROTO_MPTCP);
+ fd = sock_connect_mptcp("127.0.0.1", "15432", proto_tx);
break;
case AF_INET6:
- fd = sock_connect_mptcp("::1", "15432", IPPROTO_MPTCP);
+ fd = sock_connect_mptcp("::1", "15432", proto_tx);
break;
default:
xerror("Unknown pf %d\n", pf);
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 2/8] selftests: mptcp: sockopt: enhance compatibility with TCP tests
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 1/8] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 3/8] selftests: mptcp: sockopt: implement TCP TLS tests Geliang Tang
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
Enhance compatibility with TCP tests in mptcp_sockopt.c, skip mptcp
getsockopt checks during tcp tests since MPTCP socket options are not
available for them.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 25 +++++++++++++------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index e4752f848f08..8fb04c19af5c 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -383,8 +383,11 @@ static void do_getsockopt_mptcp_info(struct so_state *s, int fd, size_t w)
olen = sizeof(i);
ret = getsockopt(fd, SOL_MPTCP, MPTCP_INFO, &i, &olen);
- if (ret < 0)
+ if (ret < 0) {
+ if (errno == EOPNOTSUPP || errno == ENOPROTOOPT)
+ return;
die_perror("getsockopt MPTCP_INFO");
+ }
s->pkt_stats_avail = olen >= sizeof(i);
@@ -414,8 +417,11 @@ static void do_getsockopt_tcp_info(struct so_state *s, int fd, size_t r, size_t
olen = sizeof(ti);
ret = getsockopt(fd, SOL_MPTCP, MPTCP_TCPINFO, &ti, &olen);
- if (ret < 0)
+ if (ret < 0) {
+ if (errno == EOPNOTSUPP || errno == ENOPROTOOPT)
+ return;
xerror("getsockopt MPTCP_TCPINFO (tries %d, %m)");
+ }
assert(olen <= sizeof(ti));
assert(ti.d.size_kernel > 0);
@@ -469,8 +475,11 @@ static void do_getsockopt_subflow_addrs(struct so_state *s, int fd)
olen = sizeof(addrs);
ret = getsockopt(fd, SOL_MPTCP, MPTCP_SUBFLOW_ADDRS, &addrs, &olen);
- if (ret < 0)
+ if (ret < 0) {
+ if (errno == EOPNOTSUPP || errno == ENOPROTOOPT)
+ return;
die_perror("getsockopt MPTCP_SUBFLOW_ADDRS");
+ }
assert(olen <= sizeof(addrs));
assert(addrs.d.size_kernel > 0);
@@ -541,10 +550,8 @@ static void do_getsockopt_mptcp_full_info(struct so_state *s, int fd)
ret = getsockopt(fd, SOL_MPTCP, MPTCP_FULL_INFO, &mfi, &olen);
if (ret < 0) {
- if (errno == EOPNOTSUPP) {
- perror("MPTCP_FULL_INFO test skipped");
+ if (errno == EOPNOTSUPP || errno == ENOPROTOOPT)
return;
- }
xerror("getsockopt MPTCP_FULL_INFO");
}
@@ -650,7 +657,8 @@ static void connect_one_server(int fd, int pipefd)
if (eof)
total += 1; /* sequence advances due to FIN */
- assert(s.mptcpi_rcv_delta == (uint64_t)total);
+ if (s.mptcpi_rcv_delta)
+ assert(s.mptcpi_rcv_delta == (uint64_t)total);
close(fd);
}
@@ -685,7 +693,8 @@ static void process_one_client(int fd, int pipefd)
xerror("expected EOF, got %lu", ret3);
do_getsockopts(&s, fd, ret, ret2);
- if (s.mptcpi_rcv_delta != (uint64_t)ret + 1)
+ if (s.mptcpi_rcv_delta &&
+ s.mptcpi_rcv_delta != (uint64_t)ret + 1)
xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64 ", diff %" PRId64,
s.mptcpi_rcv_delta, ret + 1, s.mptcpi_rcv_delta - (ret + 1));
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 3/8] selftests: mptcp: sockopt: implement TCP TLS tests
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 1/8] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 2/8] selftests: mptcp: sockopt: enhance compatibility with TCP tests Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 4/8] tls: add MPTCP protocol support Geliang Tang
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch adds Kernel TLS (KTLS) testing infrastructure to MPTCP sockopt
selftest, introducing a new '-c' option to enable TLS tests. It includes
a helper for configuring TLS socket options and implements TCP-specific
KTLS test cases for both IPv4 and IPv6, along with the necessary header
includes and config updates.
TLS_OVERHEAD_SIZE macro is defined to account for the overhead in sent
and received data length.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/config | 1 +
.../selftests/net/mptcp/mptcp_sockopt.c | 75 ++++++++++++++++++-
.../selftests/net/mptcp/mptcp_sockopt.sh | 36 +++++++++
3 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/config b/tools/testing/selftests/net/mptcp/config
index 59051ee2a986..18bd29ac5b24 100644
--- a/tools/testing/selftests/net/mptcp/config
+++ b/tools/testing/selftests/net/mptcp/config
@@ -34,3 +34,4 @@ CONFIG_NFT_SOCKET=m
CONFIG_NFT_TPROXY=m
CONFIG_SYN_COOKIES=y
CONFIG_VETH=y
+CONFIG_TLS=y
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 8fb04c19af5c..444851221473 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -25,10 +25,12 @@
#include <netinet/in.h>
#include <linux/tcp.h>
+#include <linux/tls.h>
static int pf = AF_INET;
static int proto_tx = IPPROTO_MPTCP;
static int proto_rx = IPPROTO_MPTCP;
+static bool tls;
#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
@@ -36,6 +38,9 @@ static int proto_rx = IPPROTO_MPTCP;
#ifndef SOL_MPTCP
#define SOL_MPTCP 284
#endif
+#ifndef TCP_ULP
+#define TCP_ULP 31
+#endif
#ifndef MPTCP_INFO
struct mptcp_info {
@@ -137,7 +142,7 @@ static void die_perror(const char *msg)
static void die_usage(int r)
{
- fprintf(stderr, "Usage: mptcp_sockopt [-6] [-t tcp|mptcp] [-r tcp|mptcp]\n");
+ fprintf(stderr, "Usage: mptcp_sockopt [-6] [-t tcp|mptcp] [-r tcp|mptcp] [-c]\n");
exit(r);
}
@@ -184,6 +189,54 @@ static void xgetaddrinfo(const char *node, const char *service,
}
}
+#define TLS_OVERHEAD_SIZE 29
+
+static int do_setsockopt_tls(int fd)
+{
+ struct tls12_crypto_info_aes_gcm_128 tls_tx = {
+ .info = {
+ .version = TLS_1_2_VERSION,
+ .cipher_type = TLS_CIPHER_AES_GCM_128,
+ },
+ };
+ struct tls12_crypto_info_aes_gcm_128 tls_rx = {
+ .info = {
+ .version = TLS_1_2_VERSION,
+ .cipher_type = TLS_CIPHER_AES_GCM_128,
+ },
+ };
+ int so_buf = 6553500;
+ int err;
+
+ err = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
+ if (err) {
+ perror("setsockopt TCP_ULP");
+ return err;
+ }
+ err = setsockopt(fd, SOL_TLS, TLS_TX, (void *)&tls_tx, sizeof(tls_tx));
+ if (err) {
+ perror("setsockopt TLS_TX");
+ return err;
+ }
+ err = setsockopt(fd, SOL_TLS, TLS_RX, (void *)&tls_rx, sizeof(tls_rx));
+ if (err) {
+ perror("setsockopt TLS_RX");
+ return err;
+ }
+ err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &so_buf, sizeof(so_buf));
+ if (err) {
+ perror("setsockopt SO_SNDBUF");
+ return err;
+ }
+ err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &so_buf, sizeof(so_buf));
+ if (err) {
+ perror("setsockopt SO_RCVBUF");
+ return err;
+ }
+
+ return 0;
+}
+
static int sock_listen_mptcp(const char * const listenaddr,
const char * const port)
{
@@ -276,7 +329,7 @@ static void parse_opts(int argc, char **argv)
{
int c;
- while ((c = getopt(argc, argv, "h6t:r:")) != -1) {
+ while ((c = getopt(argc, argv, "h6t:r:c")) != -1) {
switch (c) {
case 'h':
die_usage(0);
@@ -289,6 +342,8 @@ static void parse_opts(int argc, char **argv)
break;
case 'r':
proto_rx = protostr_to_num(optarg);
+ case 'c':
+ tls = true;
break;
default:
die_usage(1);
@@ -652,6 +707,11 @@ static void connect_one_server(int fd, int pipefd)
if (s.tcpi_rcv_delta)
assert(s.tcpi_rcv_delta <= total);
+ if (tls) {
+ ret += TLS_OVERHEAD_SIZE;
+ total += TLS_OVERHEAD_SIZE;
+ }
+
do_getsockopts(&s, fd, ret, ret);
if (eof)
@@ -692,6 +752,11 @@ static void process_one_client(int fd, int pipefd)
if (ret3 != 0)
xerror("expected EOF, got %lu", ret3);
+ if (tls) {
+ ret += TLS_OVERHEAD_SIZE;
+ ret2 += TLS_OVERHEAD_SIZE;
+ }
+
do_getsockopts(&s, fd, ret, ret2);
if (s.mptcpi_rcv_delta &&
s.mptcpi_rcv_delta != (uint64_t)ret + 1)
@@ -752,6 +817,9 @@ static int server(int pipefd)
alarm(15);
r = xaccept(fd);
+ if (tls)
+ do_setsockopt_tls(r);
+
process_one_client(r, pipefd);
close(fd);
@@ -815,6 +883,9 @@ static int client(int pipefd)
test_ip_tos_sockopt(fd);
+ if (tls)
+ do_setsockopt_tls(fd);
+
connect_one_server(fd, pipefd);
return 0;
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index ab8bce06b262..6dcc0a100094 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -351,6 +351,41 @@ do_tcpinq_tests()
return $?
}
+do_tls_test()
+{
+ print_title "KTLS $*" | head -c 53
+ ip netns exec "$ns_sbox" ./mptcp_sockopt "$@"
+ local lret=$?
+ if [ $lret -ne 0 ];then
+ ret=$lret
+ mptcp_lib_pr_fail
+ mptcp_lib_result_fail "KTLS: $*"
+ return $lret
+ fi
+
+ mptcp_lib_pr_ok
+ mptcp_lib_result_pass "KTLS: $*"
+ return $lret
+}
+
+do_tls_tests()
+{
+ local lret=0
+
+ mptcp_lib_print_info "sockopt KTLS"
+
+ local args
+ for args in "-c -t tcp -r tcp" "-6 -c -t tcp -r tcp"; do
+ do_tls_test $args
+ lret=$?
+ if [ $lret -ne 0 ] ; then
+ return $lret
+ fi
+ done
+
+ return $lret
+}
+
sin=$(mktemp)
sout=$(mktemp)
cin=$(mktemp)
@@ -366,6 +401,7 @@ run_tests $ns1 $ns2 dead:beef:1::1
do_mptcp_sockopt_tests
do_tcpinq_tests
+do_tls_tests
mptcp_lib_result_print_all_tap
exit $ret
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 4/8] tls: add MPTCP protocol support
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
` (2 preceding siblings ...)
2025-11-22 8:45 ` [RFC mptcp-next v3 3/8] selftests: mptcp: sockopt: implement TCP TLS tests Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 5/8] mptcp: update ULP getsockopt Geliang Tang
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
To extend MPTCP support based on TCP TLS, corresponding MPTCP-specific
helpers have been implemented, including:
- mptcp_sendmsg_locked() for TLS record transmission
- mptcp_inq_hint() and mptcp_recv_skb() for receive side handling
- mptcp_read_done() for data reading
- mptcp_disconnect() for connection teardown.
TLS implementation switches between the respective TCP and MPTCP helpers
based on the detected protocol.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/net/mptcp.h | 33 +++++++++++++++++++++++
net/mptcp/protocol.c | 62 +++++++++++++++++++++++++++++++++++++-------
net/tls/tls_device.c | 8 ++++--
net/tls/tls_main.c | 6 ++++-
net/tls/tls_strp.c | 16 +++++++++---
net/tls/tls_sw.c | 4 ++-
6 files changed, 113 insertions(+), 16 deletions(-)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 4cf59e83c1c5..1fca3bca439c 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -237,6 +237,16 @@ static inline __be32 mptcp_reset_option(const struct sk_buff *skb)
}
void mptcp_active_detect_blackhole(struct sock *sk, bool expired);
+
+int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len);
+
+unsigned int mptcp_inq_hint(const struct sock *sk);
+
+struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off);
+
+void mptcp_read_done(struct sock *sk, size_t len);
+
+int mptcp_disconnect(struct sock *sk, int flags);
#else
static inline void mptcp_init(void)
@@ -323,6 +333,29 @@ static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct reques
static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
static inline void mptcp_active_detect_blackhole(struct sock *sk, bool expired) { }
+
+static inline int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg,
+ size_t len)
+{
+ return 0;
+}
+
+static inline unsigned int mptcp_inq_hint(const struct sock *sk)
+{
+ return 0;
+}
+
+static inline struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
+{
+ return NULL;
+}
+
+static inline void mptcp_read_done(struct sock *sk, size_t len) { }
+
+static inline int mptcp_disconnect(struct sock *sk, int flags)
+{
+ return 0;
+}
#endif /* CONFIG_MPTCP */
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index b31724523ed5..5d796b42bc6b 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1752,8 +1752,6 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
}
}
-static int mptcp_disconnect(struct sock *sk, int flags);
-
static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
size_t len, int *copied_syn)
{
@@ -1862,7 +1860,7 @@ static void mptcp_rps_record_subflows(const struct mptcp_sock *msk)
}
}
-static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len)
{
struct mptcp_sock *msk = mptcp_sk(sk);
struct page_frag *pfrag;
@@ -1873,8 +1871,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
/* silently ignore everything else */
msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_FASTOPEN;
- lock_sock(sk);
-
mptcp_rps_record_subflows(msk);
if (unlikely(inet_test_bit(DEFER_CONNECT, sk) ||
@@ -1982,7 +1978,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
__mptcp_push_pending(sk, msg->msg_flags);
out:
- release_sock(sk);
return copied;
do_error:
@@ -1993,6 +1988,17 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
goto out;
}
+static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+{
+ int ret;
+
+ lock_sock(sk);
+ ret = mptcp_sendmsg_locked(sk, msg, len);
+ release_sock(sk);
+
+ return ret;
+}
+
static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied);
static void mptcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
@@ -2224,7 +2230,7 @@ static bool mptcp_move_skbs(struct sock *sk)
return enqueued;
}
-static unsigned int mptcp_inq_hint(const struct sock *sk)
+unsigned int mptcp_inq_hint(const struct sock *sk)
{
const struct mptcp_sock *msk = mptcp_sk(sk);
const struct sk_buff *skb;
@@ -3329,7 +3335,7 @@ static void mptcp_destroy_common(struct mptcp_sock *msk)
mptcp_pm_destroy(msk);
}
-static int mptcp_disconnect(struct sock *sk, int flags)
+int mptcp_disconnect(struct sock *sk, int flags)
{
struct mptcp_sock *msk = mptcp_sk(sk);
@@ -4271,7 +4277,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
return mask;
}
-static struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
+struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
{
struct mptcp_sock *msk = mptcp_sk(sk);
struct sk_buff *skb;
@@ -4453,6 +4459,44 @@ static ssize_t mptcp_splice_read(struct socket *sock, loff_t *ppos,
return ret;
}
+void mptcp_read_done(struct sock *sk, size_t len)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct sk_buff *skb;
+ size_t left;
+ u32 offset;
+
+ msk_owned_by_me(msk);
+
+ if (sk->sk_state == TCP_LISTEN)
+ return;
+
+ left = len;
+ while (left && (skb = mptcp_recv_skb(sk, &offset)) != NULL) {
+ int used;
+
+ used = min_t(size_t, skb->len - offset, left);
+ left -= used;
+ msk->bytes_consumed += used;
+ MPTCP_SKB_CB(skb)->offset += used;
+ MPTCP_SKB_CB(skb)->map_seq += used;
+
+ if (skb->len > offset + used)
+ break;
+
+ mptcp_eat_recv_skb(sk, skb);
+ }
+
+ mptcp_rcv_space_adjust(msk, len - left);
+
+ /* Clean up data we have read: This will do ACK frames. */
+ if (left != len) {
+ mptcp_recv_skb(sk, &offset);
+ mptcp_cleanup_rbuf(msk, len - left);
+ }
+}
+EXPORT_SYMBOL(mptcp_read_done);
+
static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index 82ea407e520a..9a69037b9a1f 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -805,7 +805,9 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
/* head of next rec is already in, note that the sock_inq will
* include the currently parsed message when called from parser
*/
- sock_data = tcp_inq(sk);
+ sock_data = sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_inq_hint(sk) :
+ tcp_inq(sk);
if (sock_data > rcd_len) {
trace_tls_device_rx_resync_nh_delay(sk, sock_data,
rcd_len);
@@ -864,7 +866,9 @@ static void tls_device_core_ctrl_rx_resync(struct tls_context *tls_ctx,
rxm = strp_msg(skb);
/* head of next rec is already in, parser will sync for us */
- if (tcp_inq(sk) > rxm->full_len) {
+ if ((sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_inq_hint(sk) :
+ tcp_inq(sk)) > rxm->full_len) {
trace_tls_device_rx_resync_nh_schedule(sk);
ctx->resync_nh_do_now = 1;
} else {
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 56ce0bc8317b..7d7bde1702c1 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -194,7 +194,9 @@ int tls_push_sg(struct sock *sk,
bvec_set_page(&bvec, p, size, offset);
iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
- ret = tcp_sendmsg_locked(sk, &msg, size);
+ ret = sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_sendmsg_locked(sk, &msg, size) :
+ tcp_sendmsg_locked(sk, &msg, size);
if (ret != size) {
if (ret > 0) {
@@ -907,6 +909,8 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
static int tls_disconnect(struct sock *sk, int flags)
{
+ if (sk->sk_protocol == IPPROTO_MPTCP)
+ return mptcp_disconnect(sk, flags);
return -EOPNOTSUPP;
}
diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
index 98e12f0ff57e..0fd19c6a579a 100644
--- a/net/tls/tls_strp.c
+++ b/net/tls/tls_strp.c
@@ -132,6 +132,8 @@ int tls_strp_msg_cow(struct tls_sw_context_rx *ctx)
tls_strp_anchor_free(strp);
strp->anchor = skb;
+ strp->sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_read_done(strp->sk, strp->stm.full_len) :
tcp_read_done(strp->sk, strp->stm.full_len);
strp->copy_mode = 1;
@@ -464,7 +466,9 @@ static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
struct sk_buff *first;
u32 offset;
- first = tcp_recv_skb(strp->sk, tp->copied_seq, &offset);
+ first = strp->sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_recv_skb(strp->sk, &offset) :
+ tcp_recv_skb(strp->sk, tp->copied_seq, &offset);
if (WARN_ON_ONCE(!first))
return;
@@ -490,7 +494,9 @@ bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
DEBUG_NET_WARN_ON_ONCE(!strp->stm.full_len);
if (!strp->copy_mode && force_refresh) {
- if (unlikely(tcp_inq(strp->sk) < strp->stm.full_len)) {
+ if (unlikely((strp->sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_inq_hint(strp->sk) :
+ tcp_inq(strp->sk)) < strp->stm.full_len)) {
WRITE_ONCE(strp->msg_ready, 0);
memset(&strp->stm, 0, sizeof(strp->stm));
return false;
@@ -513,7 +519,9 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
{
int sz, inq;
- inq = tcp_inq(strp->sk);
+ inq = strp->sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_inq_hint(strp->sk) :
+ tcp_inq(strp->sk);
if (inq < 1)
return 0;
@@ -586,6 +594,8 @@ void tls_strp_msg_done(struct tls_strparser *strp)
WARN_ON(!strp->stm.full_len);
if (likely(!strp->copy_mode))
+ strp->sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_read_done(strp->sk, strp->stm.full_len) :
tcp_read_done(strp->sk, strp->stm.full_len);
else
tls_strp_flush_anchor_copy(strp);
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 9937d4c810f2..375f6f8304c3 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -1958,7 +1958,9 @@ tls_read_flush_backlog(struct sock *sk, struct tls_prot_info *prot,
return false;
max_rec = prot->overhead_size - prot->tail_size + TLS_MAX_PAYLOAD_SIZE;
- if (done - *flushed_at < SZ_128K && tcp_inq(sk) > max_rec)
+ if (done - *flushed_at < SZ_128K && (sk->sk_protocol == IPPROTO_MPTCP ?
+ mptcp_inq_hint(sk) :
+ tcp_inq(sk)) > max_rec)
return false;
*flushed_at = done;
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 5/8] mptcp: update ULP getsockopt
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
` (3 preceding siblings ...)
2025-11-22 8:45 ` [RFC mptcp-next v3 4/8] tls: add MPTCP protocol support Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 6/8] mptcp: enable TLS setsockopt Geliang Tang
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
TCP_ULP was obtained by calling mptcp_getsockopt_first_sf_only() to get
the ULP of the first subflow. Now that the mechanism has changed, a new
helper needs to be implemented to get the ULP of the msk.
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/sockopt.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index de90a2897d2d..f3db4f2e8f81 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -1393,6 +1393,17 @@ static int mptcp_put_int_option(struct mptcp_sock *msk, char __user *optval,
return 0;
}
+static int mptcp_getsockopt_msk(struct sock *sk, int level, int optname,
+ char __user *optval, int __user *optlen)
+{
+ int ret;
+
+ lock_sock(sk);
+ ret = tcp_getsockopt(sk, level, optname, optval, optlen);
+ release_sock(sk);
+ return ret;
+}
+
static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
char __user *optval, int __user *optlen)
{
@@ -1400,6 +1411,7 @@ static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
switch (optname) {
case TCP_ULP:
+ return mptcp_getsockopt_msk(sk, SOL_TCP, optname, optval, optlen);
case TCP_CONGESTION:
case TCP_INFO:
case TCP_CC_INFO:
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 6/8] mptcp: enable TLS setsockopt
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
` (4 preceding siblings ...)
2025-11-22 8:45 ` [RFC mptcp-next v3 5/8] mptcp: update ULP getsockopt Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 7/8] selftests: mptcp: connect: update sock_test_tcpulp Geliang Tang
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch adds MPTCP TLS setsockopt support. It allows setting the TCP_ULP
option to 'tls' exclusively, and enables configuration of the TLS_TX and
TLS_RX options at the SOL_TLS level.
This option cannot be set when the socket is in CLOSE or LISTEN state.
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/sockopt.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index f3db4f2e8f81..52ff75702404 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;
}
@@ -576,6 +578,13 @@ static bool mptcp_supported_sockopt(int level, int optname)
* TCP_REPAIR_WINDOW are not supported, better avoid this mess
*/
}
+ if (level == SOL_TLS) {
+ switch (optname) {
+ case TLS_TX:
+ case TLS_RX:
+ return true;
+ }
+ }
return false;
}
@@ -819,11 +828,18 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
sockptr_t optval, unsigned int optlen)
{
struct sock *sk = (void *)msk;
+ char ulp[4] = "";
int ret, val;
switch (optname) {
case TCP_ULP:
- return -EOPNOTSUPP;
+ if (copy_from_user(ulp, optval.user, 4))
+ return -EFAULT;
+ if (strcmp(ulp, "tls\0"))
+ return -EOPNOTSUPP;
+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
+ return -EINVAL;
+ return tcp_setsockopt(sk, SOL_TCP, optname, optval, optlen);
case TCP_CONGESTION:
return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen);
case TCP_DEFER_ACCEPT:
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 7/8] selftests: mptcp: connect: update sock_test_tcpulp
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
` (5 preceding siblings ...)
2025-11-22 8:45 ` [RFC mptcp-next v3 6/8] mptcp: enable TLS setsockopt Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 8:45 ` [RFC mptcp-next v3 8/8] selftests: mptcp: sockopt: cover MPTCP KTLS test cases Geliang Tang
2025-11-22 11:15 ` [RFC mptcp-next v3 0/8] MPTCP KTLS support MPTCP CI
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
Improve sock_test_tcpulp() to properly validate TLS ULP setup on MPTCP
sockets. The updated logic verifies that TLS can be correctly configured
based on the socket protocol type and state.
fallback() helper has been implemented to verify fallback scenarios,
ensuring that MPTCP fallback-to-TCP tests continue to pass.
Initialize 'peer' pointer to NULL in main_loop() to fix the compiler
warning 'peer' may be used uninitialized.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_connect.c | 36 ++++++++++++-------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index 2e50d6f93640..64c1a57fe72b 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -266,13 +266,25 @@ static void set_mptfo(int fd, int pf)
perror("TCP_FASTOPEN");
}
+static int fallback(int fd)
+{
+ int is_mptcp = 0;
+ socklen_t optlen;
+
+ optlen = sizeof(is_mptcp);
+ if (getsockopt(fd, IPPROTO_TCP, TCP_IS_MPTCP, &is_mptcp, &optlen) == -1)
+ perror("TCP_IS_MPTCP");
+
+ return !is_mptcp;
+}
+
static int do_ulp_so(int sock, const char *name)
{
return setsockopt(sock, IPPROTO_TCP, TCP_ULP, name, strlen(name));
}
#define X(m) xerror("%s:%u: %s: failed for proto %d at line %u", __FILE__, __LINE__, (m), proto, line)
-static void sock_test_tcpulp(int sock, int proto, unsigned int line)
+static void sock_test_tcpulp(int sock, int proto, int expect, unsigned int line)
{
socklen_t buflen = 8;
char buf[8] = "";
@@ -282,14 +294,14 @@ static void sock_test_tcpulp(int sock, int proto, unsigned int line)
X("getsockopt");
if (buflen > 0) {
- if (strcmp(buf, "mptcp") != 0)
+ if (strcmp(buf, fallback(sock) ? "mptcp" : "tls") != 0)
xerror("unexpected ULP '%s' for proto %d at line %u", buf, proto, line);
ret = do_ulp_so(sock, "tls");
if (ret == 0)
X("setsockopt");
} else if (proto == IPPROTO_MPTCP) {
ret = do_ulp_so(sock, "tls");
- if (ret != -1)
+ if (ret != expect)
X("setsockopt");
}
@@ -300,7 +312,7 @@ static void sock_test_tcpulp(int sock, int proto, unsigned int line)
#undef X
}
-#define SOCK_TEST_TCPULP(s, p) sock_test_tcpulp((s), (p), __LINE__)
+#define SOCK_TEST_TCPULP(s, p, e) sock_test_tcpulp((s), (p), (e), __LINE__)
static int sock_listen_mptcp(const char * const listenaddr,
const char * const port)
@@ -325,7 +337,7 @@ static int sock_listen_mptcp(const char * const listenaddr,
if (sock < 0)
continue;
- SOCK_TEST_TCPULP(sock, cfg_sock_proto);
+ SOCK_TEST_TCPULP(sock, cfg_sock_proto, -1);
if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof(one)))
@@ -352,7 +364,7 @@ static int sock_listen_mptcp(const char * const listenaddr,
return sock;
}
- SOCK_TEST_TCPULP(sock, cfg_sock_proto);
+ SOCK_TEST_TCPULP(sock, cfg_sock_proto, -1);
if (listen(sock, 20)) {
perror("listen");
@@ -360,7 +372,7 @@ static int sock_listen_mptcp(const char * const listenaddr,
return -1;
}
- SOCK_TEST_TCPULP(sock, cfg_sock_proto);
+ SOCK_TEST_TCPULP(sock, cfg_sock_proto, -1);
return sock;
}
@@ -388,7 +400,7 @@ static int sock_connect_mptcp(const char * const remoteaddr,
continue;
}
- SOCK_TEST_TCPULP(sock, proto);
+ SOCK_TEST_TCPULP(sock, proto, -1);
if (cfg_mark)
set_mark(sock, cfg_mark);
@@ -425,7 +437,7 @@ static int sock_connect_mptcp(const char * const remoteaddr,
freeaddrinfo(addr);
if (sock != -1)
- SOCK_TEST_TCPULP(sock, proto);
+ SOCK_TEST_TCPULP(sock, proto, fallback(sock) ? -1 : 0);
return sock;
}
@@ -1202,7 +1214,7 @@ int main_loop_s(int listensock)
xerror("can't open %s: %d", cfg_input, errno);
}
- SOCK_TEST_TCPULP(remotesock, 0);
+ SOCK_TEST_TCPULP(remotesock, 0, 0);
memset(&winfo, 0, sizeof(winfo));
err = copyfd_io(fd, remotesock, 1, true, &winfo);
@@ -1364,7 +1376,7 @@ void xdisconnect(int fd)
int main_loop(void)
{
int fd = 0, ret, fd_in = 0;
- struct addrinfo *peer;
+ struct addrinfo *peer = NULL;
struct wstate winfo;
if (cfg_input && cfg_sockopt_types.mptfo) {
@@ -1381,7 +1393,7 @@ int main_loop(void)
again:
check_getpeername_connect(fd);
- SOCK_TEST_TCPULP(fd, cfg_sock_proto);
+ SOCK_TEST_TCPULP(fd, cfg_sock_proto, -1);
if (cfg_rcvbuf)
set_rcvbuf(fd, cfg_rcvbuf);
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC mptcp-next v3 8/8] selftests: mptcp: sockopt: cover MPTCP KTLS test cases
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
` (6 preceding siblings ...)
2025-11-22 8:45 ` [RFC mptcp-next v3 7/8] selftests: mptcp: connect: update sock_test_tcpulp Geliang Tang
@ 2025-11-22 8:45 ` Geliang Tang
2025-11-22 11:15 ` [RFC mptcp-next v3 0/8] MPTCP KTLS support MPTCP CI
8 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2025-11-22 8:45 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
Now that MPTCP KTLS support is implemented, extend the existing TCP KTLS
test cases to cover MPTCP for both IPv4 and IPv6.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 6dcc0a100094..c1f99dd1532b 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -375,7 +375,7 @@ do_tls_tests()
mptcp_lib_print_info "sockopt KTLS"
local args
- for args in "-c -t tcp -r tcp" "-6 -c -t tcp -r tcp"; do
+ for args in "-c -t tcp -r tcp" "-6 -c -t tcp -r tcp" "-c" "-6 -c"; do
do_tls_test $args
lret=$?
if [ $lret -ne 0 ] ; then
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC mptcp-next v3 0/8] MPTCP KTLS support
2025-11-22 8:45 [RFC mptcp-next v3 0/8] MPTCP KTLS support Geliang Tang
` (7 preceding siblings ...)
2025-11-22 8:45 ` [RFC mptcp-next v3 8/8] selftests: mptcp: sockopt: cover MPTCP KTLS test cases Geliang Tang
@ 2025-11-22 11:15 ` MPTCP CI
8 siblings, 0 replies; 10+ messages in thread
From: MPTCP CI @ 2025-11-22 11:15 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp
Hi Geliang,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Unstable: 1 failed test(s): packetdrill_dss 🔴
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Unstable: 1 failed test(s): packetdrill_dss 🔴
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/19593304037
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/943bd20791d6
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1026573
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
^ permalink raw reply [flat|nested] 10+ messages in thread