* [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt
@ 2025-08-26 9:29 Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 01/14] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
v3:
- No longer using process_one_client_inq() and connect_one_server_inq()
for switching; instead, the inq-related code has been merged into
process_one_client() and connect_one_server().
v2:
- patch 4, a new patch, add do_setsockopt_inq helper.
- cleanups.
- https://patchwork.kernel.org/project/mptcp/cover/cover.1754664106.git.tanggeliang@kylinos.cn/
v1:
- https://patchwork.kernel.org/project/mptcp/cover/cover.1754620968.git.tanggeliang@kylinos.cn/
This series consolidates the TCP_INQ test functionality from mptcp_inq
into mptcp_sockopt, simplifying the test suite while maintaining full
test coverage.
Geliang Tang (14):
selftests: mptcp: sockopt: replace /dev/urandom with getrandom
selftests: mptcp: sockopt: add protocol arguments
selftests: mptcp: sockopt: add inq argument
selftests: mptcp: sockopt: set TCP_INQ on accepted sockets
selftests: mptcp: sockopt: use unix socket instead of pipe
selftests: mptcp: sockopt: read eof at the end of process_one_client
selftests: mptcp: sockopt: use recvmsg instead of read
selftests: mptcp: sockopt: read one byte first
selftests: mptcp: sockopt: add large data transfer tests
selftests: mptcp: sockopt: add wait_for_ack
selftests: mptcp: sockopt: set FIONREAD ioctl
selftests: mptcp: sockopt: add check_tcp_inq helper
selftests: mptcp: sockopt: replace mptcp_inq with sockopt
selftests: mptcp: sockopt: remove obsolete mptcp_inq
tools/testing/selftests/net/mptcp/.gitignore | 1 -
tools/testing/selftests/net/mptcp/Makefile | 2 +-
tools/testing/selftests/net/mptcp/mptcp_inq.c | 608 ------------------
.../selftests/net/mptcp/mptcp_sockopt.c | 346 ++++++++--
.../selftests/net/mptcp/mptcp_sockopt.sh | 8 +-
5 files changed, 296 insertions(+), 669 deletions(-)
delete mode 100644 tools/testing/selftests/net/mptcp/mptcp_inq.c
--
2.48.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 01/14] selftests: mptcp: sockopt: replace /dev/urandom with getrandom
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 02/14] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Replace /dev/urandom with getrandom() for initializing the RNG. This
simplifies the code and avoids potential failures from opening device
files while maintaining cryptographic quality randomness.
These codes are from mptcp_inq.c.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 20 +++++++------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index e934dd26a59d..2bd75f731dfd 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -20,6 +20,7 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/random.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -815,21 +816,14 @@ static int rcheck(int wstatus, const char *what)
static void init_rng(void)
{
- int fd = open("/dev/urandom", O_RDONLY);
+ unsigned int foo;
- if (fd >= 0) {
- unsigned int foo;
- ssize_t ret;
-
- /* can't fail */
- ret = read(fd, &foo, sizeof(foo));
- assert(ret == sizeof(foo));
-
- close(fd);
- srand(foo);
- } else {
- srand(time(NULL));
+ if (getrandom(&foo, sizeof(foo), 0) == -1) {
+ perror("getrandom");
+ exit(1);
}
+
+ srand(foo);
}
int main(int argc, char *argv[])
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 02/14] selftests: mptcp: sockopt: add protocol arguments
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 01/14] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 03/14] selftests: mptcp: sockopt: add inq argument Geliang Tang
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
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.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 36 +++++++++++++++----
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 2bd75f731dfd..05caa9a57ac4 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -28,6 +28,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
@@ -136,7 +138,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);
}
@@ -202,7 +204,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;
@@ -260,11 +262,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);
@@ -272,6 +285,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;
@@ -557,6 +576,9 @@ static void do_getsockopt_mptcp_full_info(struct so_state *s, int fd)
static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
{
+ if (proto_tx != IPPROTO_MPTCP || proto_rx != IPPROTO_MPTCP)
+ return;
+
do_getsockopt_mptcp_info(s, fd, w);
do_getsockopt_tcp_info(s, fd, r, w);
@@ -632,7 +654,7 @@ 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);
+ assert(s.mptcpi_rcv_delta ? s.mptcpi_rcv_delta == (uint64_t)total : true);
close(fd);
}
@@ -667,7 +689,7 @@ 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, s.mptcpi_rcv_delta, ret + 1, s.mptcpi_rcv_delta - ret);
/* be nice when running on top of older kernel */
@@ -772,10 +794,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.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 03/14] selftests: mptcp: sockopt: add inq argument
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 01/14] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 02/14] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 04/14] selftests: mptcp: sockopt: set TCP_INQ on accepted sockets Geliang Tang
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Introduce -i option to enable TCP_INQ testing. This prepares for
consolidating TCP_INQ tests into a single binary by adding the necessary
command-line interface.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/mptcp_sockopt.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 05caa9a57ac4..cb3d8dc34997 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -30,6 +30,7 @@
static int pf = AF_INET;
static int proto_tx = IPPROTO_MPTCP;
static int proto_rx = IPPROTO_MPTCP;
+static bool inq;
#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
@@ -138,7 +139,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] [-i]\n");
exit(r);
}
@@ -277,7 +278,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:i")) != -1) {
switch (c) {
case 'h':
die_usage(0);
@@ -291,6 +292,9 @@ static void parse_opts(int argc, char **argv)
case 'r':
proto_rx = protostr_to_num(optarg);
break;
+ case 'i':
+ inq = true;
+ break;
default:
die_usage(1);
break;
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 04/14] selftests: mptcp: sockopt: set TCP_INQ on accepted sockets
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (2 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 03/14] selftests: mptcp: sockopt: add inq argument Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 05/14] selftests: mptcp: sockopt: use unix socket instead of pipe Geliang Tang
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Add helper functions to conditionally set TCP_INQ sockopt on accepted
sockets when running in inq mode. This ensures proper testing of TCP_CM_INQ
functionality by enabling the required socket option on both ends of the
connection. This setup is necessary for validating TCP_CM_INQ behavior
during TCP_INQ-specific tests.
These codes are from mptcp_inq.c.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/mptcp_sockopt.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index cb3d8dc34997..366e4aa4df0b 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -715,6 +715,14 @@ static void process_one_client(int fd, int pipefd)
close(fd);
}
+static void do_setsockopt_inq(int fd)
+{
+ int on = 1;
+
+ if (setsockopt(fd, IPPROTO_TCP, TCP_INQ, &on, sizeof(on)))
+ die_perror("setsockopt(TCP_INQ)");
+}
+
static int xaccept(int s)
{
int fd = accept(s, NULL, 0);
@@ -722,6 +730,9 @@ static int xaccept(int s)
if (fd < 0)
die_perror("accept");
+ if (inq)
+ do_setsockopt_inq(fd);
+
return fd;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 05/14] selftests: mptcp: sockopt: use unix socket instead of pipe
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (3 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 04/14] selftests: mptcp: sockopt: set TCP_INQ on accepted sockets Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 06/14] selftests: mptcp: sockopt: read eof at the end of process_one_client Geliang Tang
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Replaces pipe-based synchronization with Unix domain socket pairs
(SOCK_DGRAM) for better bidirectional communication reliability
between server and client processes.
These codes are from mptcp_inq.c.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 36 +++++++++----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 366e4aa4df0b..add29bdda9e5 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -593,7 +593,7 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
do_getsockopt_mptcp_full_info(s, fd);
}
-static void connect_one_server(int fd, int pipefd)
+static void connect_one_server(int fd, int unixfd)
{
char buf[4096], buf2[4096];
size_t len, i, total;
@@ -618,9 +618,9 @@ static void connect_one_server(int fd, int pipefd)
do_getsockopts(&s, fd, 0, 0);
/* un-block server */
- ret = read(pipefd, buf2, 4);
+ ret = read(unixfd, buf2, 4);
assert(ret == 4);
- close(pipefd);
+ close(unixfd);
assert(strncmp(buf2, "xmit", 4) == 0);
@@ -662,7 +662,7 @@ static void connect_one_server(int fd, int pipefd)
close(fd);
}
-static void process_one_client(int fd, int pipefd)
+static void process_one_client(int fd, int unixfd)
{
ssize_t ret, ret2, ret3;
struct so_state s;
@@ -671,7 +671,7 @@ static void process_one_client(int fd, int pipefd)
memset(&s, 0, sizeof(s));
do_getsockopts(&s, fd, 0, 0);
- ret = write(pipefd, "xmit", 4);
+ ret = write(unixfd, "xmit", 4);
assert(ret == 4);
ret = read(fd, buf, sizeof(buf));
@@ -736,7 +736,7 @@ static int xaccept(int s)
return fd;
}
-static int server(int pipefd)
+static int server(int unixfd)
{
int fd = -1, r;
@@ -752,13 +752,13 @@ static int server(int pipefd)
break;
}
- r = write(pipefd, "conn", 4);
+ r = write(unixfd, "conn", 4);
assert(r == 4);
alarm(15);
r = xaccept(fd);
- process_one_client(r, pipefd);
+ process_one_client(r, unixfd);
return 0;
}
@@ -801,7 +801,7 @@ static void test_ip_tos_sockopt(int fd)
xerror("expect socklen_t == -1");
}
-static int client(int pipefd)
+static int client(int unixfd)
{
int fd = -1;
@@ -820,7 +820,7 @@ static int client(int pipefd)
test_ip_tos_sockopt(fd);
- connect_one_server(fd, pipefd);
+ connect_one_server(fd, unixfd);
return 0;
}
@@ -867,31 +867,31 @@ int main(int argc, char *argv[])
{
int e1, e2, wstatus;
pid_t s, c, ret;
- int pipefds[2];
+ int unixfds[2];
parse_opts(argc, argv);
init_rng();
- e1 = pipe(pipefds);
+ e1 = socketpair(AF_UNIX, SOCK_DGRAM, 0, unixfds);
if (e1 < 0)
- die_perror("pipe");
+ die_perror("socketpair");
s = xfork();
if (s == 0)
- return server(pipefds[1]);
+ return server(unixfds[1]);
- close(pipefds[1]);
+ close(unixfds[1]);
/* wait until server bound a socket */
- e1 = read(pipefds[0], &e1, 4);
+ e1 = read(unixfds[0], &e1, 4);
assert(e1 == 4);
c = xfork();
if (c == 0)
- return client(pipefds[0]);
+ return client(unixfds[0]);
- close(pipefds[0]);
+ close(unixfds[0]);
ret = waitpid(s, &wstatus, 0);
if (ret == -1)
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 06/14] selftests: mptcp: sockopt: read eof at the end of process_one_client
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (4 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 05/14] selftests: mptcp: sockopt: use unix socket instead of pipe Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 07/14] selftests: mptcp: sockopt: use recvmsg instead of read Geliang Tang
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Moves EOF read handling to the end of process_one_client to ensure proper
synchronization after processing all data transfers, preparing for TCP_INQ
support in subsequent patches.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/mptcp_sockopt.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index add29bdda9e5..d69b10d2dbe3 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -687,14 +687,9 @@ static void process_one_client(int fd, int unixfd)
if (ret2 < 0)
die_perror("write");
- /* wait for hangup */
- ret3 = read(fd, buf, 1);
- if (ret3 != 0)
- xerror("expected EOF, got %lu", ret3);
-
do_getsockopts(&s, fd, ret, ret2);
- if (s.mptcpi_rcv_delta && s.mptcpi_rcv_delta != (uint64_t)ret + 1)
- xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64, s.mptcpi_rcv_delta, ret + 1, s.mptcpi_rcv_delta - ret);
+ if (s.mptcpi_rcv_delta && s.mptcpi_rcv_delta != (uint64_t)ret)
+ xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64, s.mptcpi_rcv_delta, ret, s.mptcpi_rcv_delta - ret);
/* be nice when running on top of older kernel */
if (s.pkt_stats_avail) {
@@ -712,6 +707,11 @@ static void process_one_client(int fd, int unixfd)
s.last_sample.mptcpi_bytes_acked - ret2);
}
+ /* wait for hangup */
+ ret3 = read(fd, buf, 1);
+ if (ret3 != 0)
+ xerror("expected EOF, got %lu", ret3);
+
close(fd);
}
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 07/14] selftests: mptcp: sockopt: use recvmsg instead of read
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (5 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 06/14] selftests: mptcp: sockopt: read eof at the end of process_one_client Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 08/14] selftests: mptcp: sockopt: read one byte first Geliang Tang
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Replaces read() with recvmsg() to enable control message (CMSG) handling,
preparing for TCP_INQ support in subsequent patches.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index d69b10d2dbe3..71cb311fcc50 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -665,8 +665,19 @@ static void connect_one_server(int fd, int unixfd)
static void process_one_client(int fd, int unixfd)
{
ssize_t ret, ret2, ret3;
+ char msg_buf[4096];
struct so_state s;
char buf[4096];
+ struct iovec iov = {
+ .iov_base = buf,
+ .iov_len = 1,
+ };
+ struct msghdr msg = {
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = msg_buf,
+ .msg_controllen = sizeof(msg_buf),
+ };
memset(&s, 0, sizeof(s));
do_getsockopts(&s, fd, 0, 0);
@@ -674,9 +685,10 @@ static void process_one_client(int fd, int unixfd)
ret = write(unixfd, "xmit", 4);
assert(ret == 4);
- ret = read(fd, buf, sizeof(buf));
+ iov.iov_len = sizeof(buf);
+ ret = recvmsg(fd, &msg, 0);
if (ret < 0)
- die_perror("read");
+ die_perror("recvmsg");
assert(s.mptcpi_rcv_delta <= (uint64_t)ret);
@@ -708,7 +720,8 @@ static void process_one_client(int fd, int unixfd)
}
/* wait for hangup */
- ret3 = read(fd, buf, 1);
+ iov.iov_len = 1;
+ ret3 = recvmsg(fd, &msg, 0);
if (ret3 != 0)
xerror("expected EOF, got %lu", ret3);
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 08/14] selftests: mptcp: sockopt: read one byte first
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (6 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 07/14] selftests: mptcp: sockopt: use recvmsg instead of read Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 09/14] selftests: mptcp: sockopt: add large data transfer tests Geliang Tang
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Modifies data reading to first read one byte, then the remainder, ensuring
accurate TCP_INQ validation and data consistency checks.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 28 ++++++++++++-------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 71cb311fcc50..675ed2dcee9f 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -642,18 +642,18 @@ static void connect_one_server(int fd, int unixfd)
}
total += ret;
- } while (total < len);
+ } while (total < len - 1);
- if (total != len)
- xerror("total %lu, len %lu eof %d\n", total, len, eof);
+ if (total != len - 1)
+ xerror("total %lu, len - 1 %lu eof %d\n", total, len - 1, eof);
- if (memcmp(buf, buf2, len))
+ if (memcmp(buf + 1, buf2, len - 1))
xerror("data corruption");
if (s.tcpi_rcv_delta)
assert(s.tcpi_rcv_delta <= total);
- do_getsockopts(&s, fd, ret, ret);
+ do_getsockopts(&s, fd, ret, ret + 1);
if (eof)
total += 1; /* sequence advances due to FIN */
@@ -685,6 +685,14 @@ static void process_one_client(int fd, int unixfd)
ret = write(unixfd, "xmit", 4);
assert(ret == 4);
+ /* read one byte, expect cmsg to return expected - 1 */
+ ret = recvmsg(fd, &msg, 0);
+ if (ret < 0)
+ die_perror("recvmsg");
+
+ if (inq && msg.msg_controllen == 0)
+ xerror("msg_controllen is 0");
+
iov.iov_len = sizeof(buf);
ret = recvmsg(fd, &msg, 0);
if (ret < 0)
@@ -699,9 +707,9 @@ static void process_one_client(int fd, int unixfd)
if (ret2 < 0)
die_perror("write");
- do_getsockopts(&s, fd, ret, ret2);
- if (s.mptcpi_rcv_delta && s.mptcpi_rcv_delta != (uint64_t)ret)
- xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64, s.mptcpi_rcv_delta, ret, s.mptcpi_rcv_delta - ret);
+ do_getsockopts(&s, fd, ret + 1, ret2);
+ if (s.mptcpi_rcv_delta && s.mptcpi_rcv_delta != (uint64_t)ret + 1)
+ xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64, s.mptcpi_rcv_delta, ret + 1, s.mptcpi_rcv_delta - ret);
/* be nice when running on top of older kernel */
if (s.pkt_stats_avail) {
@@ -709,9 +717,9 @@ static void process_one_client(int fd, int unixfd)
xerror("mptcpi_bytes_sent %" PRIu64 ", expect %" PRIu64,
s.last_sample.mptcpi_bytes_sent, ret2,
s.last_sample.mptcpi_bytes_sent - ret2);
- if (s.last_sample.mptcpi_bytes_received != ret)
+ if (s.last_sample.mptcpi_bytes_received != ret + 1)
xerror("mptcpi_bytes_received %" PRIu64 ", expect %" PRIu64,
- s.last_sample.mptcpi_bytes_received, ret,
+ s.last_sample.mptcpi_bytes_received, ret + 1,
s.last_sample.mptcpi_bytes_received - ret);
if (s.last_sample.mptcpi_bytes_acked != ret)
xerror("mptcpi_bytes_acked %" PRIu64 ", expect %" PRIu64,
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 09/14] selftests: mptcp: sockopt: add large data transfer tests
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (7 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 08/14] selftests: mptcp: sockopt: read one byte first Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 10/14] selftests: mptcp: sockopt: add wait_for_ack Geliang Tang
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Introduces large data transfer tests (1-17 MB) to validate MPTCP socket
options under high-volume conditions, including proper EOF handling,
preparing for TCP_INQ support in subsequent patches.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 90 ++++++++++++++++++-
1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 675ed2dcee9f..fc65157a41ee 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -620,10 +620,12 @@ static void connect_one_server(int fd, int unixfd)
/* un-block server */
ret = read(unixfd, buf2, 4);
assert(ret == 4);
- close(unixfd);
assert(strncmp(buf2, "xmit", 4) == 0);
+ ret = write(unixfd, &len, sizeof(len));
+ assert(ret == (ssize_t)sizeof(len));
+
ret = write(fd, buf, len);
if (ret < 0)
die_perror("write");
@@ -659,14 +661,51 @@ static void connect_one_server(int fd, int unixfd)
total += 1; /* sequence advances due to FIN */
assert(s.mptcpi_rcv_delta ? s.mptcpi_rcv_delta == (uint64_t)total : true);
+
+ ret = read(unixfd, buf2, 4);
+ assert(strncmp(buf2, "huge", 4) == 0);
+
+ total = rand() % (16 * 1024 * 1024);
+ total += (1 * 1024 * 1024);
+
+ ret = write(unixfd, &total, sizeof(total));
+ assert(ret == (ssize_t)sizeof(total));
+
+ while (total > 0) {
+ if (total > sizeof(buf))
+ len = sizeof(buf);
+ else
+ len = total;
+
+ ret = write(fd, buf, len);
+ if (ret < 0)
+ die_perror("write");
+ total -= ret;
+
+ /* we don't have to care about buf content, only
+ * number of total bytes sent
+ */
+ }
+
+ ret = read(unixfd, buf2, 4);
+ assert(ret == 4);
+ assert(strncmp(buf2, "shut", 4) == 0);
+
+ ret = write(fd, buf, 1);
+ assert(ret == 1);
close(fd);
+ ret = write(unixfd, "closed", 6);
+ assert(ret == 6);
+
+ close(unixfd);
}
static void process_one_client(int fd, int unixfd)
{
- ssize_t ret, ret2, ret3;
+ ssize_t ret, ret2, ret3, tot;
char msg_buf[4096];
struct so_state s;
+ size_t expect_len;
char buf[4096];
struct iovec iov = {
.iov_base = buf,
@@ -678,6 +717,7 @@ static void process_one_client(int fd, int unixfd)
.msg_control = msg_buf,
.msg_controllen = sizeof(msg_buf),
};
+ char tmp[16];
memset(&s, 0, sizeof(s));
do_getsockopts(&s, fd, 0, 0);
@@ -685,6 +725,12 @@ static void process_one_client(int fd, int unixfd)
ret = write(unixfd, "xmit", 4);
assert(ret == 4);
+ ret = read(unixfd, &expect_len, sizeof(expect_len));
+ assert(ret == (ssize_t)sizeof(expect_len));
+
+ if (expect_len > sizeof(buf))
+ xerror("expect len %zu exceeds buffer size", expect_len);
+
/* read one byte, expect cmsg to return expected - 1 */
ret = recvmsg(fd, &msg, 0);
if (ret < 0)
@@ -703,6 +749,9 @@ static void process_one_client(int fd, int unixfd)
if (s.tcpi_rcv_delta)
assert(s.tcpi_rcv_delta == (uint64_t)ret);
+ /* should have gotten exact remainder of all pending data */
+ assert(ret == (ssize_t)expect_len - 1);
+
ret2 = write(fd, buf, ret);
if (ret2 < 0)
die_perror("write");
@@ -727,6 +776,43 @@ static void process_one_client(int fd, int unixfd)
s.last_sample.mptcpi_bytes_acked - ret2);
}
+ /* request a large swath of data. */
+ ret = write(unixfd, "huge", 4);
+ assert(ret == 4);
+
+ ret = read(unixfd, &expect_len, sizeof(expect_len));
+ assert(ret == (ssize_t)sizeof(expect_len));
+
+ /* peer should send us a few mb of data */
+ if (expect_len <= sizeof(buf))
+ xerror("expect len %zu too small\n", expect_len);
+
+ tot = 0;
+ do {
+ iov.iov_len = sizeof(buf);
+ ret = recvmsg(fd, &msg, 0);
+ if (ret < 0)
+ die_perror("recvmsg");
+
+ tot += ret;
+ } while ((size_t)tot < expect_len);
+
+ ret = write(unixfd, "shut", 4);
+ assert(ret == 4);
+
+ /* wait for hangup. Should have received one more byte of data. */
+ ret = read(unixfd, tmp, sizeof(tmp));
+ assert(ret == 6);
+ assert(strncmp(tmp, "closed", 6) == 0);
+
+ sleep(1);
+
+ iov.iov_len = 1;
+ ret = recvmsg(fd, &msg, 0);
+ if (ret < 0)
+ die_perror("recvmsg");
+ assert(ret == 1);
+
/* wait for hangup */
iov.iov_len = 1;
ret3 = recvmsg(fd, &msg, 0);
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 10/14] selftests: mptcp: sockopt: add wait_for_ack
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (8 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 09/14] selftests: mptcp: sockopt: add large data transfer tests Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 11/14] selftests: mptcp: sockopt: set FIONREAD ioctl Geliang Tang
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Adds wait_for_ack() helper using TIOCOUTQ/SIOCOUTQNSD ioctls to synchronize
tests by waiting for data acknowledgment before proceeding.
These codes are from mptcp_inq.c.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 42 ++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index fc65157a41ee..b8e8fec8979f 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -21,11 +21,13 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/random.h>
+#include <sys/ioctl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <linux/tcp.h>
+#include <linux/sockios.h>
static int pf = AF_INET;
static int proto_tx = IPPROTO_MPTCP;
@@ -593,10 +595,43 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
do_getsockopt_mptcp_full_info(s, fd);
}
+/* wait up to timeout milliseconds */
+static void wait_for_ack(int fd, int timeout, size_t total)
+{
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ int nsd, ret, queued = -1;
+ struct timespec req;
+
+ ret = ioctl(fd, TIOCOUTQ, &queued);
+ if (ret < 0)
+ die_perror("TIOCOUTQ");
+
+ ret = ioctl(fd, SIOCOUTQNSD, &nsd);
+ if (ret < 0)
+ die_perror("SIOCOUTQNSD");
+
+ if ((size_t)queued > total)
+ xerror("TIOCOUTQ %u, but only %zu expected\n", queued, total);
+ assert(nsd <= queued);
+
+ if (queued == 0)
+ return;
+
+ /* wait for peer to ack rx of all data */
+ req.tv_sec = 0;
+ req.tv_nsec = 1 * 1000 * 1000ul; /* 1ms */
+ nanosleep(&req, NULL);
+ }
+
+ xerror("still tx data queued after %u ms\n", timeout);
+}
+
static void connect_one_server(int fd, int unixfd)
{
char buf[4096], buf2[4096];
- size_t len, i, total;
+ size_t len, i, total, sent;
struct so_state s;
bool eof = false;
ssize_t ret;
@@ -667,10 +702,13 @@ static void connect_one_server(int fd, int unixfd)
total = rand() % (16 * 1024 * 1024);
total += (1 * 1024 * 1024);
+ sent = total;
ret = write(unixfd, &total, sizeof(total));
assert(ret == (ssize_t)sizeof(total));
+ wait_for_ack(fd, 5000, len);
+
while (total > 0) {
if (total > sizeof(buf))
len = sizeof(buf);
@@ -691,6 +729,8 @@ static void connect_one_server(int fd, int unixfd)
assert(ret == 4);
assert(strncmp(buf2, "shut", 4) == 0);
+ wait_for_ack(fd, 5000, sent);
+
ret = write(fd, buf, 1);
assert(ret == 1);
close(fd);
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 11/14] selftests: mptcp: sockopt: set FIONREAD ioctl
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (9 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 10/14] selftests: mptcp: sockopt: add wait_for_ack Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 12/14] selftests: mptcp: sockopt: add check_tcp_inq helper Geliang Tang
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Implements FIONREAD ioctl checks to validate available data size, ensuring
synchronization between write and read operations with non-blocking waits.
These codes are from mptcp_inq.c.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index b8e8fec8979f..7cc4626b7bf3 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -771,6 +771,24 @@ static void process_one_client(int fd, int unixfd)
if (expect_len > sizeof(buf))
xerror("expect len %zu exceeds buffer size", expect_len);
+ for (;;) {
+ struct timespec req;
+ unsigned int queued;
+
+ ret = ioctl(fd, FIONREAD, &queued);
+ if (ret < 0)
+ die_perror("FIONREAD");
+ if (queued > expect_len)
+ xerror("FIONREAD returned %u, but only %zu expected\n",
+ queued, expect_len);
+ if (queued == expect_len)
+ break;
+
+ req.tv_sec = 0;
+ req.tv_nsec = 1000 * 1000ul;
+ nanosleep(&req, NULL);
+ }
+
/* read one byte, expect cmsg to return expected - 1 */
ret = recvmsg(fd, &msg, 0);
if (ret < 0)
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 12/14] selftests: mptcp: sockopt: add check_tcp_inq helper
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (10 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 11/14] selftests: mptcp: sockopt: set FIONREAD ioctl Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 13/14] selftests: mptcp: sockopt: replace mptcp_inq with sockopt Geliang Tang
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Adds check_tcp_inq() helper to extract and verify TCP_CM_INQ values from
control messages, ensuring correct in-queue data tracking during transfers.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 7cc4626b7bf3..fb6f76c4dc07 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -740,6 +740,35 @@ static void connect_one_server(int fd, int unixfd)
close(unixfd);
}
+static void get_tcp_inq(struct msghdr *msgh, unsigned int *inqv)
+{
+ struct cmsghdr *cmsg;
+
+ for (cmsg = CMSG_FIRSTHDR(msgh); cmsg ; cmsg = CMSG_NXTHDR(msgh, cmsg)) {
+ if (cmsg->cmsg_level == IPPROTO_TCP && cmsg->cmsg_type == TCP_CM_INQ) {
+ memcpy(inqv, CMSG_DATA(cmsg), sizeof(*inqv));
+ return;
+ }
+ }
+
+ xerror("could not find TCP_CM_INQ cmsg type");
+}
+
+static void check_tcp_inq(struct msghdr *msgh, unsigned int check, bool equal)
+{
+ unsigned int tcp_inq;
+
+ if (!inq)
+ return;
+
+ get_tcp_inq(msgh, &tcp_inq);
+
+ if (equal)
+ assert(tcp_inq == check);
+ else
+ assert(tcp_inq <= check);
+}
+
static void process_one_client(int fd, int unixfd)
{
ssize_t ret, ret2, ret3, tot;
@@ -797,6 +826,8 @@ static void process_one_client(int fd, int unixfd)
if (inq && msg.msg_controllen == 0)
xerror("msg_controllen is 0");
+ check_tcp_inq(&msg, expect_len - 1, true);
+
iov.iov_len = sizeof(buf);
ret = recvmsg(fd, &msg, 0);
if (ret < 0)
@@ -810,6 +841,9 @@ static void process_one_client(int fd, int unixfd)
/* should have gotten exact remainder of all pending data */
assert(ret == (ssize_t)expect_len - 1);
+ /* should be 0, all drained */
+ check_tcp_inq(&msg, 0, true);
+
ret2 = write(fd, buf, ret);
if (ret2 < 0)
die_perror("write");
@@ -853,6 +887,8 @@ static void process_one_client(int fd, int unixfd)
die_perror("recvmsg");
tot += ret;
+
+ check_tcp_inq(&msg, expect_len - tot, false);
} while ((size_t)tot < expect_len);
ret = write(unixfd, "shut", 4);
@@ -871,11 +907,15 @@ static void process_one_client(int fd, int unixfd)
die_perror("recvmsg");
assert(ret == 1);
+ /* tcp_inq should be 1 due to received fin. */
+ check_tcp_inq(&msg, 1, true);
+
/* wait for hangup */
iov.iov_len = 1;
ret3 = recvmsg(fd, &msg, 0);
if (ret3 != 0)
xerror("expected EOF, got %lu", ret3);
+ check_tcp_inq(&msg, 1, true);
close(fd);
}
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 13/14] selftests: mptcp: sockopt: replace mptcp_inq with sockopt
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (11 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 12/14] selftests: mptcp: sockopt: add check_tcp_inq helper Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 14/14] selftests: mptcp: sockopt: remove obsolete mptcp_inq Geliang Tang
2025-08-26 12:50 ` [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt MPTCP CI
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Update mptcp_sockopt.sh to use mptcp_sockopt binary instead of
mptcp_inq. This consolidates TCP_INQ testing into a single test binary
while maintaining equivalent test coverage.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 418a903c3a4d..f5150a10b064 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -305,7 +305,7 @@ run_tests()
do_tcpinq_test()
{
print_title "TCP_INQ cmsg/ioctl $*"
- ip netns exec "$ns_sbox" ./mptcp_inq "$@"
+ ip netns exec "$ns_sbox" ./mptcp_sockopt "$@"
local lret=$?
if [ $lret -ne 0 ];then
ret=$lret
@@ -331,19 +331,19 @@ do_tcpinq_tests()
local args
for args in "-t tcp" "-r tcp"; do
- do_tcpinq_test $args
+ do_tcpinq_test $args -i
lret=$?
if [ $lret -ne 0 ] ; then
return $lret
fi
- do_tcpinq_test -6 $args
+ do_tcpinq_test -6 $args -i
lret=$?
if [ $lret -ne 0 ] ; then
return $lret
fi
done
- do_tcpinq_test -r tcp -t tcp
+ do_tcpinq_test -r tcp -t tcp -i
return $?
}
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH mptcp-next v3 14/14] selftests: mptcp: sockopt: remove obsolete mptcp_inq
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (12 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 13/14] selftests: mptcp: sockopt: replace mptcp_inq with sockopt Geliang Tang
@ 2025-08-26 9:29 ` Geliang Tang
2025-08-26 12:50 ` [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt MPTCP CI
14 siblings, 0 replies; 16+ messages in thread
From: Geliang Tang @ 2025-08-26 9:29 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
Delete mptcp_inq binary and references since its functionality has been
fully integrated into mptcp_sockopt. This simplifies the test suite
structure and reduces maintenance overhead.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/.gitignore | 1 -
tools/testing/selftests/net/mptcp/Makefile | 2 +-
tools/testing/selftests/net/mptcp/mptcp_inq.c | 608 ------------------
3 files changed, 1 insertion(+), 610 deletions(-)
delete mode 100644 tools/testing/selftests/net/mptcp/mptcp_inq.c
diff --git a/tools/testing/selftests/net/mptcp/.gitignore b/tools/testing/selftests/net/mptcp/.gitignore
index 833279fb34e2..c62e91ce385d 100644
--- a/tools/testing/selftests/net/mptcp/.gitignore
+++ b/tools/testing/selftests/net/mptcp/.gitignore
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
mptcp_connect
mptcp_diag
-mptcp_inq
mptcp_sockopt
pm_nl_ctl
*.pcap
diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile
index 4c7e51336ab2..9c8da49313fb 100644
--- a/tools/testing/selftests/net/mptcp/Makefile
+++ b/tools/testing/selftests/net/mptcp/Makefile
@@ -8,7 +8,7 @@ TEST_PROGS := mptcp_connect.sh mptcp_connect_mmap.sh mptcp_connect_sendfile.sh \
mptcp_connect_checksum.sh pm_netlink.sh mptcp_join.sh diag.sh \
simult_flows.sh mptcp_sockopt.sh userspace_pm.sh
-TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_inq mptcp_diag
+TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_diag
TEST_FILES := mptcp_lib.sh settings
diff --git a/tools/testing/selftests/net/mptcp/mptcp_inq.c b/tools/testing/selftests/net/mptcp/mptcp_inq.c
deleted file mode 100644
index f3bcaa48df8f..000000000000
--- a/tools/testing/selftests/net/mptcp/mptcp_inq.c
+++ /dev/null
@@ -1,608 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#define _GNU_SOURCE
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <sys/ioctl.h>
-#include <sys/random.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <netdb.h>
-#include <netinet/in.h>
-
-#include <linux/tcp.h>
-#include <linux/sockios.h>
-
-#ifndef IPPROTO_MPTCP
-#define IPPROTO_MPTCP 262
-#endif
-#ifndef SOL_MPTCP
-#define SOL_MPTCP 284
-#endif
-
-static int pf = AF_INET;
-static int proto_tx = IPPROTO_MPTCP;
-static int proto_rx = IPPROTO_MPTCP;
-
-static void die_perror(const char *msg)
-{
- perror(msg);
- exit(1);
-}
-
-static void die_usage(int r)
-{
- fprintf(stderr, "Usage: mptcp_inq [-6] [ -t tcp|mptcp ] [ -r tcp|mptcp]\n");
- exit(r);
-}
-
-static void xerror(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fputc('\n', stderr);
- exit(1);
-}
-
-static const char *getxinfo_strerr(int err)
-{
- if (err == EAI_SYSTEM)
- return strerror(errno);
-
- return gai_strerror(err);
-}
-
-static void xgetaddrinfo(const char *node, const char *service,
- struct addrinfo *hints,
- struct addrinfo **res)
-{
- int err;
-
-again:
- err = getaddrinfo(node, service, hints, res);
- if (err) {
- const char *errstr;
-
- if (err == EAI_SOCKTYPE) {
- hints->ai_protocol = IPPROTO_TCP;
- goto again;
- }
-
- errstr = getxinfo_strerr(err);
-
- fprintf(stderr, "Fatal: getaddrinfo(%s:%s): %s\n",
- node ? node : "", service ? service : "", errstr);
- exit(1);
- }
-}
-
-static int sock_listen_mptcp(const char * const listenaddr,
- const char * const port)
-{
- int sock = -1;
- struct addrinfo hints = {
- .ai_protocol = IPPROTO_MPTCP,
- .ai_socktype = SOCK_STREAM,
- .ai_flags = AI_PASSIVE | AI_NUMERICHOST
- };
-
- hints.ai_family = pf;
-
- struct addrinfo *a, *addr;
- int one = 1;
-
- xgetaddrinfo(listenaddr, port, &hints, &addr);
- hints.ai_family = pf;
-
- for (a = addr; a; a = a->ai_next) {
- sock = socket(a->ai_family, a->ai_socktype, proto_rx);
- if (sock < 0)
- continue;
-
- if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one,
- sizeof(one)))
- perror("setsockopt");
-
- if (bind(sock, a->ai_addr, a->ai_addrlen) == 0)
- break; /* success */
-
- perror("bind");
- close(sock);
- sock = -1;
- }
-
- freeaddrinfo(addr);
-
- if (sock < 0)
- xerror("could not create listen socket");
-
- if (listen(sock, 20))
- die_perror("listen");
-
- return sock;
-}
-
-static int sock_connect_mptcp(const char * const remoteaddr,
- const char * const port, int proto)
-{
- struct addrinfo hints = {
- .ai_protocol = IPPROTO_MPTCP,
- .ai_socktype = SOCK_STREAM,
- };
- struct addrinfo *a, *addr;
- int sock = -1;
-
- hints.ai_family = pf;
-
- xgetaddrinfo(remoteaddr, port, &hints, &addr);
- for (a = addr; a; a = a->ai_next) {
- sock = socket(a->ai_family, a->ai_socktype, proto);
- if (sock < 0)
- continue;
-
- if (connect(sock, a->ai_addr, a->ai_addrlen) == 0)
- break; /* success */
-
- die_perror("connect");
- }
-
- if (sock < 0)
- xerror("could not create connect socket");
-
- freeaddrinfo(addr);
- 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, "h6t:r:")) != -1) {
- switch (c) {
- case 'h':
- die_usage(0);
- break;
- 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;
- }
- }
-}
-
-/* wait up to timeout milliseconds */
-static void wait_for_ack(int fd, int timeout, size_t total)
-{
- int i;
-
- for (i = 0; i < timeout; i++) {
- int nsd, ret, queued = -1;
- struct timespec req;
-
- ret = ioctl(fd, TIOCOUTQ, &queued);
- if (ret < 0)
- die_perror("TIOCOUTQ");
-
- ret = ioctl(fd, SIOCOUTQNSD, &nsd);
- if (ret < 0)
- die_perror("SIOCOUTQNSD");
-
- if ((size_t)queued > total)
- xerror("TIOCOUTQ %u, but only %zu expected\n", queued, total);
- assert(nsd <= queued);
-
- if (queued == 0)
- return;
-
- /* wait for peer to ack rx of all data */
- req.tv_sec = 0;
- req.tv_nsec = 1 * 1000 * 1000ul; /* 1ms */
- nanosleep(&req, NULL);
- }
-
- xerror("still tx data queued after %u ms\n", timeout);
-}
-
-static void connect_one_server(int fd, int unixfd)
-{
- size_t len, i, total, sent;
- char buf[4096], buf2[4096];
- ssize_t ret;
-
- len = rand() % (sizeof(buf) - 1);
-
- if (len < 128)
- len = 128;
-
- for (i = 0; i < len ; i++) {
- buf[i] = rand() % 26;
- buf[i] += 'A';
- }
-
- buf[i] = '\n';
-
- /* un-block server */
- ret = read(unixfd, buf2, 4);
- assert(ret == 4);
-
- assert(strncmp(buf2, "xmit", 4) == 0);
-
- ret = write(unixfd, &len, sizeof(len));
- assert(ret == (ssize_t)sizeof(len));
-
- ret = write(fd, buf, len);
- if (ret < 0)
- die_perror("write");
-
- if (ret != (ssize_t)len)
- xerror("short write");
-
- ret = read(unixfd, buf2, 4);
- assert(strncmp(buf2, "huge", 4) == 0);
-
- total = rand() % (16 * 1024 * 1024);
- total += (1 * 1024 * 1024);
- sent = total;
-
- ret = write(unixfd, &total, sizeof(total));
- assert(ret == (ssize_t)sizeof(total));
-
- wait_for_ack(fd, 5000, len);
-
- while (total > 0) {
- if (total > sizeof(buf))
- len = sizeof(buf);
- else
- len = total;
-
- ret = write(fd, buf, len);
- if (ret < 0)
- die_perror("write");
- total -= ret;
-
- /* we don't have to care about buf content, only
- * number of total bytes sent
- */
- }
-
- ret = read(unixfd, buf2, 4);
- assert(ret == 4);
- assert(strncmp(buf2, "shut", 4) == 0);
-
- wait_for_ack(fd, 5000, sent);
-
- ret = write(fd, buf, 1);
- assert(ret == 1);
- close(fd);
- ret = write(unixfd, "closed", 6);
- assert(ret == 6);
-
- close(unixfd);
-}
-
-static void get_tcp_inq(struct msghdr *msgh, unsigned int *inqv)
-{
- struct cmsghdr *cmsg;
-
- for (cmsg = CMSG_FIRSTHDR(msgh); cmsg ; cmsg = CMSG_NXTHDR(msgh, cmsg)) {
- if (cmsg->cmsg_level == IPPROTO_TCP && cmsg->cmsg_type == TCP_CM_INQ) {
- memcpy(inqv, CMSG_DATA(cmsg), sizeof(*inqv));
- return;
- }
- }
-
- xerror("could not find TCP_CM_INQ cmsg type");
-}
-
-static void process_one_client(int fd, int unixfd)
-{
- unsigned int tcp_inq;
- size_t expect_len;
- char msg_buf[4096];
- char buf[4096];
- char tmp[16];
- struct iovec iov = {
- .iov_base = buf,
- .iov_len = 1,
- };
- struct msghdr msg = {
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = msg_buf,
- .msg_controllen = sizeof(msg_buf),
- };
- ssize_t ret, tot;
-
- ret = write(unixfd, "xmit", 4);
- assert(ret == 4);
-
- ret = read(unixfd, &expect_len, sizeof(expect_len));
- assert(ret == (ssize_t)sizeof(expect_len));
-
- if (expect_len > sizeof(buf))
- xerror("expect len %zu exceeds buffer size", expect_len);
-
- for (;;) {
- struct timespec req;
- unsigned int queued;
-
- ret = ioctl(fd, FIONREAD, &queued);
- if (ret < 0)
- die_perror("FIONREAD");
- if (queued > expect_len)
- xerror("FIONREAD returned %u, but only %zu expected\n",
- queued, expect_len);
- if (queued == expect_len)
- break;
-
- req.tv_sec = 0;
- req.tv_nsec = 1000 * 1000ul;
- nanosleep(&req, NULL);
- }
-
- /* read one byte, expect cmsg to return expected - 1 */
- ret = recvmsg(fd, &msg, 0);
- if (ret < 0)
- die_perror("recvmsg");
-
- if (msg.msg_controllen == 0)
- xerror("msg_controllen is 0");
-
- get_tcp_inq(&msg, &tcp_inq);
-
- assert((size_t)tcp_inq == (expect_len - 1));
-
- iov.iov_len = sizeof(buf);
- ret = recvmsg(fd, &msg, 0);
- if (ret < 0)
- die_perror("recvmsg");
-
- /* should have gotten exact remainder of all pending data */
- assert(ret == (ssize_t)tcp_inq);
-
- /* should be 0, all drained */
- get_tcp_inq(&msg, &tcp_inq);
- assert(tcp_inq == 0);
-
- /* request a large swath of data. */
- ret = write(unixfd, "huge", 4);
- assert(ret == 4);
-
- ret = read(unixfd, &expect_len, sizeof(expect_len));
- assert(ret == (ssize_t)sizeof(expect_len));
-
- /* peer should send us a few mb of data */
- if (expect_len <= sizeof(buf))
- xerror("expect len %zu too small\n", expect_len);
-
- tot = 0;
- do {
- iov.iov_len = sizeof(buf);
- ret = recvmsg(fd, &msg, 0);
- if (ret < 0)
- die_perror("recvmsg");
-
- tot += ret;
-
- get_tcp_inq(&msg, &tcp_inq);
-
- if (tcp_inq > expect_len - tot)
- xerror("inq %d, remaining %d total_len %d\n",
- tcp_inq, expect_len - tot, (int)expect_len);
-
- assert(tcp_inq <= expect_len - tot);
- } while ((size_t)tot < expect_len);
-
- ret = write(unixfd, "shut", 4);
- assert(ret == 4);
-
- /* wait for hangup. Should have received one more byte of data. */
- ret = read(unixfd, tmp, sizeof(tmp));
- assert(ret == 6);
- assert(strncmp(tmp, "closed", 6) == 0);
-
- sleep(1);
-
- iov.iov_len = 1;
- ret = recvmsg(fd, &msg, 0);
- if (ret < 0)
- die_perror("recvmsg");
- assert(ret == 1);
-
- get_tcp_inq(&msg, &tcp_inq);
-
- /* tcp_inq should be 1 due to received fin. */
- assert(tcp_inq == 1);
-
- iov.iov_len = 1;
- ret = recvmsg(fd, &msg, 0);
- if (ret < 0)
- die_perror("recvmsg");
-
- /* expect EOF */
- assert(ret == 0);
- get_tcp_inq(&msg, &tcp_inq);
- assert(tcp_inq == 1);
-
- close(fd);
-}
-
-static int xaccept(int s)
-{
- int fd = accept(s, NULL, 0);
-
- if (fd < 0)
- die_perror("accept");
-
- return fd;
-}
-
-static int server(int unixfd)
-{
- int fd = -1, r, on = 1;
-
- switch (pf) {
- case AF_INET:
- fd = sock_listen_mptcp("127.0.0.1", "15432");
- break;
- case AF_INET6:
- fd = sock_listen_mptcp("::1", "15432");
- break;
- default:
- xerror("Unknown pf %d\n", pf);
- break;
- }
-
- r = write(unixfd, "conn", 4);
- assert(r == 4);
-
- alarm(15);
- r = xaccept(fd);
-
- if (-1 == setsockopt(r, IPPROTO_TCP, TCP_INQ, &on, sizeof(on)))
- die_perror("setsockopt");
-
- process_one_client(r, unixfd);
-
- return 0;
-}
-
-static int client(int unixfd)
-{
- int fd = -1;
-
- alarm(15);
-
- switch (pf) {
- case AF_INET:
- fd = sock_connect_mptcp("127.0.0.1", "15432", proto_tx);
- break;
- case AF_INET6:
- fd = sock_connect_mptcp("::1", "15432", proto_tx);
- break;
- default:
- xerror("Unknown pf %d\n", pf);
- }
-
- connect_one_server(fd, unixfd);
-
- return 0;
-}
-
-static void init_rng(void)
-{
- unsigned int foo;
-
- if (getrandom(&foo, sizeof(foo), 0) == -1) {
- perror("getrandom");
- exit(1);
- }
-
- srand(foo);
-}
-
-static pid_t xfork(void)
-{
- pid_t p = fork();
-
- if (p < 0)
- die_perror("fork");
- else if (p == 0)
- init_rng();
-
- return p;
-}
-
-static int rcheck(int wstatus, const char *what)
-{
- if (WIFEXITED(wstatus)) {
- if (WEXITSTATUS(wstatus) == 0)
- return 0;
- fprintf(stderr, "%s exited, status=%d\n", what, WEXITSTATUS(wstatus));
- return WEXITSTATUS(wstatus);
- } else if (WIFSIGNALED(wstatus)) {
- xerror("%s killed by signal %d\n", what, WTERMSIG(wstatus));
- } else if (WIFSTOPPED(wstatus)) {
- xerror("%s stopped by signal %d\n", what, WSTOPSIG(wstatus));
- }
-
- return 111;
-}
-
-int main(int argc, char *argv[])
-{
- int e1, e2, wstatus;
- pid_t s, c, ret;
- int unixfds[2];
-
- parse_opts(argc, argv);
-
- e1 = socketpair(AF_UNIX, SOCK_DGRAM, 0, unixfds);
- if (e1 < 0)
- die_perror("pipe");
-
- s = xfork();
- if (s == 0)
- return server(unixfds[1]);
-
- close(unixfds[1]);
-
- /* wait until server bound a socket */
- e1 = read(unixfds[0], &e1, 4);
- assert(e1 == 4);
-
- c = xfork();
- if (c == 0)
- return client(unixfds[0]);
-
- close(unixfds[0]);
-
- ret = waitpid(s, &wstatus, 0);
- if (ret == -1)
- die_perror("waitpid");
- e1 = rcheck(wstatus, "server");
- ret = waitpid(c, &wstatus, 0);
- if (ret == -1)
- die_perror("waitpid");
- e2 = rcheck(wstatus, "client");
-
- return e1 ? e1 : e2;
-}
--
2.48.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
` (13 preceding siblings ...)
2025-08-26 9:29 ` [PATCH mptcp-next v3 14/14] selftests: mptcp: sockopt: remove obsolete mptcp_inq Geliang Tang
@ 2025-08-26 12:50 ` MPTCP CI
14 siblings, 0 replies; 16+ messages in thread
From: MPTCP CI @ 2025-08-26 12:50 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: Unstable: 1 failed test(s): selftest_mptcp_connect 🔴
- KVM Validation: debug: Unstable: 1 failed test(s): selftest_mptcp_connect 🔴
- 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/17234297108
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/2b989c1de52d
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=995595
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] 16+ messages in thread
end of thread, other threads:[~2025-08-26 12:50 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-26 9:29 [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 01/14] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 02/14] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 03/14] selftests: mptcp: sockopt: add inq argument Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 04/14] selftests: mptcp: sockopt: set TCP_INQ on accepted sockets Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 05/14] selftests: mptcp: sockopt: use unix socket instead of pipe Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 06/14] selftests: mptcp: sockopt: read eof at the end of process_one_client Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 07/14] selftests: mptcp: sockopt: use recvmsg instead of read Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 08/14] selftests: mptcp: sockopt: read one byte first Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 09/14] selftests: mptcp: sockopt: add large data transfer tests Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 10/14] selftests: mptcp: sockopt: add wait_for_ack Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 11/14] selftests: mptcp: sockopt: set FIONREAD ioctl Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 12/14] selftests: mptcp: sockopt: add check_tcp_inq helper Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 13/14] selftests: mptcp: sockopt: replace mptcp_inq with sockopt Geliang Tang
2025-08-26 9:29 ` [PATCH mptcp-next v3 14/14] selftests: mptcp: sockopt: remove obsolete mptcp_inq Geliang Tang
2025-08-26 12:50 ` [PATCH mptcp-next v3 00/14] selftests: consolidate TCP_INQ testing into sockopt MPTCP CI
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.