:p
atchew
Login
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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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() @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 */ @@ -XXX,XX +XXX,XX @@ 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 */ @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ #include <netdb.h> #include <netinet/in.h> +#include <net/if.h> #include <linux/tcp.h> @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ #include <sys/socket.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/ioctl.h> #include <netdb.h> #include <netinet/in.h> @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ #include <linux/tcp.h> static int pf = AF_INET; +static uint8_t tos_in; #ifndef IPPROTO_MPTCP #define IPPROTO_MPTCP 262 @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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=$? @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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
From: Geliang Tang <tanggeliang@kylinos.cn> v2: - IP_FREEBIND/IPV6_FREEBIND are set in do_getsockopt_transparent, fix it. - Use "for" loops in mptcp_sockopt.sh. - Move "add IP_TOS socket option test" out of this set. - some cleanups. 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 (10): 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_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 | 257 +++++++++++++++++- .../selftests/net/mptcp/mptcp_sockopt.sh | 37 ++- 2 files changed, 282 insertions(+), 12 deletions(-) -- 2.48.1
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 | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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 - mptcp_lib_pr_ok - mptcp_lib_result_pass "sockopt v4" + + for opt in "SOL_MPTCP"; do + print_title "$opt sockopt v4" + mptcp_lib_pr_ok + mptcp_lib_result_pass "$opt sockopt v4" + done 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 - mptcp_lib_pr_ok - mptcp_lib_result_pass "sockopt v6" + + for opt in "SOL_MPTCP"; do + print_title "$opt sockopt v6" + mptcp_lib_pr_ok + mptcp_lib_result_pass "$opt sockopt v6" + done + } run_tests() @@ -XXX,XX +XXX,XX @@ 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
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 | 7 ++-- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 */ @@ -XXX,XX +XXX,XX @@ 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 */ @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() return fi - for opt in "SOL_MPTCP"; do + for opt in "SOL_MPTCP" \ + "SO_REUSEADDR"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() return fi - for opt in "SOL_MPTCP"; do + for opt in "SOL_MPTCP" \ + "SO_REUSEADDR"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" done - } run_tests() -- 2.48.1
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 | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() fi for opt in "SOL_MPTCP" \ - "SO_REUSEADDR"; do + "SO_REUSEADDR" "SO_REUSEPORT"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() fi for opt in "SOL_MPTCP" \ - "SO_REUSEADDR"; do + "SO_REUSEADDR" "SO_REUSEPORT"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 6 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ #include <netdb.h> #include <netinet/in.h> +#include <net/if.h> #include <linux/tcp.h> @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() fi for opt in "SOL_MPTCP" \ - "SO_REUSEADDR" "SO_REUSEPORT"; do + "SO_REUSEADDR" "SO_REUSEPORT" \ + "SO_BINDTODEVICE"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() fi for opt in "SOL_MPTCP" \ - "SO_REUSEADDR" "SO_REUSEPORT"; do + "SO_REUSEADDR" "SO_REUSEPORT" \ + "SO_BINDTODEVICE"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 4 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ #include <sys/socket.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/ioctl.h> #include <netdb.h> #include <netinet/in.h> @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ - "SO_BINDTODEVICE"; do + "SO_BINDTODEVICE" "SO_BINDTOIFINDEX"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ - "SO_BINDTODEVICE"; do + "SO_BINDTODEVICE" "SO_BINDTOIFINDEX"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 27 +++++++++++++++++++ .../selftests/net/mptcp/mptcp_sockopt.sh | 6 +++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ static void do_setsockopt_bindtoifindex(int fd) perror("setsockopt(SO_BINDTOIFINDEX)"); } +static void do_setsockopt_freebind(int fd) +{ + int optname = (pf == AF_INET ? IP_FREEBIND : IPV6_FREEBIND); + int level = (pf == AF_INET ? SOL_IP : SOL_IPV6); + int enable = 1; + + if (setsockopt(fd, level, optname, &enable, sizeof(enable))) + perror("setsockopt(IP(V6)_FREEBIND)"); +} + static void do_setsockopts(int fd) { do_setsockopt_reuseaddr(fd); do_setsockopt_reuseport(fd); do_setsockopt_bindtodevice(fd); do_setsockopt_bindtoifindex(fd); + do_setsockopt_freebind(fd); } static int sock_listen_mptcp(const char * const listenaddr, @@ -XXX,XX +XXX,XX @@ static void do_getsockopt_bindtoifindex(int fd) assert(ifindex == get_ifindex(fd, "lo")); } +static void do_getsockopt_freebind(int fd) +{ + int optname = (pf == AF_INET ? IP_FREEBIND : IPV6_FREEBIND); + int level = (pf == AF_INET ? SOL_IP : SOL_IPV6); + socklen_t len; + int enable; + + len = sizeof(enable); + if (getsockopt(fd, level, optname, &enable, &len)) + die_perror("getsockopt(IP(V6)_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); @@ -XXX,XX +XXX,XX @@ 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_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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ - "SO_BINDTODEVICE" "SO_BINDTOIFINDEX"; do + "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ + "IP_FREEBIND"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ - "SO_BINDTODEVICE" "SO_BINDTOIFINDEX"; do + "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ + "IPV6_FREEBIND"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 27 +++++++++++++++++++ .../selftests/net/mptcp/mptcp_sockopt.sh | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ static void do_setsockopt_freebind(int fd) perror("setsockopt(IP(V6)_FREEBIND)"); } +static void do_setsockopt_transparent(int fd) +{ + int optname = (pf == AF_INET ? IP_TRANSPARENT : IPV6_TRANSPARENT); + int level = (pf == AF_INET ? SOL_IP : SOL_IPV6); + int enable = 1; + + if (setsockopt(fd, level, optname, &enable, sizeof(enable))) + perror("setsockopt(IP(V6)_TRANSPARENT)"); +} + static void do_setsockopts(int fd) { do_setsockopt_reuseaddr(fd); @@ -XXX,XX +XXX,XX @@ static void do_setsockopts(int fd) do_setsockopt_bindtodevice(fd); do_setsockopt_bindtoifindex(fd); do_setsockopt_freebind(fd); + do_setsockopt_transparent(fd); } static int sock_listen_mptcp(const char * const listenaddr, @@ -XXX,XX +XXX,XX @@ static void do_getsockopt_freebind(int fd) assert(enable == 1); } +static void do_getsockopt_transparent(int fd) +{ + int optname = (pf == AF_INET ? IP_TRANSPARENT : IPV6_TRANSPARENT); + int level = (pf == AF_INET ? SOL_IP : SOL_IPV6); + socklen_t len; + int enable; + + len = sizeof(enable); + if (getsockopt(fd, level, optname, &enable, &len)) + die_perror("getsockopt(IP(V6)_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); @@ -XXX,XX +XXX,XX @@ static void do_getsockopts(struct so_state *s, int fd, size_t r, size_t w) do_getsockopt_bindtoifindex(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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ - "IP_FREEBIND"; do + "IP_FREEBIND" "IP_TRANSPARENT"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ - "IPV6_FREEBIND"; do + "IPV6_FREEBIND" "IPV6_TRANSPARENT"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 6 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ static void do_setsockopt_transparent(int fd) perror("setsockopt(IP(V6)_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); @@ -XXX,XX +XXX,XX @@ static void do_setsockopts(int fd) do_setsockopt_bindtoifindex(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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ - "IP_FREEBIND" "IP_TRANSPARENT"; do + "IP_FREEBIND" "IP_TRANSPARENT" \ + "IP_BIND_ADDRESS_NO_PORT"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() for opt in "SOL_MPTCP" \ "SO_REUSEADDR" "SO_REUSEPORT" \ "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ - "IPV6_FREEBIND" "IPV6_TRANSPARENT"; do + "IPV6_FREEBIND" "IPV6_TRANSPARENT" \ + "IP_BIND_ADDRESS_NO_PORT"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 6 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() "SO_REUSEADDR" "SO_REUSEPORT" \ "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ "IP_FREEBIND" "IP_TRANSPARENT" \ - "IP_BIND_ADDRESS_NO_PORT"; do + "IP_BIND_ADDRESS_NO_PORT" \ + "IP_LOCAL_PORT_RANGE"; do print_title "$opt sockopt v4" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v4" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() "SO_REUSEADDR" "SO_REUSEPORT" \ "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ "IPV6_FREEBIND" "IPV6_TRANSPARENT" \ - "IP_BIND_ADDRESS_NO_PORT"; do + "IP_BIND_ADDRESS_NO_PORT" \ + "IP_LOCAL_PORT_RANGE"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1
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 | 30 +++++++++++++++++++ .../selftests/net/mptcp/mptcp_sockopt.sh | 3 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -XXX,XX +XXX,XX @@ 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 (pf != AF_INET6) + return; + + if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &v6only, + sizeof(v6only))) + perror("setsockopt(IPV6_V6ONLY)"); +} + static void do_setsockopts(int fd) { do_setsockopt_reuseaddr(fd); @@ -XXX,XX +XXX,XX @@ static void do_setsockopts(int fd) do_setsockopt_transparent(fd); do_setsockopt_bind_address_no_port(fd); do_setsockopt_local_port_range(fd); + do_setsockopt_v6only(fd); } static int sock_listen_mptcp(const char * const listenaddr, @@ -XXX,XX +XXX,XX @@ 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; + + if (pf != AF_INET6) + return; + + 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); @@ -XXX,XX +XXX,XX @@ 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); + + 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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() "SO_BINDTODEVICE" "SO_BINDTOIFINDEX" \ "IPV6_FREEBIND" "IPV6_TRANSPARENT" \ "IP_BIND_ADDRESS_NO_PORT" \ - "IP_LOCAL_PORT_RANGE"; do + "IP_LOCAL_PORT_RANGE" \ + "IPV6_V6ONLY"; do print_title "$opt sockopt v6" mptcp_lib_pr_ok mptcp_lib_result_pass "$opt sockopt v6" -- 2.48.1