mptcp.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options
@ 2025-08-19  9:00 Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 01/11] selftests: mptcp: sockopt: improve test output clarity Geliang Tang
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This series significantly expands MPTCP socket option test coverage
by adding validation for 10 more socket options:

1. SO_REUSEADDR/SO_REUSEPORT - Test socket reuse capabilities
2. SO_BINDTODEVICE/SO_BINDTOIFINDEX - Validate interface binding
3. IP_TOS - Verify Type of Service handling
4. IP_FREEBIND - Test free address binding
5. IP_TRANSPARENT - Validate transparent proxying
6. IP_BIND_ADDRESS_NO_PORT - Test deferred port binding
7. IP_LOCAL_PORT_RANGE - Check local port range restriction
8. IPV6_V6ONLY - Verify IPv6-only sockets

Each commit systematically adds:
- Setsockopt/getsockopt operations in mptcp_sockopt.c
- Dedicated test cases in mptcp_sockopt.sh
- IPv4 and IPv6 coverage
- Error handling and edge case validation

The new tests verify that MPTCP correctly propagates socket options to
subflows and maintains consistent behavior across address families.

Link: https://github.com/multipath-tcp/mptcp_net-next/issues/525

Geliang Tang (11):
  selftests: mptcp: sockopt: improve test output clarity
  selftests: mptcp: sockopt: add SO_REUSEADDR test helper
  selftests: mptcp: sockopt: add SO_REUSEPORT test
  selftests: mptcp: sockopt: add SO_BINDTODEVICE test
  selftests: mptcp: sockopt: add SO_BINDTOIFINDEX test
  selftests: mptcp: sockopt: add IP_TOS socket option test
  selftests: mptcp: sockopt: add IP_FREEBIND tests
  selftests: mptcp: sockopt: add IP_TRANSPARENT tests
  selftests: mptcp: sockopt: add IP_BIND_ADDRESS_NO_PORT test
  selftests: mptcp: sockopt: add IP_LOCAL_PORT_RANGE test
  selftests: mptcp: sockopt: add IPV6_V6ONLY test

 .../selftests/net/mptcp/mptcp_sockopt.c       | 359 +++++++++++++++---
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  94 ++++-
 2 files changed, 403 insertions(+), 50 deletions(-)

-- 
2.48.1


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

* [PATCH mptcp-next 01/11] selftests: mptcp: sockopt: improve test output clarity
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 02/11] selftests: mptcp: sockopt: add SO_REUSEADDR test helper Geliang Tang
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Refine test output to print detailed titles for SOL_MPTCP socket option
tests in both IPv4 and IPv6 contexts. This enhances readability and
distinctly separates v4/v6 results. The output now explicitly labels
each test phase and result, making failures easier to identify.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.sh       | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 418a903c3a4d..375d1eabe4f7 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -261,28 +261,32 @@ do_mptcp_sockopt_tests()
 	ip netns exec "$ns_sbox" ./mptcp_sockopt
 	lret=$?
 
-	print_title "SOL_MPTCP sockopt v4"
+	mptcp_lib_print_info "sockopt v4"
 	if [ $lret -ne 0 ]; then
-		mptcp_lib_pr_fail
+		mptcp_lib_pr_fail "sockopt v4"
 		mptcp_lib_result_fail "sockopt v4"
 		ret=$lret
 		return
 	fi
+
+	print_title "SOL_MPTCP sockopt v4"
 	mptcp_lib_pr_ok
-	mptcp_lib_result_pass "sockopt v4"
+	mptcp_lib_result_pass "SOL_MPTCP sockopt v4"
 
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
-	print_title "SOL_MPTCP sockopt v6"
+	mptcp_lib_print_info "sockopt v6"
 	if [ $lret -ne 0 ]; then
-		mptcp_lib_pr_fail
+		mptcp_lib_pr_fail "sockopt v6"
 		mptcp_lib_result_fail "sockopt v6"
 		ret=$lret
 		return
 	fi
+
+	print_title "SOL_MPTCP sockopt v6"
 	mptcp_lib_pr_ok
-	mptcp_lib_result_pass "sockopt v6"
+	mptcp_lib_result_pass "SOL_MPTCP sockopt v6"
 }
 
 run_tests()
@@ -329,6 +333,8 @@ do_tcpinq_tests()
 		return
 	fi
 
+	mptcp_lib_print_info "sockopt TCP_INQ"
+
 	local args
 	for args in "-t tcp" "-r tcp"; do
 		do_tcpinq_test $args
-- 
2.48.1


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

* [PATCH mptcp-next 02/11] selftests: mptcp: sockopt: add SO_REUSEADDR test helper
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 01/11] selftests: mptcp: sockopt: improve test output clarity Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 03/11] selftests: mptcp: sockopt: add SO_REUSEPORT test Geliang Tang
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Introduce helper functions to set and verify the SO_REUSEADDR socket
option. This includes:
- do_setsockopt_reuseaddr() to set the option
- do_getsockopt_reuseaddr() to validate the value
- Integration into IPv4/IPv6 test flows
- Explicit result reporting in the test script

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 34 ++++++++++++++++---
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 +++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index e934dd26a59d..a91709aeca06 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -182,6 +182,19 @@ static void xgetaddrinfo(const char *node, const char *service,
 	}
 }
 
+static void do_setsockopt_reuseaddr(int fd)
+{
+	int one = 1;
+
+	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
+		perror("setsockopt(SO_REUSEADDR)");
+}
+
+static void do_setsockopts(int fd)
+{
+	do_setsockopt_reuseaddr(fd);
+}
+
 static int sock_listen_mptcp(const char * const listenaddr,
 			     const char * const port)
 {
@@ -195,7 +208,6 @@ static int sock_listen_mptcp(const char * const listenaddr,
 	hints.ai_family = pf;
 
 	struct addrinfo *a, *addr;
-	int one = 1;
 
 	xgetaddrinfo(listenaddr, port, &hints, &addr);
 	hints.ai_family = pf;
@@ -205,9 +217,7 @@ static int sock_listen_mptcp(const char * const listenaddr,
 		if (sock < 0)
 			continue;
 
-		if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one,
-				     sizeof(one)))
-			perror("setsockopt");
+		do_setsockopts(sock);
 
 		if (bind(sock, a->ai_addr, a->ai_addrlen) == 0)
 			break; /* success */
@@ -246,6 +256,8 @@ static int sock_connect_mptcp(const char * const remoteaddr,
 		if (sock < 0)
 			continue;
 
+		do_setsockopts(sock);
+
 		if (connect(sock, a->ai_addr, a->ai_addrlen) == 0)
 			break; /* success */
 
@@ -554,6 +566,18 @@ static void do_getsockopt_mptcp_full_info(struct so_state *s, int fd)
 	assert(!memcmp(&sfinfo->addrs, &s->addrs, sizeof(struct mptcp_subflow_addrs)));
 }
 
+static void do_getsockopt_reuseaddr(int fd)
+{
+	socklen_t len;
+	int reuse;
+
+	len = sizeof(reuse);
+	if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, &len))
+		perror("getsockopt(SO_REUSEADDR)");
+
+	assert(reuse == 1);
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -564,6 +588,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 
 	if (r)
 		do_getsockopt_mptcp_full_info(s, fd);
+
+	do_getsockopt_reuseaddr(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 375d1eabe4f7..2f6b16cd51af 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -273,6 +273,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SOL_MPTCP sockopt v4"
 
+	print_title "SO_REUSEADDR sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_REUSEADDR sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -287,6 +291,10 @@ do_mptcp_sockopt_tests()
 	print_title "SOL_MPTCP sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SOL_MPTCP sockopt v6"
+
+	print_title "SO_REUSEADDR sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_REUSEADDR sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 03/11] selftests: mptcp: sockopt: add SO_REUSEPORT test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 01/11] selftests: mptcp: sockopt: improve test output clarity Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 02/11] selftests: mptcp: sockopt: add SO_REUSEADDR test helper Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 04/11] selftests: mptcp: sockopt: add SO_BINDTODEVICE test Geliang Tang
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Implement comprehensive testing for the SO_REUSEPORT socket option:
- Setsockopt and getsockopt helpers for SO_REUSEPORT
- Verification of the set value
- Integration into both client/server workflows
- IPv4 and IPv6 test coverage

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 23 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 +++++++
 2 files changed, 31 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index a91709aeca06..816d71706f7d 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -190,9 +190,18 @@ static void do_setsockopt_reuseaddr(int fd)
 		perror("setsockopt(SO_REUSEADDR)");
 }
 
+static void do_setsockopt_reuseport(int fd)
+{
+	int one = 1;
+
+	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)))
+		perror("setsockopt(SO_REUSEPORT)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
+	do_setsockopt_reuseport(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -578,6 +587,18 @@ static void do_getsockopt_reuseaddr(int fd)
 	assert(reuse == 1);
 }
 
+static void do_getsockopt_reuseport(int fd)
+{
+	socklen_t len;
+	int reuse;
+
+	len = sizeof(reuse);
+	if (getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &reuse, &len))
+		perror("getsockopt(SO_REUSEPORT)");
+
+	assert(reuse == 1);
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -590,6 +611,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 		do_getsockopt_mptcp_full_info(s, fd);
 
 	do_getsockopt_reuseaddr(fd);
+
+	do_getsockopt_reuseport(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 2f6b16cd51af..271d9777da54 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -277,6 +277,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_REUSEADDR sockopt v4"
 
+	print_title "SO_REUSEPORT sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_REUSEPORT sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -295,6 +299,10 @@ do_mptcp_sockopt_tests()
 	print_title "SO_REUSEADDR sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_REUSEADDR sockopt v6"
+
+	print_title "SO_REUSEPORT sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_REUSEPORT sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 04/11] selftests: mptcp: sockopt: add SO_BINDTODEVICE test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (2 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 03/11] selftests: mptcp: sockopt: add SO_REUSEPORT test Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 05/11] selftests: mptcp: sockopt: add SO_BINDTOIFINDEX test Geliang Tang
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add tests for the SO_BINDTODEVICE socket option:
- Binds sockets to the loopback device ("lo")
- Verifies the binding via getsockopt
- Includes IPv4 and IPv6 test cases
- Reports results explicitly in the test script

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 25 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++++++
 2 files changed, 33 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 816d71706f7d..df4f85f129f7 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -23,6 +23,7 @@
 
 #include <netdb.h>
 #include <netinet/in.h>
+#include <net/if.h>
 
 #include <linux/tcp.h>
 
@@ -198,10 +199,20 @@ static void do_setsockopt_reuseport(int fd)
 		perror("setsockopt(SO_REUSEPORT)");
 }
 
+static void do_setsockopt_bindtodevice(int fd)
+{
+	const char *interface = "lo";
+
+	if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
+		       interface, strlen(interface)))
+		perror("setsockopt(SO_BINDTODEVICE)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
 	do_setsockopt_reuseport(fd);
+	do_setsockopt_bindtodevice(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -599,6 +610,18 @@ static void do_getsockopt_reuseport(int fd)
 	assert(reuse == 1);
 }
 
+static void do_getsockopt_bindtodevice(int fd)
+{
+	char ifname[IFNAMSIZ] = { 0 };
+	socklen_t len;
+
+	len = sizeof(ifname);
+	if (getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, &len))
+		die_perror("getsockopt(SO_BINDTODEVICE)");
+
+	assert(!memcmp(ifname, "lo", len));
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -613,6 +636,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_reuseaddr(fd);
 
 	do_getsockopt_reuseport(fd);
+
+	do_getsockopt_bindtodevice(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 271d9777da54..948e54b50c43 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -281,6 +281,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_REUSEPORT sockopt v4"
 
+	print_title "SO_BINDTODEVICE sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_BINDTODEVICE sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -303,6 +307,10 @@ do_mptcp_sockopt_tests()
 	print_title "SO_REUSEPORT sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_REUSEPORT sockopt v6"
+
+	print_title "SO_BINDTODEVICE sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_BINDTODEVICE sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 05/11] selftests: mptcp: sockopt: add SO_BINDTOIFINDEX test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (3 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 04/11] selftests: mptcp: sockopt: add SO_BINDTODEVICE test Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 06/11] selftests: mptcp: sockopt: add IP_TOS socket option test Geliang Tang
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Implement tests for the SO_BINDTOIFINDEX socket option:
- Uses ioctl to get the loopback interface index
- Sets the option to bind to "lo"
- Validates the bound index via getsockopt
- Supports both IPv4 and IPv6

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 41 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++++
 2 files changed, 49 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index df4f85f129f7..25456e540cad 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/ioctl.h>
 
 #include <netdb.h>
 #include <netinet/in.h>
@@ -208,11 +209,36 @@ static void do_setsockopt_bindtodevice(int fd)
 		perror("setsockopt(SO_BINDTODEVICE)");
 }
 
+static int get_ifindex(int fd, const char *ifname)
+{
+	struct ifreq ifr;
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+	if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
+		perror("ioctl");
+		return -1;
+	}
+
+	return ifr.ifr_ifindex;
+}
+
+static void do_setsockopt_bindtoifindex(int fd)
+{
+	int ifindex = get_ifindex(fd, "lo");
+
+	if (setsockopt(fd, SOL_SOCKET, SO_BINDTOIFINDEX,
+		       &ifindex, sizeof(ifindex)))
+		perror("setsockopt(SO_BINDTOIFINDEX)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
 	do_setsockopt_reuseport(fd);
 	do_setsockopt_bindtodevice(fd);
+	do_setsockopt_bindtoifindex(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -622,6 +648,19 @@ static void do_getsockopt_bindtodevice(int fd)
 	assert(!memcmp(ifname, "lo", len));
 }
 
+static void do_getsockopt_bindtoifindex(int fd)
+{
+	socklen_t len;
+	int ifindex;
+
+	len = sizeof(ifindex);
+	if (getsockopt(fd, SOL_SOCKET, SO_BINDTOIFINDEX,
+		       &ifindex, &len))
+		die_perror("getsockopt(SO_BINDTOIFINDEX)");
+
+	assert(ifindex == get_ifindex(fd, "lo"));
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -638,6 +677,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_reuseport(fd);
 
 	do_getsockopt_bindtodevice(fd);
+
+	do_getsockopt_bindtoifindex(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 948e54b50c43..8eae13f4da38 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -285,6 +285,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_BINDTODEVICE sockopt v4"
 
+	print_title "SO_BINDTOIFINDEX sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_BINDTOIFINDEX sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -311,6 +315,10 @@ do_mptcp_sockopt_tests()
 	print_title "SO_BINDTODEVICE sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_BINDTODEVICE sockopt v6"
+
+	print_title "SO_BINDTOIFINDEX sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "SO_BINDTOIFINDEX sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 06/11] selftests: mptcp: sockopt: add IP_TOS socket option test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (4 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 05/11] selftests: mptcp: sockopt: add SO_BINDTOIFINDEX test Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 07/11] selftests: mptcp: sockopt: add IP_FREEBIND tests Geliang Tang
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add comprehensive testing for IP_TOS (Type of Service):
- Sets a random TOS value and verifies it
- Tests edge cases (zero-length buffer, negative size)
- Validates proper error handling
- Covers both IPv4 and IPv6

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 85 ++++++++++---------
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++
 2 files changed, 53 insertions(+), 40 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 25456e540cad..3bef535ce981 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -29,6 +29,7 @@
 #include <linux/tcp.h>
 
 static int pf = AF_INET;
+static uint8_t tos_in;
 
 #ifndef IPPROTO_MPTCP
 #define IPPROTO_MPTCP 262
@@ -233,12 +234,20 @@ static void do_setsockopt_bindtoifindex(int fd)
 		perror("setsockopt(SO_BINDTOIFINDEX)");
 }
 
+static void do_setsockopt_tos(int fd)
+{
+	tos_in = rand() & 0xfc;
+	if (setsockopt(fd, SOL_IP, IP_TOS, &tos_in, sizeof(tos_in)))
+		die_perror("setsockopt(IP_TOS)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
 	do_setsockopt_reuseport(fd);
 	do_setsockopt_bindtodevice(fd);
 	do_setsockopt_bindtoifindex(fd);
+	do_setsockopt_tos(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -661,6 +670,40 @@ static void do_getsockopt_bindtoifindex(int fd)
 	assert(ifindex == get_ifindex(fd, "lo"));
 }
 
+static void do_getsockopt_tos(int fd)
+{
+	uint8_t tos_out;
+	socklen_t s;
+	int r;
+
+	tos_out = 0;
+	s = sizeof(tos_out);
+	if (getsockopt(fd, SOL_IP, IP_TOS, &tos_out, &s))
+		die_perror("getsockopt IP_TOS");
+
+	if (!tos_in)
+		xerror("tos_in shouldn't be 0");
+
+	if (tos_in != tos_out)
+		xerror("tos %x != %x socklen_t %d\n", tos_in, tos_out, s);
+
+	if (s != 1)
+		xerror("tos should be 1 byte");
+
+	s = 0;
+	if (getsockopt(fd, SOL_IP, IP_TOS, &tos_out, &s))
+		die_perror("getsockopt IP_TOS 0");
+	if (s != 0)
+		xerror("expect socklen_t == 0");
+
+	s = -1;
+	r = getsockopt(fd, SOL_IP, IP_TOS, &tos_out, &s);
+	if (r != -1 && errno != EINVAL)
+		die_perror("getsockopt IP_TOS did not indicate -EINVAL");
+	if (s != -1)
+		xerror("expect socklen_t == -1");
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -679,6 +722,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_bindtodevice(fd);
 
 	do_getsockopt_bindtoifindex(fd);
+
+	do_getsockopt_tos(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
@@ -840,44 +885,6 @@ static int server(int pipefd)
 	return 0;
 }
 
-static void test_ip_tos_sockopt(int fd)
-{
-	uint8_t tos_in, tos_out;
-	socklen_t s;
-	int r;
-
-	tos_in = rand() & 0xfc;
-	r = setsockopt(fd, SOL_IP, IP_TOS, &tos_in, sizeof(tos_out));
-	if (r != 0)
-		die_perror("setsockopt IP_TOS");
-
-	tos_out = 0;
-	s = sizeof(tos_out);
-	r = getsockopt(fd, SOL_IP, IP_TOS, &tos_out, &s);
-	if (r != 0)
-		die_perror("getsockopt IP_TOS");
-
-	if (tos_in != tos_out)
-		xerror("tos %x != %x socklen_t %d\n", tos_in, tos_out, s);
-
-	if (s != 1)
-		xerror("tos should be 1 byte");
-
-	s = 0;
-	r = getsockopt(fd, SOL_IP, IP_TOS, &tos_out, &s);
-	if (r != 0)
-		die_perror("getsockopt IP_TOS 0");
-	if (s != 0)
-		xerror("expect socklen_t == 0");
-
-	s = -1;
-	r = getsockopt(fd, SOL_IP, IP_TOS, &tos_out, &s);
-	if (r != -1 && errno != EINVAL)
-		die_perror("getsockopt IP_TOS did not indicate -EINVAL");
-	if (s != -1)
-		xerror("expect socklen_t == -1");
-}
-
 static int client(int pipefd)
 {
 	int fd = -1;
@@ -895,8 +902,6 @@ static int client(int pipefd)
 		xerror("Unknown pf %d\n", pf);
 	}
 
-	test_ip_tos_sockopt(fd);
-
 	connect_one_server(fd, pipefd);
 
 	return 0;
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 8eae13f4da38..9972012d08f6 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -289,6 +289,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_BINDTOIFINDEX sockopt v4"
 
+	print_title "IP_TOS sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_TOS sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -319,6 +323,10 @@ do_mptcp_sockopt_tests()
 	print_title "SO_BINDTOIFINDEX sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "SO_BINDTOIFINDEX sockopt v6"
+
+	print_title "IP_TOS sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_TOS sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 07/11] selftests: mptcp: sockopt: add IP_FREEBIND tests
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (5 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 06/11] selftests: mptcp: sockopt: add IP_TOS socket option test Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 08/11] selftests: mptcp: sockopt: add IP_TRANSPARENT tests Geliang Tang
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add tests for IP_FREEBIND (IPv4) and IPV6_FREEBIND (IPv6):
- Setsockopt helpers to enable FREEBIND
- Getsockopt validation of the enabled state
- Test integration for both address families
- Script result reporting

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 37 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++++
 2 files changed, 45 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 3bef535ce981..1e7cacdebc72 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -241,6 +241,21 @@ static void do_setsockopt_tos(int fd)
 		die_perror("setsockopt(IP_TOS)");
 }
 
+static void do_setsockopt_freebind(int fd)
+{
+	int optname = IP_FREEBIND;
+	int level = SOL_IP;
+	int enable = 1;
+
+	if (pf == AF_INET6) {
+		level = SOL_IPV6;
+		optname = IPV6_FREEBIND;
+	}
+
+	if (setsockopt(fd, level, optname, &enable, sizeof(enable)))
+		perror("setsockopt(IP_FREEBIND)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
@@ -248,6 +263,7 @@ static void do_setsockopts(int fd)
 	do_setsockopt_bindtodevice(fd);
 	do_setsockopt_bindtoifindex(fd);
 	do_setsockopt_tos(fd);
+	do_setsockopt_freebind(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -704,6 +720,25 @@ static void do_getsockopt_tos(int fd)
 		xerror("expect socklen_t == -1");
 }
 
+static void do_getsockopt_freebind(int fd)
+{
+	int optname = IP_FREEBIND;
+	int level = SOL_IP;
+	socklen_t len;
+	int enable;
+
+	if (pf == AF_INET6) {
+		level = SOL_IPV6;
+		optname = IPV6_FREEBIND;
+	}
+
+	len = sizeof(enable);
+	if (getsockopt(fd, level, optname, &enable, &len))
+		die_perror("getsockopt(IP_FREEBIND)");
+
+	assert(enable == 1);
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -724,6 +759,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_bindtoifindex(fd);
 
 	do_getsockopt_tos(fd);
+
+	do_getsockopt_freebind(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 9972012d08f6..b5054533872b 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -293,6 +293,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_TOS sockopt v4"
 
+	print_title "IP_FREEBIND sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_FREEBIND sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -327,6 +331,10 @@ do_mptcp_sockopt_tests()
 	print_title "IP_TOS sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_TOS sockopt v6"
+
+	print_title "IPV6_FREEBIND sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IPV6_FREEBIND sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 08/11] selftests: mptcp: sockopt: add IP_TRANSPARENT tests
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (6 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 07/11] selftests: mptcp: sockopt: add IP_FREEBIND tests Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 09/11] selftests: mptcp: sockopt: add IP_BIND_ADDRESS_NO_PORT test Geliang Tang
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Implement tests for transparent socket options:
- IP_TRANSPARENT (IPv4) and IPV6_TRANSPARENT (IPv6)
- Setsockopt and getsockopt helpers
- State verification after setting
- IPv4/IPv6 coverage in test script

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 37 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++++
 2 files changed, 45 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 1e7cacdebc72..fe54c333e455 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -256,6 +256,21 @@ static void do_setsockopt_freebind(int fd)
 		perror("setsockopt(IP_FREEBIND)");
 }
 
+static void do_setsockopt_transparent(int fd)
+{
+	int optname = IP_TRANSPARENT;
+	int level = SOL_IP;
+	int enable = 1;
+
+	if (pf == AF_INET6) {
+		level = SOL_IPV6;
+		optname = IPV6_TRANSPARENT;
+	}
+
+	if (setsockopt(fd, level, optname, &enable, sizeof(enable)))
+		perror("setsockopt(IP_TRANSPARENT)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
@@ -264,6 +279,7 @@ static void do_setsockopts(int fd)
 	do_setsockopt_bindtoifindex(fd);
 	do_setsockopt_tos(fd);
 	do_setsockopt_freebind(fd);
+	do_setsockopt_transparent(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -739,6 +755,25 @@ static void do_getsockopt_freebind(int fd)
 	assert(enable == 1);
 }
 
+static void do_getsockopt_transparent(int fd)
+{
+	int optname = IP_FREEBIND;
+	int level = SOL_IP;
+	socklen_t len;
+	int enable;
+
+	if (pf == AF_INET6) {
+		level = SOL_IPV6;
+		optname = IPV6_FREEBIND;
+	}
+
+	len = sizeof(enable);
+	if (getsockopt(fd, level, optname, &enable, &len))
+		die_perror("getsockopt(IP_TRANSPARENT)");
+
+	assert(enable == 1);
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -761,6 +796,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_tos(fd);
 
 	do_getsockopt_freebind(fd);
+
+	do_getsockopt_transparent(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index b5054533872b..ed73ad7bba66 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -297,6 +297,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_FREEBIND sockopt v4"
 
+	print_title "IP_TRANSPARENT sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_TRANSPARENT sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -335,6 +339,10 @@ do_mptcp_sockopt_tests()
 	print_title "IPV6_FREEBIND sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IPV6_FREEBIND sockopt v6"
+
+	print_title "IPV6_TRANSPARENT sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IPV6_TRANSPARENT sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 09/11] selftests: mptcp: sockopt: add IP_BIND_ADDRESS_NO_PORT test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (7 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 08/11] selftests: mptcp: sockopt: add IP_TRANSPARENT tests Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 10/11] selftests: mptcp: sockopt: add IP_LOCAL_PORT_RANGE test Geliang Tang
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add tests for the IP_BIND_ADDRESS_NO_PORT socket option:
- Enables the option via setsockopt
- Verifies the enabled state via getsockopt
- Includes tests for both IPv4 and IPv6
- Updates test script output

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 25 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++++++
 2 files changed, 33 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index fe54c333e455..02b7ec774b86 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -271,6 +271,15 @@ static void do_setsockopt_transparent(int fd)
 		perror("setsockopt(IP_TRANSPARENT)");
 }
 
+static void do_setsockopt_bind_address_no_port(int fd)
+{
+	int enable = 1;
+
+	if (setsockopt(fd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &enable,
+		       sizeof(enable)))
+		perror("setsockopt(IP_BIND_ADDRESS_NO_PORT)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
@@ -280,6 +289,7 @@ static void do_setsockopts(int fd)
 	do_setsockopt_tos(fd);
 	do_setsockopt_freebind(fd);
 	do_setsockopt_transparent(fd);
+	do_setsockopt_bind_address_no_port(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -774,6 +784,19 @@ static void do_getsockopt_transparent(int fd)
 	assert(enable == 1);
 }
 
+static void do_getsockopt_bind_address_no_port(int fd)
+{
+	socklen_t len;
+	int enable;
+
+	len = sizeof(enable);
+	if (getsockopt(fd, SOL_IP, IP_BIND_ADDRESS_NO_PORT,
+		       &enable, &len))
+		die_perror("getsockopt(IP_TRANSPARENT)");
+
+	assert(enable == 1);
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -798,6 +821,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_freebind(fd);
 
 	do_getsockopt_transparent(fd);
+
+	do_getsockopt_bind_address_no_port(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index ed73ad7bba66..1bee46c9b29a 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -301,6 +301,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_TRANSPARENT sockopt v4"
 
+	print_title "IP_BIND_ADDRESS_NO_PORT sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_BIND_ADDRESS_NO_PORT sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -343,6 +347,10 @@ do_mptcp_sockopt_tests()
 	print_title "IPV6_TRANSPARENT sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IPV6_TRANSPARENT sockopt v6"
+
+	print_title "IP_BIND_ADDRESS_NO_PORT sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_BIND_ADDRESS_NO_PORT sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 10/11] selftests: mptcp: sockopt: add IP_LOCAL_PORT_RANGE test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (8 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 09/11] selftests: mptcp: sockopt: add IP_BIND_ADDRESS_NO_PORT test Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19  9:00 ` [PATCH mptcp-next 11/11] selftests: mptcp: sockopt: add IPV6_V6ONLY test Geliang Tang
  2025-08-19 11:59 ` [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options MPTCP CI
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add tests for IP_LOCAL_PORT_RANGE:
- Sets port range to 30000-31000
- Verifies the range via getsockopt
- Covers both IPv4 and IPv6
- Reports results in test script

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 25 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  8 ++++++
 2 files changed, 33 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 02b7ec774b86..3e2072869527 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -280,6 +280,15 @@ static void do_setsockopt_bind_address_no_port(int fd)
 		perror("setsockopt(IP_BIND_ADDRESS_NO_PORT)");
 }
 
+static void do_setsockopt_local_port_range(int fd)
+{
+	uint32_t port_range = (31000 << 16 | 30000); // [30000 - 31000]
+
+	if (setsockopt(fd, SOL_IP, IP_LOCAL_PORT_RANGE, &port_range,
+		       sizeof(port_range)))
+		perror("setsockopt(IP_LOCAL_PORT_RANGE)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
@@ -290,6 +299,7 @@ static void do_setsockopts(int fd)
 	do_setsockopt_freebind(fd);
 	do_setsockopt_transparent(fd);
 	do_setsockopt_bind_address_no_port(fd);
+	do_setsockopt_local_port_range(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -797,6 +807,19 @@ static void do_getsockopt_bind_address_no_port(int fd)
 	assert(enable == 1);
 }
 
+static void do_getsockopt_local_port_range(int fd)
+{
+	uint32_t port_range;
+	socklen_t len;
+
+	len = sizeof(port_range);
+	if (getsockopt(fd, SOL_IP, IP_LOCAL_PORT_RANGE,
+		       &port_range, &len))
+		die_perror("getsockopt(IP_LOCAL_PORT_RANGE)");
+
+	assert(port_range == (31000 << 16 | 30000));
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -823,6 +846,8 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_transparent(fd);
 
 	do_getsockopt_bind_address_no_port(fd);
+
+	do_getsockopt_local_port_range(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 1bee46c9b29a..a688917a13c1 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -305,6 +305,10 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_BIND_ADDRESS_NO_PORT sockopt v4"
 
+	print_title "IP_LOCAL_PORT_RANGE sockopt v4"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_LOCAL_PORT_RANGE sockopt v4"
+
 	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
 	lret=$?
 
@@ -351,6 +355,10 @@ do_mptcp_sockopt_tests()
 	print_title "IP_BIND_ADDRESS_NO_PORT sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_BIND_ADDRESS_NO_PORT sockopt v6"
+
+	print_title "IP_LOCAL_PORT_RANGE sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IP_LOCAL_PORT_RANGE sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* [PATCH mptcp-next 11/11] selftests: mptcp: sockopt: add IPV6_V6ONLY test
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (9 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 10/11] selftests: mptcp: sockopt: add IP_LOCAL_PORT_RANGE test Geliang Tang
@ 2025-08-19  9:00 ` Geliang Tang
  2025-08-19 11:59 ` [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options MPTCP CI
  11 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2025-08-19  9:00 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add IPv6-specific testing for IPV6_V6ONLY:
- Enables the option and verifies its state
- Restricted to IPv6 sockets
- Reports results in the test script

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.c       | 27 +++++++++++++++++++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  4 +++
 2 files changed, 31 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 3e2072869527..3d01cc20afb1 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -289,6 +289,15 @@ static void do_setsockopt_local_port_range(int fd)
 		perror("setsockopt(IP_LOCAL_PORT_RANGE)");
 }
 
+static void do_setsockopt_v6only(int fd)
+{
+	int v6only = 1;
+
+	if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &v6only,
+		       sizeof(v6only)))
+		perror("setsockopt(IPV6_V6ONLY)");
+}
+
 static void do_setsockopts(int fd)
 {
 	do_setsockopt_reuseaddr(fd);
@@ -300,6 +309,9 @@ static void do_setsockopts(int fd)
 	do_setsockopt_transparent(fd);
 	do_setsockopt_bind_address_no_port(fd);
 	do_setsockopt_local_port_range(fd);
+
+	if (pf == AF_INET6)
+		do_setsockopt_v6only(fd);
 }
 
 static int sock_listen_mptcp(const char * const listenaddr,
@@ -820,6 +832,18 @@ static void do_getsockopt_local_port_range(int fd)
 	assert(port_range == (31000 << 16 | 30000));
 }
 
+static void do_getsockopt_v6only(int fd)
+{
+	socklen_t len;
+	int v6only;
+
+	len = sizeof(v6only);
+	if (getsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &v6only, &len))
+		die_perror("getsockopt(IPV6_V6ONLY)");
+
+	assert(v6only == 1);
+}
+
 static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 {
 	do_getsockopt_mptcp_info(s, fd, w);
@@ -848,6 +872,9 @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w)
 	do_getsockopt_bind_address_no_port(fd);
 
 	do_getsockopt_local_port_range(fd);
+
+	if (pf == AF_INET6)
+		do_getsockopt_v6only(fd);
 }
 
 static void connect_one_server(int fd, int pipefd)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index a688917a13c1..6664f8f0733d 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -359,6 +359,10 @@ do_mptcp_sockopt_tests()
 	print_title "IP_LOCAL_PORT_RANGE sockopt v6"
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "IP_LOCAL_PORT_RANGE sockopt v6"
+
+	print_title "IPV6_V6ONLY sockopt v6"
+	mptcp_lib_pr_ok
+	mptcp_lib_result_pass "IPV6_V6ONLY sockopt v6"
 }
 
 run_tests()
-- 
2.48.1


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

* Re: [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options
  2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
                   ` (10 preceding siblings ...)
  2025-08-19  9:00 ` [PATCH mptcp-next 11/11] selftests: mptcp: sockopt: add IPV6_V6ONLY test Geliang Tang
@ 2025-08-19 11:59 ` MPTCP CI
  11 siblings, 0 replies; 13+ messages in thread
From: MPTCP CI @ 2025-08-19 11:59 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: 2 failed test(s): selftest_mptcp_connect selftest_mptcp_connect_checksum 🔴
- KVM Validation: debug: Unstable: 4 failed test(s): packetdrill_add_addr selftest_mptcp_connect selftest_mptcp_connect_checksum selftest_mptcp_join 🔴
- 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/17065050678

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


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

end of thread, other threads:[~2025-08-19 11:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-19  9:00 [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 01/11] selftests: mptcp: sockopt: improve test output clarity Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 02/11] selftests: mptcp: sockopt: add SO_REUSEADDR test helper Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 03/11] selftests: mptcp: sockopt: add SO_REUSEPORT test Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 04/11] selftests: mptcp: sockopt: add SO_BINDTODEVICE test Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 05/11] selftests: mptcp: sockopt: add SO_BINDTOIFINDEX test Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 06/11] selftests: mptcp: sockopt: add IP_TOS socket option test Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 07/11] selftests: mptcp: sockopt: add IP_FREEBIND tests Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 08/11] selftests: mptcp: sockopt: add IP_TRANSPARENT tests Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 09/11] selftests: mptcp: sockopt: add IP_BIND_ADDRESS_NO_PORT test Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 10/11] selftests: mptcp: sockopt: add IP_LOCAL_PORT_RANGE test Geliang Tang
2025-08-19  9:00 ` [PATCH mptcp-next 11/11] selftests: mptcp: sockopt: add IPV6_V6ONLY test Geliang Tang
2025-08-19 11:59 ` [PATCH mptcp-next 00/11] selftests: cover more MPTCP socket options MPTCP CI

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).