This patch extended the MPTCP test base, to test the new helper
bpf_skc_to_mptcp_sock().
Added a new function verify_msk() to verify the msk token, and a new
function get_msk_token() to parse the msk token from the output of the
command 'ip mptcp monitor'.
Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
tools/testing/selftests/bpf/bpf_tcp_helpers.h | 6 ++
.../testing/selftests/bpf/prog_tests/mptcp.c | 102 ++++++++++++++++--
tools/testing/selftests/bpf/progs/mptcp.c | 28 ++++-
3 files changed, 126 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/bpf/bpf_tcp_helpers.h b/tools/testing/selftests/bpf/bpf_tcp_helpers.h
index b1ede6f0b821..05f62f81cc4d 100644
--- a/tools/testing/selftests/bpf/bpf_tcp_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_tcp_helpers.h
@@ -83,6 +83,12 @@ struct tcp_sock {
__u64 tcp_mstamp; /* most recent packet received/sent */
} __attribute__((preserve_access_index));
+struct mptcp_sock {
+ struct inet_connection_sock sk;
+
+ __u32 token;
+} __attribute__((preserve_access_index));
+
static __always_inline struct inet_connection_sock *inet_csk(const struct sock *sk)
{
return (struct inet_connection_sock *)sk;
diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index 87ee7bd8a689..035a87755b94 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -3,19 +3,20 @@
#include "cgroup_helpers.h"
#include "network_helpers.h"
+char monitor_log_path[64];
+
struct mptcp_storage {
__u32 invoked;
__u32 is_mptcp;
+ __u32 token;
};
-static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 is_mptcp)
+static int verify_tsk(int map_fd, int client_fd)
{
+ char *msg = "plain TCP socket";
int err = 0, cfd = client_fd;
struct mptcp_storage val;
- if (is_mptcp == 1)
- return 0;
-
if (CHECK_FAIL(bpf_map_lookup_elem(map_fd, &cfd, &val) < 0)) {
perror("Failed to read socket storage");
return -1;
@@ -36,6 +37,85 @@ static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 is_mptcp)
return err;
}
+/*
+ * Parse the token from the output of 'ip mptcp monitor':
+ *
+ * [ CREATED] token=3ca933d3 remid=0 locid=0 saddr4=127.0.0.1 ...
+ * [ CREATED] token=2ab57040 remid=0 locid=0 saddr4=127.0.0.1 ...
+ */
+static __u32 get_msk_token(void)
+{
+ char *prefix = "[ CREATED] token=";
+ char buf[BUFSIZ] = {};
+ __u32 token = 0;
+ ssize_t len;
+ int fd;
+
+ sync();
+
+ fd = open(monitor_log_path, O_RDONLY);
+ if (CHECK_FAIL(fd < 0)) {
+ log_err("Failed to open %s", monitor_log_path);
+ goto err;
+ }
+
+ len = read(fd, buf, sizeof(buf));
+ if (CHECK_FAIL(len < 0)) {
+ log_err("Failed to read %s", monitor_log_path);
+ goto err;
+ }
+
+ if (strncmp(buf, prefix, strlen(prefix))) {
+ log_err("Invalid prefix %s", buf);
+ goto err;
+ }
+
+ token = strtol(buf + strlen(prefix), NULL, 16);
+
+err:
+ close(fd);
+ return token;
+}
+
+static int verify_msk(int map_fd, int client_fd)
+{
+ char *msg = "MPTCP subflow socket";
+ int err = 0, cfd = client_fd;
+ struct mptcp_storage val;
+ __u32 token;
+
+ token = get_msk_token();
+ if (token <= 0) {
+ log_err("Unexpected token %x", token);
+ return -1;
+ }
+
+ if (CHECK_FAIL(bpf_map_lookup_elem(map_fd, &cfd, &val) < 0)) {
+ perror("Failed to read socket storage");
+ return -1;
+ }
+
+ if (val.invoked != 1) {
+ log_err("%s: unexpected invoked count %d != 1",
+ msg, val.invoked);
+ err++;
+ }
+
+ if (val.is_mptcp != 1) {
+ log_err("%s: unexpected bpf_tcp_sock.is_mptcp %d != 1",
+ msg, val.is_mptcp);
+ err++;
+ }
+
+ if (val.token != token) {
+ log_err("Unexpected mptcp_sock.token %x != %x",
+ val.token, token);
+ err++;
+ }
+
+ return err;
+}
+
static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
{
int client_fd, prog_fd, map_fd, err;
@@ -70,8 +150,8 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
goto close_client_fd;
}
- err += is_mptcp ? verify_sk(map_fd, client_fd, "MPTCP subflow socket", 1) :
- verify_sk(map_fd, client_fd, "plain TCP socket", 0);
+ err += is_mptcp ? verify_msk(map_fd, client_fd) :
+ verify_tsk(map_fd, client_fd);
close_client_fd:
close(client_fd);
@@ -83,6 +163,7 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
void test_mptcp(void)
{
+ char cmd[256], tmp_dir[] = "/tmp/XXXXXX";
int server_fd, cgroup_fd;
cgroup_fd = test__join_cgroup("/mptcp");
@@ -100,6 +181,13 @@ void test_mptcp(void)
with_mptcp:
/* with MPTCP */
+ if (CHECK_FAIL(!mkdtemp(tmp_dir)))
+ goto close_cgroup_fd;
+ snprintf(monitor_log_path, sizeof(monitor_log_path),
+ "%s/ip_mptcp_monitor", tmp_dir);
+ snprintf(cmd, sizeof(cmd), "ip mptcp monitor > %s &", monitor_log_path);
+ if (CHECK_FAIL(system(cmd)))
+ goto close_cgroup_fd;
server_fd = start_mptcp_server(AF_INET, NULL, 0, 0);
if (CHECK_FAIL(server_fd < 0))
goto close_cgroup_fd;
@@ -107,6 +195,8 @@ void test_mptcp(void)
CHECK_FAIL(run_test(cgroup_fd, server_fd, true));
close(server_fd);
+ snprintf(cmd, sizeof(cmd), "rm -rf %s", tmp_dir);
+ system(cmd);
close_cgroup_fd:
close(cgroup_fd);
diff --git a/tools/testing/selftests/bpf/progs/mptcp.c b/tools/testing/selftests/bpf/progs/mptcp.c
index a14ed1b66da8..b08448a12c02 100644
--- a/tools/testing/selftests/bpf/progs/mptcp.c
+++ b/tools/testing/selftests/bpf/progs/mptcp.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
+#include "bpf_tcp_helpers.h"
char _license[] SEC("license") = "GPL";
__u32 _version SEC("version") = 1;
@@ -8,6 +9,7 @@ __u32 _version SEC("version") = 1;
struct mptcp_storage {
__u32 invoked;
__u32 is_mptcp;
+ __u32 token;
};
struct {
@@ -20,8 +22,10 @@ struct {
SEC("sockops")
int _sockops(struct bpf_sock_ops *ctx)
{
+ char fmt[] = "invoked=%u is_mptcp=%u token=%x";
struct mptcp_storage *storage;
struct bpf_tcp_sock *tcp_sk;
+ struct mptcp_sock *msk;
int op = (int)ctx->op;
struct bpf_sock *sk;
@@ -36,13 +40,29 @@ int _sockops(struct bpf_sock_ops *ctx)
if (!tcp_sk)
return 1;
- storage = bpf_sk_storage_get(&socket_storage_map, sk, 0,
- BPF_SK_STORAGE_GET_F_CREATE);
- if (!storage)
- return 1;
+ if (!tcp_sk->is_mptcp) {
+ storage = bpf_sk_storage_get(&socket_storage_map, sk, 0,
+ BPF_SK_STORAGE_GET_F_CREATE);
+ if (!storage)
+ return 1;
+
+ storage->token = 0;
+ } else {
+ msk = bpf_skc_to_mptcp_sock(sk);
+ if (!msk)
+ return 1;
+
+ storage = bpf_sk_storage_get(&socket_storage_map, msk, 0,
+ BPF_SK_STORAGE_GET_F_CREATE);
+ if (!storage)
+ return 1;
+ storage->token = msk->token;
+ }
storage->invoked++;
storage->is_mptcp = tcp_sk->is_mptcp;
+ bpf_trace_printk(fmt, sizeof(fmt),
+ storage->invoked, storage->is_mptcp, storage->token);
return 1;
}
--
2.34.1