selftests/bpf: Verify token of struct mptcp_sock
authorGeliang Tang <geliang.tang@suse.com>
Thu, 19 May 2022 23:30:14 +0000 (16:30 -0700)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 20 May 2022 22:35:00 +0000 (15:35 -0700)
This patch verifies the struct member token of struct mptcp_sock. Add a
new member token in struct mptcp_storage to store the token value of the
msk socket got by bpf_skc_to_mptcp_sock(). Trace the kernel function
mptcp_pm_new_connection() by using bpf fentry prog to obtain the msk token
and save it in a global bpf variable. Pass the variable to verify_msk() to
verify it with the token saved in socket_storage_map.

v4:
 - use ASSERT_* instead of CHECK_FAIL (Andrii)
 - skip the test if 'ip mptcp monitor' is not supported (Mat)

v5:
 - Drop 'ip mptcp monitor', trace mptcp_pm_new_connection instead (Martin)
 - Use ASSERT_EQ (Andrii)

Signed-off-by: Geliang Tang <geliang.tang@suse.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Link: https://lore.kernel.org/bpf/20220519233016.105670-6-mathew.j.martineau@linux.intel.com
tools/testing/selftests/bpf/bpf_tcp_helpers.h
tools/testing/selftests/bpf/prog_tests/mptcp.c
tools/testing/selftests/bpf/progs/mptcp_sock.c

index 1a3f6ece429e906b9ff9f35a104b2a65babf6788..422491872619c37b2e4ef486f7d84db41fb5167a 100644 (file)
@@ -228,6 +228,8 @@ extern void tcp_cong_avoid_ai(struct tcp_sock *tp, __u32 w, __u32 acked) __ksym;
 
 struct mptcp_sock {
        struct inet_connection_sock     sk;
 
 struct mptcp_sock {
        struct inet_connection_sock     sk;
+
+       __u32           token;
 } __attribute__((preserve_access_index));
 
 #endif
 } __attribute__((preserve_access_index));
 
 #endif
index 227682ae8e09f450f5e169b461acf7bf977f9369..c84d7c593f9f7c303b81574a2c1925b0678d0d8c 100644 (file)
@@ -10,6 +10,7 @@
 struct mptcp_storage {
        __u32 invoked;
        __u32 is_mptcp;
 struct mptcp_storage {
        __u32 invoked;
        __u32 is_mptcp;
+       __u32 token;
 };
 
 static int verify_tsk(int map_fd, int client_fd)
 };
 
 static int verify_tsk(int map_fd, int client_fd)
@@ -30,11 +31,14 @@ static int verify_tsk(int map_fd, int client_fd)
        return err;
 }
 
        return err;
 }
 
-static int verify_msk(int map_fd, int client_fd)
+static int verify_msk(int map_fd, int client_fd, __u32 token)
 {
        int err, cfd = client_fd;
        struct mptcp_storage val;
 
 {
        int err, cfd = client_fd;
        struct mptcp_storage val;
 
+       if (!ASSERT_GT(token, 0, "invalid token"))
+               return -1;
+
        err = bpf_map_lookup_elem(map_fd, &cfd, &val);
        if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
                return err;
        err = bpf_map_lookup_elem(map_fd, &cfd, &val);
        if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
                return err;
@@ -45,6 +49,9 @@ static int verify_msk(int map_fd, int client_fd)
        if (!ASSERT_EQ(val.is_mptcp, 1, "unexpected is_mptcp"))
                err++;
 
        if (!ASSERT_EQ(val.is_mptcp, 1, "unexpected is_mptcp"))
                err++;
 
+       if (!ASSERT_EQ(val.token, token, "unexpected token"))
+               err++;
+
        return err;
 }
 
        return err;
 }
 
@@ -57,6 +64,10 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
        if (!ASSERT_OK_PTR(sock_skel, "skel_open_load"))
                return -EIO;
 
        if (!ASSERT_OK_PTR(sock_skel, "skel_open_load"))
                return -EIO;
 
+       err = mptcp_sock__attach(sock_skel);
+       if (!ASSERT_OK(err, "skel_attach"))
+               goto out;
+
        prog_fd = bpf_program__fd(sock_skel->progs._sockops);
        if (!ASSERT_GE(prog_fd, 0, "bpf_program__fd")) {
                err = -EIO;
        prog_fd = bpf_program__fd(sock_skel->progs._sockops);
        if (!ASSERT_GE(prog_fd, 0, "bpf_program__fd")) {
                err = -EIO;
@@ -79,7 +90,7 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
                goto out;
        }
 
                goto out;
        }
 
-       err += is_mptcp ? verify_msk(map_fd, client_fd) :
+       err += is_mptcp ? verify_msk(map_fd, client_fd, sock_skel->bss->token) :
                          verify_tsk(map_fd, client_fd);
 
        close(client_fd);
                          verify_tsk(map_fd, client_fd);
 
        close(client_fd);
index dc73b3fbb50bbf869acebac242f9c3d744c8fe13..f038b0e699a2f58dcc18e25fa98e579d318148a9 100644 (file)
@@ -7,10 +7,12 @@
 #include "bpf_tcp_helpers.h"
 
 char _license[] SEC("license") = "GPL";
 #include "bpf_tcp_helpers.h"
 
 char _license[] SEC("license") = "GPL";
+__u32 token = 0;
 
 struct mptcp_storage {
        __u32 invoked;
        __u32 is_mptcp;
 
 struct mptcp_storage {
        __u32 invoked;
        __u32 is_mptcp;
+       __u32 token;
 };
 
 struct {
 };
 
 struct {
@@ -47,6 +49,8 @@ int _sockops(struct bpf_sock_ops *ctx)
                                             BPF_SK_STORAGE_GET_F_CREATE);
                if (!storage)
                        return 1;
                                             BPF_SK_STORAGE_GET_F_CREATE);
                if (!storage)
                        return 1;
+
+               storage->token = 0;
        } else {
                msk = bpf_skc_to_mptcp_sock(sk);
                if (!msk)
        } else {
                msk = bpf_skc_to_mptcp_sock(sk);
                if (!msk)
@@ -56,9 +60,21 @@ int _sockops(struct bpf_sock_ops *ctx)
                                             BPF_SK_STORAGE_GET_F_CREATE);
                if (!storage)
                        return 1;
                                             BPF_SK_STORAGE_GET_F_CREATE);
                if (!storage)
                        return 1;
+
+               storage->token = msk->token;
        }
        storage->invoked++;
        storage->is_mptcp = is_mptcp;
 
        return 1;
 }
        }
        storage->invoked++;
        storage->is_mptcp = is_mptcp;
 
        return 1;
 }
+
+SEC("fentry/mptcp_pm_new_connection")
+int BPF_PROG(trace_mptcp_pm_new_connection, struct mptcp_sock *msk,
+            const struct sock *ssk, int server_side)
+{
+       if (!server_side)
+               token = msk->token;
+
+       return 0;
+}