From: T S Rameshkumar <rameshsv06@gmail.com>
To: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org
Cc: netdev@vger.kernel.org, mptcp@lists.linux.dev,
linux-kernel@vger.kernel.org,
T S Rameshkumar <rameshkumar.t@phytecembedded.in>
Subject: [PATCH mptcp-next] selftests: mptcp: sockopt: test passive Fast Open early write push
Date: Thu, 8 Oct 2026 16:40:03 +0530 [thread overview]
Message-ID: <20261008111003.136143-1-rameshkumar.t@phytecembedded.in> (raw)
Add automated test coverage for passive Fast Open early write data
push in mptcp_sockopt.c and mptcp_sockopt.sh.
The server enables TCP_FASTOPEN on an MPTCP listening socket, accepts
an incoming connection with SYN payload data, and immediately writes
reply bytes before the 3-way handshake fully completes. The client
connects with TCP_FASTOPEN_CONNECT, sends request data, and validates
reception of the server's reply over both IPv4 and IPv6.
Signed-off-by: T S Rameshkumar <rameshkumar.t@phytecembedded.in>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 59 ++++++++++++++++++-
.../selftests/net/mptcp/mptcp_sockopt.sh | 34 +++++++++++
2 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index b6e58d936..04af7cebc 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -28,6 +28,7 @@
#include <linux/compiler.h>
static int pf = AF_INET;
+static bool do_tfo;
#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
@@ -247,6 +248,14 @@ static int sock_connect_mptcp(const char * const remoteaddr,
if (sock < 0)
continue;
+ if (do_tfo) {
+ int one = 1;
+
+ if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
+ &one, sizeof(one)) < 0)
+ die_perror("setsockopt TCP_FASTOPEN_CONNECT");
+ }
+
if (connect(sock, a->ai_addr, a->ai_addrlen) == 0)
break; /* success */
@@ -264,7 +273,7 @@ static void parse_opts(int argc, char **argv)
{
int c;
- while ((c = getopt(argc, argv, "h6")) != -1) {
+ while ((c = getopt(argc, argv, "h6f")) != -1) {
switch (c) {
case 'h':
die_usage(0);
@@ -272,6 +281,9 @@ static void parse_opts(int argc, char **argv)
case '6':
pf = AF_INET6;
break;
+ case 'f':
+ do_tfo = true;
+ break;
default:
die_usage(1);
break;
@@ -719,13 +731,36 @@ static int server(int pipefd)
break;
}
+ if (do_tfo) {
+ int qlen = 5;
+
+ if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) < 0)
+ die_perror("setsockopt TCP_FASTOPEN");
+ }
+
r = write(pipefd, "conn", 4);
assert(r == 4);
alarm(15);
r = xaccept(fd);
- process_one_client(r, pipefd);
+ if (do_tfo) {
+ char buf[64] = {0};
+ ssize_t n;
+
+ n = read(r, buf, sizeof(buf) - 1);
+ if (n <= 0)
+ die_perror("read tfo syn data");
+
+ n = write(r, "PONG_REPLY", 10);
+ if (n != 10)
+ die_perror("write tfo reply");
+
+ n = read(r, buf, 1);
+ close(r);
+ } else {
+ process_one_client(r, pipefd);
+ }
close(fd);
return 0;
@@ -775,6 +810,26 @@ static int client(int pipefd)
alarm(15);
+ if (do_tfo) {
+ const char *addr = (pf == AF_INET) ? "127.0.0.1" : "::1";
+ struct timeval tv = {.tv_sec = 5, .tv_usec = 0};
+ char buf[64] = {0};
+ ssize_t n;
+
+ fd = sock_connect_mptcp(addr, "15432", IPPROTO_MPTCP);
+ n = write(fd, "PING_DATA", 9);
+ if (n != 9)
+ die_perror("write PING_DATA");
+
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ n = read(fd, buf, sizeof(buf) - 1);
+ if (n <= 0 || strcmp(buf, "PONG_REPLY") != 0)
+ xerror("Fastopen early write failed: received %zd bytes '%s'", n, buf);
+
+ close(fd);
+ return 0;
+ }
+
switch (pf) {
case AF_INET:
fd = sock_connect_mptcp("127.0.0.1", "15432", IPPROTO_MPTCP);
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index e850a8742..b3b523ce8 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -351,6 +351,39 @@ do_tcpinq_tests()
return $?
}
+do_fastopen_tests()
+{
+ local lret=0
+
+ ip netns exec "$ns_sbox" sysctl -q net.ipv4.tcp_fastopen=3
+
+ ip netns exec "$ns_sbox" ./mptcp_sockopt -f
+ lret=$?
+
+ print_title "Fast Open early write v4"
+ if [ $lret -ne 0 ]; then
+ mptcp_lib_pr_fail
+ mptcp_lib_result_fail "Fast Open early write v4"
+ ret=$lret
+ return
+ fi
+ mptcp_lib_pr_ok
+ mptcp_lib_result_pass "Fast Open early write v4"
+
+ ip netns exec "$ns_sbox" ./mptcp_sockopt -6 -f
+ lret=$?
+
+ print_title "Fast Open early write v6"
+ if [ $lret -ne 0 ]; then
+ mptcp_lib_pr_fail
+ mptcp_lib_result_fail "Fast Open early write v6"
+ ret=$lret
+ return
+ fi
+ mptcp_lib_pr_ok
+ mptcp_lib_result_pass "Fast Open early write v6"
+}
+
sin=$(mktemp)
sout=$(mktemp)
cin=$(mktemp)
@@ -366,6 +399,7 @@ run_tests $ns1 $ns2 dead:beef:1::1
do_mptcp_sockopt_tests
do_tcpinq_tests
+do_fastopen_tests
mptcp_lib_result_print_all_tap
exit $ret
--
2.34.1
next reply other threads:[~2026-10-08 11:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-08 11:10 T S Rameshkumar [this message]
2026-10-08 11:31 ` [PATCH mptcp-next] selftests: mptcp: sockopt: test passive Fast Open early write push Matthieu Baerts
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261008111003.136143-1-rameshkumar.t@phytecembedded.in \
--to=rameshsv06@gmail.com \
--cc=geliang@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martineau@kernel.org \
--cc=matttbe@kernel.org \
--cc=mptcp@lists.linux.dev \
--cc=netdev@vger.kernel.org \
--cc=rameshkumar.t@phytecembedded.in \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox