From: Geliang Tang tanggeliang@kylinos.cn
This set is part 11 of series "use network helpers" all BPF selftests wide.
Finally something new in this set.
The helper make_sockaddr is extended to support sockets of AF_PACKET, AF_ALG and AF_VSOCK families. Then these types of sockets can be used to start_server_str() helper too.
Imitating connect_to_* interfaces, send_to_* interfaces are added to support sendto() with given FD or the address string.
Add more conditions to control listen: nolisten flag, listen_support() helper and clear "type" bits for listen.
Patch 1 for AF_UNIX socket: Patch 1 uses start_server_str for a AF_UNIX socket.
Patches 2-6 for AF_PACKET sockets: Patch 2 adds AF_PACKET support for make_sockaddr. Patch 3 uses start_server_str for a AF_PACKET socket. Patches 4-5 adds send_to_fd_opts/send_to_addr_str helpers. Patch 6 uses send_to_addr_str for a AF_PACKET socket.
Patches 7-9 for AF_ALG sockets: Patch 7 adds AF_ALG support for make_sockaddr. Patch 8 add nolisten flag, needed by patch 9. Patch 9 uses send_to_addr_str for a AF_ALG socket.
Patches 10-15 for AF_VSOCK sockets: Patch 10 adds AF_VSOCK support for make_sockaddr. Patches 11-12 uses make_sockaddr for AF_VSOCK sockets. Patches 13-14 adds more conditions to control listen. Patch 15 uses start_server_str for AF_VSOCK sockets.
Geliang Tang (15): selftests/bpf: Use start_server_str in skc_to_unix_sock selftests/bpf: AF_PACKET support for make_sockaddr selftests/bpf: Use start_server_str in lwt_redirect selftests/bpf: Add send_to_fd_opts helper selftests/bpf: Add send_to_addr_str helper selftests/bpf: Use send_to_addr_str in xdp_bonding selftests/bpf: AF_ALG support for make_sockaddr selftests/bpf: Add nolisten for network_helper_opts selftests/bpf: Use start_server_str in crypto_sanity selftests/bpf: AF_VSOCK support for make_sockaddr selftests/bpf: Add loopback_addr_str helper selftests/bpf: Use make_sockaddr in sockmap_helpers selftests/bpf: Check listen support for start_server_addr selftests/bpf: Clear type bits for start_server_addr selftests/bpf: Use start_server_str in sockmap_helpers
tools/testing/selftests/bpf/network_helpers.c | 144 +++++++++++++++--- tools/testing/selftests/bpf/network_helpers.h | 21 +++ .../selftests/bpf/prog_tests/crypto_sanity.c | 12 +- .../selftests/bpf/prog_tests/lwt_redirect.c | 21 +-- .../bpf/prog_tests/migrate_reuseport.c | 2 +- .../bpf/prog_tests/skc_to_unix_sock.c | 22 +-- .../bpf/prog_tests/sockmap_helpers.h | 101 +++--------- .../selftests/bpf/prog_tests/xdp_bonding.c | 20 +-- 8 files changed, 186 insertions(+), 157 deletions(-)
From: Geliang Tang tanggeliang@kylinos.cn
This patch uses network helper start_server_str() in skc_to_unix_sock test in skc_to_unix_sock.c to simplify the code.
This is the first time to use start_server_str() for a AF_UNIX socket. The first "@" of "sun_path" needs to be skipped by make_sockaddr(), so path string "sock_path + 1" ("skc_to_unix_sock") is passed to the helper, not "sock_path" ("@skc_to_unix_sock").
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- .../bpf/prog_tests/skc_to_unix_sock.c | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c b/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c index 3eefdfed1db9..4c23409a3072 100644 --- a/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c +++ b/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c @@ -4,13 +4,16 @@ #include <test_progs.h> #include <sys/un.h> #include "test_skc_to_unix_sock.skel.h" +#include "network_helpers.h"
static const char *sock_path = "@skc_to_unix_sock";
void test_skc_to_unix_sock(void) { + struct network_helper_opts opts = { + .backlog = 1, + }; struct test_skc_to_unix_sock *skel; - struct sockaddr_un sockaddr; int err, sockfd = 0;
skel = test_skc_to_unix_sock__open(); @@ -28,21 +31,8 @@ void test_skc_to_unix_sock(void) goto cleanup;
/* trigger unix_listen */ - sockfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (!ASSERT_GT(sockfd, 0, "socket failed")) - goto cleanup; - - memset(&sockaddr, 0, sizeof(sockaddr)); - sockaddr.sun_family = AF_UNIX; - strncpy(sockaddr.sun_path, sock_path, strlen(sock_path)); - sockaddr.sun_path[0] = '\0'; - - err = bind(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); - if (!ASSERT_OK(err, "bind failed")) - goto cleanup; - - err = listen(sockfd, 1); - if (!ASSERT_OK(err, "listen failed")) + sockfd = start_server_str(AF_UNIX, SOCK_STREAM, sock_path + 1, 0, &opts); + if (!ASSERT_OK_FD(sockfd, "start_server_str")) goto cleanup;
ASSERT_EQ(strcmp(skel->bss->path, sock_path), 0, "bpf_skc_to_unix_sock failed");
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds AF_PACKET support for make_sockaddr(), uses sscanf() to parse the given addr_str string into sll_ifindex, sll_halen and sll_addr of sockaddr_ll. Other fields of struct sockaddr_ll are not used in BPF selftests right now.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index a3f0a49fb26f..2a142d713861 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -416,6 +416,21 @@ int make_sockaddr(int family, const char *addr_str, __u16 port, if (len) *len = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(addr_str); return 0; + } else if (family == AF_PACKET) { + struct sockaddr_ll *sll = (void *)addr; + + memset(addr, 0, sizeof(*sll)); + sll->sll_family = family; + sll->sll_protocol = htons(ETH_P_ALL); + if (addr_str && + sscanf(addr_str, "%d %c %s", &sll->sll_ifindex, + &sll->sll_halen, sll->sll_addr) == -1) { + log_err("AF_PACKET sscanf(%s)", addr_str); + return -1; + } + if (len) + *len = sizeof(*sll); + return 0; } return -1; }
From: Geliang Tang tanggeliang@kylinos.cn
AF_PACKET can be passed to start_server_str() now. Use it to simplify the code in lwt_redirect.
In this test, use sprintf() to save the "ifindex" value into addr_str string, then pass it to the helper.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- .../selftests/bpf/prog_tests/lwt_redirect.c | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_redirect.c b/tools/testing/selftests/bpf/prog_tests/lwt_redirect.c index 835a1d756c16..f4c54bb7e416 100644 --- a/tools/testing/selftests/bpf/prog_tests/lwt_redirect.c +++ b/tools/testing/selftests/bpf/prog_tests/lwt_redirect.c @@ -94,30 +94,19 @@ static int new_packet_sock(const char *ifname) { int err = 0; int ignore_outgoing = 1; + char addr_str[32]; int ifindex = -1; int s = -1;
- s = socket(AF_PACKET, SOCK_RAW, 0); - if (!ASSERT_GE(s, 0, "socket(AF_PACKET)")) - return -1; - ifindex = if_nametoindex(ifname); - if (!ASSERT_GE(ifindex, 0, "if_nametoindex")) { - close(s); + if (!ASSERT_GE(ifindex, 0, "if_nametoindex")) return -1; - }
- struct sockaddr_ll addr = { - .sll_family = AF_PACKET, - .sll_protocol = htons(ETH_P_IP), - .sll_ifindex = ifindex, - }; + sprintf(addr_str, "%d", ifindex);
- err = bind(s, (struct sockaddr *)&addr, sizeof(addr)); - if (!ASSERT_OK(err, "bind(AF_PACKET)")) { - close(s); + s = start_server_str(AF_PACKET, SOCK_RAW, addr_str, 0, NULL); + if (!ASSERT_OK_FD(s, "start_server_str")) return -1; - }
/* Use packet socket to capture only the ingress, so we can distinguish * the case where a regression that actually redirects the packet to
From: Geliang Tang tanggeliang@kylinos.cn
Similar to network helpers connect_to_addr() and connect_to_fd_opts(), this patch adds two helpers send_to_addr() send_to_fd_opts() to use sendto() to send data. They accepts three more parameters "const void *data", "size_t datalen" and "int flags" for the sending data. send_to_addr() is a static function at this moment, only send_to_fd_opts() is exported.
The first user of send_to_fd_opts() is fastopen_connect() in network_helpers.c.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 65 ++++++++++++------- tools/testing/selftests/bpf/network_helpers.h | 2 + 2 files changed, 45 insertions(+), 22 deletions(-)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 2a142d713861..311c3a559414 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -206,41 +206,62 @@ void free_fds(int *fds, unsigned int nr_close_fds) } }
-int fastopen_connect(int server_fd, const char *data, unsigned int data_len, - int timeout_ms) +static int send_to_addr(int type, const void *data, size_t datalen, int flags, + const struct sockaddr_storage *addr, socklen_t addrlen, + const struct network_helper_opts *opts) { - struct sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - struct sockaddr_in *addr_in; int fd, ret;
- if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { - log_err("Failed to get server addr"); + fd = client_socket(addr->ss_family, type, opts); + if (fd < 0) { + log_err("Failed to create client socket"); return -1; }
- addr_in = (struct sockaddr_in *)&addr; - fd = socket(addr_in->sin_family, SOCK_STREAM, 0); - if (fd < 0) { - log_err("Failed to create client socket"); + ret = sendto(fd, data, datalen, flags, + (const struct sockaddr *)addr, addrlen); + if (ret != datalen) { + log_err("Failed to send to server"); + save_errno_close(fd); return -1; }
- if (settimeo(fd, timeout_ms)) - goto error_close; + return fd; +}
- ret = sendto(fd, data, data_len, MSG_FASTOPEN, (struct sockaddr *)&addr, - addrlen); - if (ret != data_len) { - log_err("sendto(data, %u) != %d\n", data_len, ret); - goto error_close; +int send_to_fd_opts(int server_fd, const void *data, size_t datalen, int flags, + const struct network_helper_opts *opts) +{ + struct sockaddr_storage addr; + socklen_t addrlen, optlen; + int type; + + if (!opts) + opts = &default_opts; + + optlen = sizeof(type); + if (getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &type, &optlen)) { + log_err("getsockopt(SOL_TYPE)"); + return -1; }
- return fd; + addrlen = sizeof(addr); + if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { + log_err("Failed to get server addr"); + return -1; + }
-error_close: - save_errno_close(fd); - return -1; + return send_to_addr(type, data, datalen, flags, &addr, addrlen, opts); +} + +int fastopen_connect(int server_fd, const char *data, unsigned int data_len, + int timeout_ms) +{ + struct network_helper_opts opts = { + .timeout_ms = timeout_ms, + }; + + return send_to_fd_opts(server_fd, data, data_len, MSG_FASTOPEN, &opts); }
int client_socket(int family, int type, diff --git a/tools/testing/selftests/bpf/network_helpers.h b/tools/testing/selftests/bpf/network_helpers.h index cce56955371f..19210a234bc1 100644 --- a/tools/testing/selftests/bpf/network_helpers.h +++ b/tools/testing/selftests/bpf/network_helpers.h @@ -74,6 +74,8 @@ int connect_to_addr_str(int family, int type, const char *addr_str, __u16 port, int connect_to_fd(int server_fd, int timeout_ms); int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts); int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms); +int send_to_fd_opts(int server_fd, const void *data, size_t datalen, int flags, + const struct network_helper_opts *opts); int fastopen_connect(int server_fd, const char *data, unsigned int data_len, int timeout_ms); int make_sockaddr(int family, const char *addr_str, __u16 port,
From: Geliang Tang tanggeliang@kylinos.cn
Similar to network helper connect_to_addr_str(), this patch adds a new helper send_to_addr_str(). It uses make_sockaddr() to make a sockaddr_storage type address from the "family", "addr_str" and "port" parameters and passes it to send_to_addr().
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 16 ++++++++++++++++ tools/testing/selftests/bpf/network_helpers.h | 3 +++ 2 files changed, 19 insertions(+)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 311c3a559414..a6c158718267 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -229,6 +229,22 @@ static int send_to_addr(int type, const void *data, size_t datalen, int flags, return fd; }
+int send_to_addr_str(int family, int type, const char *addr_str, __u16 port, + const void *data, size_t datalen, int flags, + const struct network_helper_opts *opts) +{ + struct sockaddr_storage addr; + socklen_t addrlen; + + if (!opts) + opts = &default_opts; + + if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) + return -1; + + return send_to_addr(type, data, datalen, flags, &addr, addrlen, opts); +} + int send_to_fd_opts(int server_fd, const void *data, size_t datalen, int flags, const struct network_helper_opts *opts) { diff --git a/tools/testing/selftests/bpf/network_helpers.h b/tools/testing/selftests/bpf/network_helpers.h index 19210a234bc1..ebed1fb1bd49 100644 --- a/tools/testing/selftests/bpf/network_helpers.h +++ b/tools/testing/selftests/bpf/network_helpers.h @@ -76,6 +76,9 @@ int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts); int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms); int send_to_fd_opts(int server_fd, const void *data, size_t datalen, int flags, const struct network_helper_opts *opts); +int send_to_addr_str(int family, int type, const char *addr_str, __u16 port, + const void *data, size_t datalen, int flags, + const struct network_helper_opts *opts); int fastopen_connect(int server_fd, const char *data, unsigned int data_len, int timeout_ms); int make_sockaddr(int family, const char *addr_str, __u16 port,
From: Geliang Tang tanggeliang@kylinos.cn
The first user of send_to_addr_str() is send_udp_packets() in xdp_bonding. Use sprintf() to generate "addr_str" string from ifindex, sll_halen and sll_addr, and pass it to send_to_addr_str(). Since IPPROTO_ICMP is used, set it as opts.proto and pass opts to the helper too.
Use ASSERT_OK_FD() to check the return fd of send_to_addr_str().
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- .../selftests/bpf/prog_tests/xdp_bonding.c | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c index 6d8b54124cb3..5c60268b805c 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c @@ -206,6 +206,9 @@ static void bonding_cleanup(struct skeletons *skeletons)
static int send_udp_packets(int vary_dst_ip) { + struct network_helper_opts opts = { + .proto = IPPROTO_RAW, + }; struct ethhdr eh = { .h_source = BOND1_MAC, .h_dest = BOND2_MAC, @@ -213,17 +216,15 @@ static int send_udp_packets(int vary_dst_ip) }; struct iphdr iph = {}; struct udphdr uh = {}; + char addr_str[32]; uint8_t buf[128]; int i, s = -1; int ifindex;
- s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); - if (!ASSERT_GE(s, 0, "socket")) - goto err; - ifindex = if_nametoindex("bond1"); if (!ASSERT_GT(ifindex, 0, "get bond1 ifindex")) goto err; + sprintf(addr_str, "%d %c %s", ifindex, ETH_ALEN, BOND2_MAC_STR);
iph.ihl = 5; iph.version = 4; @@ -237,13 +238,6 @@ static int send_udp_packets(int vary_dst_ip) iph.check = 0;
for (i = 1; i <= NPACKETS; i++) { - int n; - struct sockaddr_ll saddr_ll = { - .sll_ifindex = ifindex, - .sll_halen = ETH_ALEN, - .sll_addr = BOND2_MAC, - }; - /* vary the UDP destination port for even distribution with roundrobin/xor modes */ uh.dest++;
@@ -255,8 +249,8 @@ static int send_udp_packets(int vary_dst_ip) memcpy(buf + sizeof(eh), &iph, sizeof(iph)); memcpy(buf + sizeof(eh) + sizeof(iph), &uh, sizeof(uh));
- n = sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&saddr_ll, sizeof(saddr_ll)); - if (!ASSERT_EQ(n, sizeof(buf), "sendto")) + s = send_to_addr_str(AF_PACKET, SOCK_RAW, addr_str, 0, buf, sizeof(buf), 0, &opts); + if (!ASSERT_OK_FD(s, "send_to_addr_str")) goto err; }
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds AF_ALG support for make_sockaddr(), uses sscanf() to parse the given addr_str string to "salg_type" and "salg_name" of struct sockaddr_alg.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index a6c158718267..8f39adbc2c16 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -17,6 +17,7 @@ #include <linux/in.h> #include <linux/in6.h> #include <linux/limits.h> +#include <linux/if_alg.h>
#include "bpf_util.h" #include "network_helpers.h" @@ -468,6 +469,20 @@ int make_sockaddr(int family, const char *addr_str, __u16 port, if (len) *len = sizeof(*sll); return 0; + } else if (family == AF_ALG) { + struct sockaddr_alg *salg = (void *)addr; + + memset(addr, 0, sizeof(*salg)); + salg->salg_family = family; + if (addr_str && + sscanf(addr_str, "%s %s", + salg->salg_type, salg->salg_name) == -1) { + log_err("AF_ALG sscanf(%s)", addr_str); + return -1; + } + if (len) + *len = sizeof(*salg); + return 0; } return -1; }
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds a struct member "nolisten" for network_helper_opts, which is used to control whether to invoke listen() or not in start_server_addr().
Also print out a warning if backlog is set for a type not support listen for connections.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 5 ++++- tools/testing/selftests/bpf/network_helpers.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 8f39adbc2c16..f140a76d3d7f 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -109,11 +109,14 @@ int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t a goto error_close; }
- if (type == SOCK_STREAM) { + if (!opts->nolisten && type == SOCK_STREAM) { if (listen(fd, opts->backlog ? MAX(opts->backlog, 0) : 1) < 0) { log_err("Failed to listed on socket"); goto error_close; } + } else if (opts->backlog) { + log_err("Useless network helper opts: backlog %d", + opts->backlog); }
return fd; diff --git a/tools/testing/selftests/bpf/network_helpers.h b/tools/testing/selftests/bpf/network_helpers.h index ebed1fb1bd49..16f266c53b61 100644 --- a/tools/testing/selftests/bpf/network_helpers.h +++ b/tools/testing/selftests/bpf/network_helpers.h @@ -34,6 +34,7 @@ struct network_helper_opts { * changing the "tcp_syncookies" sysctl from 1 to 2. */ int backlog; + bool nolisten; int (*post_socket_cb)(int fd, void *opts); void *cb_opts; };
From: Geliang Tang tanggeliang@kylinos.cn
This patch uses start_server_str() to start a AF_ALG server in test crypto_sanity, since no listen is needed in this test, nolisten flag of network_helper_opts is set.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- .../testing/selftests/bpf/prog_tests/crypto_sanity.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/crypto_sanity.c b/tools/testing/selftests/bpf/prog_tests/crypto_sanity.c index b1a3a49a822a..9b7a26c79123 100644 --- a/tools/testing/selftests/bpf/prog_tests/crypto_sanity.c +++ b/tools/testing/selftests/bpf/prog_tests/crypto_sanity.c @@ -20,16 +20,12 @@ static int opfd = -1, tfmfd = -1; static const char algo[] = "ecb(aes)"; static int init_afalg(void) { - struct sockaddr_alg sa = { - .salg_family = AF_ALG, - .salg_type = "skcipher", - .salg_name = "ecb(aes)" + struct network_helper_opts opts = { + .nolisten = true, };
- tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (tfmfd == -1) - return errno; - if (bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) + tfmfd = start_server_str(AF_ALG, SOCK_SEQPACKET, "skcipher ecb(aes)", 0, &opts); + if (!ASSERT_OK_FD(tfmfd, "start_server_addr")) return errno; if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, crypto_key, 16) == -1) return errno;
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds AF_VSOCK support for make_sockaddr(), uses atoi() to convert the given addr_str string to an integer id and sets it to "svm_cid". Set "svm_port" as VMADDR_PORT_ANY if the value of port is zero.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index f140a76d3d7f..8b06b0bf66ae 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -18,6 +18,7 @@ #include <linux/in6.h> #include <linux/limits.h> #include <linux/if_alg.h> +#include <linux/vm_sockets.h>
#include "bpf_util.h" #include "network_helpers.h" @@ -486,6 +487,16 @@ int make_sockaddr(int family, const char *addr_str, __u16 port, if (len) *len = sizeof(*salg); return 0; + } else if (family == AF_VSOCK) { + struct sockaddr_vm *svm = (void *)addr; + + memset(addr, 0, sizeof(*svm)); + svm->svm_family = family; + svm->svm_port = port ?: VMADDR_PORT_ANY; + svm->svm_cid = addr_str ? atoi(addr_str) : 0; + if (len) + *len = sizeof(*svm); + return 0; } return -1; }
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds a new helper loopback_addr_str() to get the loopback address string according to the given different protocol family.
Also use this new helper in start_servers() in migrate_reuseport.c.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.h | 15 +++++++++++++++ .../selftests/bpf/prog_tests/migrate_reuseport.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/network_helpers.h b/tools/testing/selftests/bpf/network_helpers.h index 16f266c53b61..893f07c677da 100644 --- a/tools/testing/selftests/bpf/network_helpers.h +++ b/tools/testing/selftests/bpf/network_helpers.h @@ -55,6 +55,21 @@ struct ipv6_packet { } __packed; extern struct ipv6_packet pkt_v6;
+static inline char *loopback_addr_str(int family) +{ + switch (family) { + case AF_INET: + return "127.0.0.1"; + case AF_INET6: + return "::1"; + case AF_VSOCK: + return "1"; /* VMADDR_CID_LOCAL */ + default: + fprintf(stderr, "unsupported address family %d", family); + return NULL; + } +} + int settimeo(int fd, int timeout_ms); int start_server_str(int family, int type, const char *addr_str, __u16 port, const struct network_helper_opts *opts); diff --git a/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c b/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c index 653b0a20fab9..7c31c7fdaecb 100644 --- a/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c +++ b/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c @@ -221,7 +221,7 @@ static int start_servers(struct migrate_reuseport_test_case *test_case, prog_fd = bpf_program__fd(skel->progs.migrate_reuseport);
make_sockaddr(test_case->family, - test_case->family == AF_INET ? "127.0.0.1" : "::1", 0, + loopback_addr_str(test_case->family), 0, &test_case->addr, &test_case->addrlen);
for (i = 0; i < NR_SERVERS; i++) {
From: Geliang Tang tanggeliang@kylinos.cn
AF_VSOCK is supported in make_sockaddr() now, use it to implement init_addr_loopback() in sockmap_helpers.h. Then three local functions init_addr_loopback4(), init_addr_loopback6() and init_addr_loopback_vsock() can be dropped.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- .../bpf/prog_tests/sockmap_helpers.h | 54 +------------------ 1 file changed, 2 insertions(+), 52 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h index e880f97bc44d..0fe095497f34 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h @@ -1,17 +1,12 @@ #ifndef __SOCKMAP_HELPERS__ #define __SOCKMAP_HELPERS__
-#include <linux/vm_sockets.h> +#include "network_helpers.h"
#define IO_TIMEOUT_SEC 30 #define MAX_STRERR_LEN 256 #define MAX_TEST_NAME 80
-/* workaround for older vm_sockets.h */ -#ifndef VMADDR_CID_LOCAL -#define VMADDR_CID_LOCAL 1 -#endif - #define __always_unused __attribute__((__unused__))
#define _FAIL(errnum, fmt...) \ @@ -239,55 +234,10 @@ static inline int recv_timeout(int fd, void *buf, size_t len, int flags, return recv(fd, buf, len, flags); }
-static inline void init_addr_loopback4(struct sockaddr_storage *ss, - socklen_t *len) -{ - struct sockaddr_in *addr4 = memset(ss, 0, sizeof(*ss)); - - addr4->sin_family = AF_INET; - addr4->sin_port = 0; - addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - *len = sizeof(*addr4); -} - -static inline void init_addr_loopback6(struct sockaddr_storage *ss, - socklen_t *len) -{ - struct sockaddr_in6 *addr6 = memset(ss, 0, sizeof(*ss)); - - addr6->sin6_family = AF_INET6; - addr6->sin6_port = 0; - addr6->sin6_addr = in6addr_loopback; - *len = sizeof(*addr6); -} - -static inline void init_addr_loopback_vsock(struct sockaddr_storage *ss, - socklen_t *len) -{ - struct sockaddr_vm *addr = memset(ss, 0, sizeof(*ss)); - - addr->svm_family = AF_VSOCK; - addr->svm_port = VMADDR_PORT_ANY; - addr->svm_cid = VMADDR_CID_LOCAL; - *len = sizeof(*addr); -} - static inline void init_addr_loopback(int family, struct sockaddr_storage *ss, socklen_t *len) { - switch (family) { - case AF_INET: - init_addr_loopback4(ss, len); - return; - case AF_INET6: - init_addr_loopback6(ss, len); - return; - case AF_VSOCK: - init_addr_loopback_vsock(ss, len); - return; - default: - FAIL("unsupported address family %d", family); - } + make_sockaddr(family, loopback_addr_str(family), 0, ss, len); }
static inline struct sockaddr *sockaddr(struct sockaddr_storage *ss)
From: Geliang Tang tanggeliang@kylinos.cn
No only SOCK_STREAM type supports listen for connections on a socket, SOCK_SEQPACKET used in sockmap_listen.c supports it too. This patch adds a new helper listen_support() to check whether a given "type" supports listen for connections on a socket or not.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 8b06b0bf66ae..6b6734b893e4 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -82,6 +82,17 @@ int settimeo(int fd, int timeout_ms)
#define save_errno_close(fd) ({ int __save = errno; close(fd); errno = __save; })
+static bool listen_support(int type) +{ + switch (type) { + case SOCK_STREAM: + case SOCK_SEQPACKET: + return true; + default: + return false; + } +} + int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t addrlen, const struct network_helper_opts *opts) { @@ -110,7 +121,7 @@ int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t a goto error_close; }
- if (!opts->nolisten && type == SOCK_STREAM) { + if (!opts->nolisten && listen_support(type)) { if (listen(fd, opts->backlog ? MAX(opts->backlog, 0) : 1) < 0) { log_err("Failed to listed on socket"); goto error_close;
From: Geliang Tang tanggeliang@kylinos.cn
The types "sotype | SOCK_NONBLOCK" are passed to socket_loopback_reuseport by some tests in sockmap_listen.c, so they must be handled in helper start_server_addr() too.
This patch uses SOCK_TYPE_MASK to clear useless bits of "type" before check whether it supports listen for connections.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- tools/testing/selftests/bpf/network_helpers.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 6b6734b893e4..919b691c2699 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -28,6 +28,9 @@ #define IPPROTO_MPTCP 262 #endif
+#define SOCK_MAX (SOCK_PACKET + 1) +#define SOCK_TYPE_MASK 0xf + #define clean_errno() (errno == 0 ? "None" : strerror(errno)) #define log_err(MSG, ...) ({ \ int __save = errno; \ @@ -121,6 +124,9 @@ int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t a goto error_close; }
+ if (type > SOCK_MAX) + type &= SOCK_TYPE_MASK; + if (!opts->nolisten && listen_support(type)) { if (listen(fd, opts->backlog ? MAX(opts->backlog, 0) : 1) < 0) { log_err("Failed to listed on socket");
From: Geliang Tang tanggeliang@kylinos.cn
Now both SOCK_SEQPACKET and SOCK_NONBLOCK can be passed as "type" parameter into start_server_str(), use this helper in socket_loopback_reuseport() in sockmap_helpers.h to simplify the code.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn --- .../bpf/prog_tests/sockmap_helpers.h | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h index 0fe095497f34..1e681e71e9ad 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h @@ -310,8 +310,14 @@ static inline int create_socket_pairs(int s, int family, int sotype, return err; }
-static inline int enable_reuseport(int s, int progfd) +struct cb_opts { + int progfd; +}; + +static int enable_reuseport(int s, void *opts) { + struct cb_opts *co = (struct cb_opts *)opts; + int progfd = co->progfd; int err, one = 1;
err = xsetsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); @@ -327,34 +333,19 @@ static inline int enable_reuseport(int s, int progfd)
static inline int socket_loopback_reuseport(int family, int sotype, int progfd) { - struct sockaddr_storage addr; - socklen_t len = 0; - int err, s; - - init_addr_loopback(family, &addr, &len); - - s = xsocket(family, sotype, 0); - if (s == -1) - return -1; - - if (progfd >= 0) - enable_reuseport(s, progfd); - - err = xbind(s, sockaddr(&addr), len); - if (err) - goto close; - - if (sotype & SOCK_DGRAM) - return s; - - err = xlisten(s, SOMAXCONN); - if (err) - goto close; + struct cb_opts cb_opts = { + .progfd = progfd, + }; + struct network_helper_opts opts = { + .backlog = SOMAXCONN, + }; + + if (progfd >= 0) { + opts.post_socket_cb = enable_reuseport; + opts.cb_opts = &cb_opts; + }
- return s; -close: - xclose(s); - return -1; + return start_server_str(family, sotype, loopback_addr_str(family), 0, &opts); }
static inline int socket_loopback(int family, int sotype)
On Tue, Jul 23, 2024 at 3:22 PM Geliang Tang geliang@kernel.org wrote:
From: Geliang Tang tanggeliang@kylinos.cn
This set is part 11 of series "use network helpers" all BPF selftests wide.
Finally something new in this set.
Geliang,
See "Top scores (negative):" https://lore.kernel.org/bpf/ZqANgbFHX128IZYV@mini-arch/ you're the top spammer on this list.
I strongly suggest you invest just as much time in reviewing other people's patches as sending yours or they will all be automatically rejected.
Hi Alexei,
On Tue, 2024-07-23 at 17:04 -0700, Alexei Starovoitov wrote:
I strongly suggest you invest just as much time in reviewing other people's patches as sending yours or they will all be automatically rejected.
Thanks for your reminder. I didn't know that our community has such a rule. I will try to reduce the number of iterations of my patches and the number of my emails sent to our community.
I am very willing to review other people's patches, but I am only familiar with "BPF [SELFTESTS]" module. If possible, I would like to add myself (Geliang Tang geliang@kernel.org) as a reviewer of this module in MAINTAINERS so that I can receive emails of new patches for reviewing. Or please add this for me.
Thanks, -Geliang
On Tue, Jul 23, 2024 at 7:07 PM Geliang Tang geliang@kernel.org wrote:
Hi Alexei,
On Tue, 2024-07-23 at 17:04 -0700, Alexei Starovoitov wrote:
I strongly suggest you invest just as much time in reviewing other people's patches as sending yours or they will all be automatically rejected.
Thanks for your reminder. I didn't know that our community has such a rule. I will try to reduce the number of iterations of my patches and the number of my emails sent to our community.
Every patch submission has a cost. A reviewer and/or maintainer has to process it. You're sending way more than average, hence depleting the time reviewer/maintainers can spend on other submissions. This is not ok.
I am very willing to review other people's patches, but I am only familiar with "BPF [SELFTESTS]" module. If possible, I would like to add myself (Geliang Tang geliang@kernel.org) as a reviewer of this module in MAINTAINERS so that I can receive emails of new patches for reviewing. Or please add this for me.
That's not how it works. Anyone can subscribe to bpf@vger and start reviewing patches. After some time when developers and maintainers see that a person commenting on the patches actually adding value then they will get recognized with R: or M: in the MAINTAINERS file.
On Tue, 2024-07-23 at 19:43 -0700, Alexei Starovoitov wrote:
On Tue, Jul 23, 2024 at 7:07 PM Geliang Tang geliang@kernel.org wrote:
Hi Alexei,
On Tue, 2024-07-23 at 17:04 -0700, Alexei Starovoitov wrote:
I strongly suggest you invest just as much time in reviewing other people's patches as sending yours or they will all be automatically rejected.
Thanks for your reminder. I didn't know that our community has such a rule. I will try to reduce the number of iterations of my patches and the number of my emails sent to our community.
Every patch submission has a cost. A reviewer and/or maintainer has to process it. You're sending way more than average, hence depleting the time reviewer/maintainers can spend on other submissions. This is not ok.
I am very willing to review other people's patches, but I am only familiar with "BPF [SELFTESTS]" module. If possible, I would like to add myself (Geliang Tang geliang@kernel.org) as a reviewer of this module in MAINTAINERS so that I can receive emails of new patches for reviewing. Or please add this for me.
That's not how it works. Anyone can subscribe to bpf@vger and start reviewing patches. After some time when developers and maintainers see that a person commenting on the patches actually adding value then they will get recognized with R: or M: in the MAINTAINERS file.
Got it, thanks for your explanation.
-Geliang
linux-kselftest-mirror@lists.linaro.org