All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt
@ 2025-09-12 14:19 Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 1/9] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

v4:
 - v3 changed the behavior of process_one_client and connect_one_server,
   causing intermittent failures during loop testing. Revert to using the
   v2 approach, along with some cleanups.

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().
 - https://patchwork.kernel.org/project/mptcp/cover/cover.1756200029.git.tanggeliang@kylinos.cn/

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 (9):
  selftests: mptcp: sockopt: replace /dev/urandom with getrandom
  selftests: mptcp: sockopt: add protocol arguments
  selftests: mptcp: sockopt: add inq argument
  selftests: mptcp: sockopt: rename pipefd to ipcfd
  selftests: mptcp: sockopt: set TCP_INQ sockopt
  selftests: mptcp: sockopt: handle INQ on server side
  selftests: mptcp: sockopt: handle INQ on client side
  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 | 613 ------------------
 .../selftests/net/mptcp/mptcp_sockopt.c       | 368 +++++++++--
 .../selftests/net/mptcp/mptcp_sockopt.sh      |   6 +-
 5 files changed, 335 insertions(+), 655 deletions(-)
 delete mode 100644 tools/testing/selftests/net/mptcp/mptcp_inq.c

-- 
2.48.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH mptcp-next v4 1/9] selftests: mptcp: sockopt: replace /dev/urandom with getrandom
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 2/9] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 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 286164f7246e..32a78663d45d 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>
@@ -820,21 +821,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] 11+ messages in thread

* [PATCH mptcp-next v4 2/9] selftests: mptcp: sockopt: add protocol arguments
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 1/9] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 3/9] selftests: mptcp: sockopt: add inq argument Geliang Tang
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 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       | 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 32a78663d45d..838dc79cb09d 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;
@@ -777,10 +796,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] 11+ messages in thread

* [PATCH mptcp-next v4 3/9] selftests: mptcp: sockopt: add inq argument
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 1/9] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 2/9] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 4/9] selftests: mptcp: sockopt: rename pipefd to ipcfd Geliang Tang
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 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 838dc79cb09d..96d636005cb2 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] 11+ messages in thread

* [PATCH mptcp-next v4 4/9] selftests: mptcp: sockopt: rename pipefd to ipcfd
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (2 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 3/9] selftests: mptcp: sockopt: add inq argument Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 5/9] selftests: mptcp: sockopt: set TCP_INQ sockopt Geliang Tang
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Rename pipefd to ipcfd to better reflect its generalized purpose since
it now handles both pipes and Unix domain sockets. This naming improves
code clarity for IPC channel handling.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 39 ++++++++++---------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 96d636005cb2..776a017577ce 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -590,7 +590,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 ipcfd)
 {
 	char buf[4096], buf2[4096];
 	size_t len, i, total;
@@ -615,9 +615,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(ipcfd, buf2, 4);
 	assert(ret == 4);
-	close(pipefd);
+	close(ipcfd);
 
 	assert(strncmp(buf2, "xmit", 4) == 0);
 
@@ -659,7 +659,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 ipcfd)
 {
 	ssize_t ret, ret2, ret3;
 	struct so_state s;
@@ -668,7 +668,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(ipcfd, "xmit", 4);
 	assert(ret == 4);
 
 	ret = read(fd, buf, sizeof(buf));
@@ -726,7 +726,7 @@ static int xaccept(int s)
 	return fd;
 }
 
-static int server(int pipefd)
+static int server(int ipcfd)
 {
 	int fd = -1, r;
 
@@ -742,13 +742,13 @@ static int server(int pipefd)
 		break;
 	}
 
-	r = write(pipefd, "conn", 4);
+	r = write(ipcfd, "conn", 4);
 	assert(r == 4);
 
 	alarm(15);
 	r = xaccept(fd);
 
-	process_one_client(r, pipefd);
+	process_one_client(r, ipcfd);
 
 	close(fd);
 	return 0;
@@ -792,7 +792,7 @@ static void test_ip_tos_sockopt(int fd)
 		xerror("expect socklen_t == -1");
 }
 
-static int client(int pipefd)
+static int client(int ipcfd)
 {
 	int fd = -1;
 
@@ -811,7 +811,7 @@ static int client(int pipefd)
 
 	test_ip_tos_sockopt(fd);
 
-	connect_one_server(fd, pipefd);
+	connect_one_server(fd, ipcfd);
 
 	return 0;
 }
@@ -858,35 +858,36 @@ int main(int argc, char *argv[])
 {
 	int e1, e2, wstatus;
 	pid_t s, c, ret;
-	int pipefds[2];
+	int ipcfds[2];
 
 	parse_opts(argc, argv);
 
 	init_rng();
 
-	e1 = pipe(pipefds);
+	e1 = inq ? socketpair(AF_UNIX, SOCK_DGRAM, 0, ipcfds) :
+		   pipe(ipcfds);
 	if (e1 < 0)
 		die_perror("pipe");
 
 	s = xfork();
 	if (s == 0) {
-		close(pipefds[0]);
-		ret = server(pipefds[1]);
-		close(pipefds[1]);
+		close(ipcfds[0]);
+		ret = server(ipcfds[1]);
+		close(ipcfds[1]);
 		return ret;
 	}
 
-	close(pipefds[1]);
+	close(ipcfds[1]);
 
 	/* wait until server bound a socket */
-	e1 = read(pipefds[0], &e1, 4);
+	e1 = read(ipcfds[0], &e1, 4);
 	assert(e1 == 4);
 
 	c = xfork();
 	if (c == 0)
-		return client(pipefds[0]);
+		return client(ipcfds[0]);
 
-	close(pipefds[0]);
+	close(ipcfds[0]);
 
 	ret = waitpid(s, &wstatus, 0);
 	if (ret == -1)
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH mptcp-next v4 5/9] selftests: mptcp: sockopt: set TCP_INQ sockopt
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (3 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 4/9] selftests: mptcp: sockopt: rename pipefd to ipcfd Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 6/9] selftests: mptcp: sockopt: handle INQ on server side Geliang Tang
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add a helper 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 776a017577ce..aadef8b0aea4 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -726,6 +726,14 @@ static int xaccept(int s)
 	return fd;
 }
 
+static void do_setsockopt_inq(int fd)
+{
+	int on = 1;
+
+	if (-1 == setsockopt(fd, IPPROTO_TCP, TCP_INQ, &on, sizeof(on)))
+		die_perror("setsockopt(TCP_INQ)");
+}
+
 static int server(int ipcfd)
 {
 	int fd = -1, r;
@@ -748,6 +756,9 @@ static int server(int ipcfd)
 	alarm(15);
 	r = xaccept(fd);
 
+	if (inq)
+		do_setsockopt_inq(r);
+
 	process_one_client(r, ipcfd);
 
 	close(fd);
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH mptcp-next v4 6/9] selftests: mptcp: sockopt: handle INQ on server side
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (4 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 5/9] selftests: mptcp: sockopt: set TCP_INQ sockopt Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 7/9] selftests: mptcp: sockopt: handle INQ on client side Geliang Tang
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Integrate process_one_client() and get_tcp_inq() from mptcp_inq.c into
mptcp_sockopt.c, and rename process_one_client() to process_inq_client()
to handle TCP_INQ-specific operations on server side.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 155 +++++++++++++++++-
 1 file changed, 153 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index aadef8b0aea4..f5342903a80a 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/random.h>
+#include <sys/ioctl.h>
 
 #include <netdb.h>
 #include <netinet/in.h>
@@ -716,6 +717,153 @@ static void process_one_client(int fd, int ipcfd)
 	close(fd);
 }
 
+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_inq_client(int fd, int ipcfd)
+{
+	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(ipcfd, "xmit", 4);
+	assert(ret == 4);
+
+	ret = read(ipcfd, &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(ipcfd, "huge", 4);
+	assert(ret == 4);
+
+	ret = read(ipcfd, &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(ipcfd, "shut", 4);
+	assert(ret == 4);
+
+	/* wait for hangup. Should have received one more byte of data. */
+	ret = read(ipcfd, 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);
@@ -756,10 +904,13 @@ static int server(int ipcfd)
 	alarm(15);
 	r = xaccept(fd);
 
-	if (inq)
+	if (inq) {
 		do_setsockopt_inq(r);
 
-	process_one_client(r, ipcfd);
+		process_inq_client(r, ipcfd);
+	} else {
+		process_one_client(r, ipcfd);
+	}
 
 	close(fd);
 	return 0;
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH mptcp-next v4 7/9] selftests: mptcp: sockopt: handle INQ on client side
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (5 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 6/9] selftests: mptcp: sockopt: handle INQ on server side Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 8/9] selftests: mptcp: sockopt: replace mptcp_inq with sockopt Geliang Tang
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Integrate connect_one_server() and wait_for_ack() from mptcp_inq.c into
mptcp_sockopt.c, and rename connect_one_server() to connect_inq_server()
to handle TCP_INQ-specific operations on client side.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 116 +++++++++++++++++-
 1 file changed, 115 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index f5342903a80a..ef7a445b626a 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -27,6 +27,7 @@
 #include <netinet/in.h>
 
 #include <linux/tcp.h>
+#include <linux/sockios.h>
 
 static int pf = AF_INET;
 static int proto_tx = IPPROTO_MPTCP;
@@ -660,6 +661,116 @@ static void connect_one_server(int fd, int ipcfd)
 	close(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_inq_server(int fd, int ipcfd)
+{
+	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(ipcfd, buf2, 4);
+	assert(ret == 4);
+
+	assert(strncmp(buf2, "xmit", 4) == 0);
+
+	ret = write(ipcfd, &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(ipcfd, buf2, 4);
+	assert(strncmp(buf2, "huge", 4) == 0);
+
+	total = rand() % (16 * 1024 * 1024);
+	total += (1 * 1024 * 1024);
+	sent = total;
+
+	ret = write(ipcfd, &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(ipcfd, 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(ipcfd, "closed", 6);
+	assert(ret == 6);
+
+	close(ipcfd);
+}
+
 static void process_one_client(int fd, int ipcfd)
 {
 	ssize_t ret, ret2, ret3;
@@ -973,7 +1084,10 @@ static int client(int ipcfd)
 
 	test_ip_tos_sockopt(fd);
 
-	connect_one_server(fd, ipcfd);
+	if (inq)
+		connect_inq_server(fd, ipcfd);
+	else
+		connect_one_server(fd, ipcfd);
 
 	return 0;
 }
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH mptcp-next v4 8/9] selftests: mptcp: sockopt: replace mptcp_inq with sockopt
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (6 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 7/9] selftests: mptcp: sockopt: handle INQ on client side Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 14:19 ` [PATCH mptcp-next v4 9/9] selftests: mptcp: sockopt: remove obsolete mptcp_inq Geliang Tang
  2025-09-12 16:05 ` [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt MPTCP CI
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch updates 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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index f01989be6e9b..14c18692065a 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
@@ -330,7 +330,7 @@ do_tcpinq_tests()
 	fi
 
 	local args
-	for args in "-t tcp" "-r tcp"; do
+	for args in "-t tcp -i" "-r tcp -i"; do
 		do_tcpinq_test $args
 		lret=$?
 		if [ $lret -ne 0 ] ; then
@@ -343,7 +343,7 @@ do_tcpinq_tests()
 		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] 11+ messages in thread

* [PATCH mptcp-next v4 9/9] selftests: mptcp: sockopt: remove obsolete mptcp_inq
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (7 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 8/9] selftests: mptcp: sockopt: replace mptcp_inq with sockopt Geliang Tang
@ 2025-09-12 14:19 ` Geliang Tang
  2025-09-12 16:05 ` [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt MPTCP CI
  9 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2025-09-12 14:19 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 | 613 ------------------
 3 files changed, 1 insertion(+), 615 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 8e8f6441ad8b..000000000000
--- a/tools/testing/selftests/net/mptcp/mptcp_inq.c
+++ /dev/null
@@ -1,613 +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);
-
-	close(fd);
-	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) {
-		close(unixfds[0]);
-		ret = server(unixfds[1]);
-		close(unixfds[1]);
-		return ret;
-	}
-
-	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] 11+ messages in thread

* Re: [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt
  2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
                   ` (8 preceding siblings ...)
  2025-09-12 14:19 ` [PATCH mptcp-next v4 9/9] selftests: mptcp: sockopt: remove obsolete mptcp_inq Geliang Tang
@ 2025-09-12 16:05 ` MPTCP CI
  9 siblings, 0 replies; 11+ messages in thread
From: MPTCP CI @ 2025-09-12 16:05 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: Success! ✅
- KVM Validation: debug: 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/17677628486

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/d377d14467b4
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1001827


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] 11+ messages in thread

end of thread, other threads:[~2025-09-12 16:05 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-12 14:19 [PATCH mptcp-next v4 0/9] selftests: consolidate TCP_INQ testing into sockopt Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 1/9] selftests: mptcp: sockopt: replace /dev/urandom with getrandom Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 2/9] selftests: mptcp: sockopt: add protocol arguments Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 3/9] selftests: mptcp: sockopt: add inq argument Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 4/9] selftests: mptcp: sockopt: rename pipefd to ipcfd Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 5/9] selftests: mptcp: sockopt: set TCP_INQ sockopt Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 6/9] selftests: mptcp: sockopt: handle INQ on server side Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 7/9] selftests: mptcp: sockopt: handle INQ on client side Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 8/9] selftests: mptcp: sockopt: replace mptcp_inq with sockopt Geliang Tang
2025-09-12 14:19 ` [PATCH mptcp-next v4 9/9] selftests: mptcp: sockopt: remove obsolete mptcp_inq Geliang Tang
2025-09-12 16:05 ` [PATCH mptcp-next v4 0/9] 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.