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 | 25 ++++-
3 files changed, 123 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..9ea6687c8f4d 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 5ec1cc4c2ef6..770104dc5448 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -8,16 +8,17 @@
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 char monitor_log_path[64];
+
+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;
@@ -38,6 +39,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);
+ return token;
+ }
+
+ 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;
@@ -90,8 +170,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);
@@ -103,6 +183,7 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
void test_base(void)
{
+ char cmd[256], tmp_dir[] = "/tmp/XXXXXX";
int server_fd, cgroup_fd;
cgroup_fd = test__join_cgroup("/mptcp");
@@ -120,6 +201,13 @@ void test_base(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;
@@ -127,6 +215,8 @@ void test_base(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 0d65fb889d03..afacea5ad9ca 100644
--- a/tools/testing/selftests/bpf/progs/mptcp.c
+++ b/tools/testing/selftests/bpf/progs/mptcp.c
@@ -3,6 +3,7 @@
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
+#include "bpf_tcp_helpers.h"
char _license[] SEC("license") = "GPL";
__u32 _version SEC("version") = 1;
@@ -10,6 +11,7 @@ __u32 _version SEC("version") = 1;
struct mptcp_storage {
__u32 invoked;
__u32 is_mptcp;
+ __u32 token;
};
struct {
@@ -24,6 +26,7 @@ int _sockops(struct bpf_sock_ops *ctx)
{
struct mptcp_storage *storage;
struct bpf_tcp_sock *tcp_sk;
+ struct mptcp_sock *msk;
int op = (int)ctx->op;
struct bpf_sock *sk;
@@ -38,11 +41,25 @@ 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;
--
2.34.1