| // SPDX-License-Identifier: GPL-2.0 |
| /* Copyright (c) 2020 Facebook */ |
| |
| #include <sys/types.h> |
| #include <bpf/bpf.h> |
| #include <bpf/libbpf.h> |
| #include "test_progs.h" |
| #include "network_helpers.h" |
| #include "test_sk_storage_trace_itself.skel.h" |
| #include "test_sk_storage_tracing.skel.h" |
| |
| #define LO_ADDR6 "::1" |
| #define TEST_COMM "test_progs" |
| |
| struct sk_stg { |
| __u32 pid; |
| __u32 last_notclose_state; |
| char comm[16]; |
| }; |
| |
| static struct test_sk_storage_tracing *skel; |
| static __u32 duration; |
| static pid_t my_pid; |
| |
| static int check_sk_stg(int sk_fd, __u32 expected_state) |
| { |
| struct sk_stg sk_stg; |
| int err; |
| |
| err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.sk_stg_map), &sk_fd, |
| &sk_stg); |
| if (!ASSERT_OK(err, "map_lookup(sk_stg_map)")) |
| return -1; |
| |
| if (!ASSERT_EQ(sk_stg.last_notclose_state, expected_state, |
| "last_notclose_state")) |
| return -1; |
| |
| if (!ASSERT_EQ(sk_stg.pid, my_pid, "pid")) |
| return -1; |
| |
| if (!ASSERT_STREQ(sk_stg.comm, skel->bss->task_comm, "task_comm")) |
| return -1; |
| |
| return 0; |
| } |
| |
| static void do_test(void) |
| { |
| int listen_fd = -1, passive_fd = -1, active_fd = -1, value = 1, err; |
| char abyte; |
| |
| listen_fd = start_server(AF_INET6, SOCK_STREAM, LO_ADDR6, 0, 0); |
| if (CHECK(listen_fd == -1, "start_server", |
| "listen_fd:%d errno:%d\n", listen_fd, errno)) |
| return; |
| |
| active_fd = connect_to_fd(listen_fd, 0); |
| if (CHECK(active_fd == -1, "connect_to_fd", "active_fd:%d errno:%d\n", |
| active_fd, errno)) |
| goto out; |
| |
| err = bpf_map_update_elem(bpf_map__fd(skel->maps.del_sk_stg_map), |
| &active_fd, &value, 0); |
| if (!ASSERT_OK(err, "map_update(del_sk_stg_map)")) |
| goto out; |
| |
| passive_fd = accept(listen_fd, NULL, 0); |
| if (CHECK(passive_fd == -1, "accept", "passive_fd:%d errno:%d\n", |
| passive_fd, errno)) |
| goto out; |
| |
| shutdown(active_fd, SHUT_WR); |
| err = read(passive_fd, &abyte, 1); |
| if (!ASSERT_OK(err, "read(passive_fd)")) |
| goto out; |
| |
| shutdown(passive_fd, SHUT_WR); |
| err = read(active_fd, &abyte, 1); |
| if (!ASSERT_OK(err, "read(active_fd)")) |
| goto out; |
| |
| err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.del_sk_stg_map), |
| &active_fd, &value); |
| if (!ASSERT_ERR(err, "map_lookup(del_sk_stg_map)")) |
| goto out; |
| |
| err = check_sk_stg(listen_fd, BPF_TCP_LISTEN); |
| if (!ASSERT_OK(err, "listen_fd sk_stg")) |
| goto out; |
| |
| err = check_sk_stg(active_fd, BPF_TCP_FIN_WAIT2); |
| if (!ASSERT_OK(err, "active_fd sk_stg")) |
| goto out; |
| |
| err = check_sk_stg(passive_fd, BPF_TCP_LAST_ACK); |
| ASSERT_OK(err, "passive_fd sk_stg"); |
| |
| out: |
| if (active_fd != -1) |
| close(active_fd); |
| if (passive_fd != -1) |
| close(passive_fd); |
| if (listen_fd != -1) |
| close(listen_fd); |
| } |
| |
| void serial_test_sk_storage_tracing(void) |
| { |
| struct test_sk_storage_trace_itself *skel_itself; |
| int err; |
| |
| my_pid = getpid(); |
| |
| skel_itself = test_sk_storage_trace_itself__open_and_load(); |
| |
| if (!ASSERT_NULL(skel_itself, "test_sk_storage_trace_itself")) { |
| test_sk_storage_trace_itself__destroy(skel_itself); |
| return; |
| } |
| |
| skel = test_sk_storage_tracing__open_and_load(); |
| if (!ASSERT_OK_PTR(skel, "test_sk_storage_tracing")) |
| return; |
| |
| err = test_sk_storage_tracing__attach(skel); |
| if (!ASSERT_OK(err, "test_sk_storage_tracing__attach")) { |
| test_sk_storage_tracing__destroy(skel); |
| return; |
| } |
| |
| do_test(); |
| |
| test_sk_storage_tracing__destroy(skel); |
| } |