Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <test_progs.h>
0003 #include <network_helpers.h>
0004 
0005 #include "test_tcpbpf.h"
0006 #include "test_tcpbpf_kern.skel.h"
0007 
0008 #define LO_ADDR6 "::1"
0009 #define CG_NAME "/tcpbpf-user-test"
0010 
0011 static __u32 duration;
0012 
0013 static void verify_result(struct tcpbpf_globals *result)
0014 {
0015     __u32 expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) |
0016                  (1 << BPF_SOCK_OPS_RWND_INIT) |
0017                  (1 << BPF_SOCK_OPS_TCP_CONNECT_CB) |
0018                  (1 << BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB) |
0019                  (1 << BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) |
0020                  (1 << BPF_SOCK_OPS_NEEDS_ECN) |
0021                  (1 << BPF_SOCK_OPS_STATE_CB) |
0022                  (1 << BPF_SOCK_OPS_TCP_LISTEN_CB));
0023 
0024     /* check global map */
0025     CHECK(expected_events != result->event_map, "event_map",
0026           "unexpected event_map: actual 0x%08x != expected 0x%08x\n",
0027           result->event_map, expected_events);
0028 
0029     ASSERT_EQ(result->bytes_received, 501, "bytes_received");
0030     ASSERT_EQ(result->bytes_acked, 1002, "bytes_acked");
0031     ASSERT_EQ(result->data_segs_in, 1, "data_segs_in");
0032     ASSERT_EQ(result->data_segs_out, 1, "data_segs_out");
0033     ASSERT_EQ(result->bad_cb_test_rv, 0x80, "bad_cb_test_rv");
0034     ASSERT_EQ(result->good_cb_test_rv, 0, "good_cb_test_rv");
0035     ASSERT_EQ(result->num_listen, 1, "num_listen");
0036 
0037     /* 3 comes from one listening socket + both ends of the connection */
0038     ASSERT_EQ(result->num_close_events, 3, "num_close_events");
0039 
0040     /* check setsockopt for SAVE_SYN */
0041     ASSERT_EQ(result->tcp_save_syn, 0, "tcp_save_syn");
0042 
0043     /* check getsockopt for SAVED_SYN */
0044     ASSERT_EQ(result->tcp_saved_syn, 1, "tcp_saved_syn");
0045 
0046     /* check getsockopt for window_clamp */
0047     ASSERT_EQ(result->window_clamp_client, 9216, "window_clamp_client");
0048     ASSERT_EQ(result->window_clamp_server, 9216, "window_clamp_server");
0049 }
0050 
0051 static void run_test(struct tcpbpf_globals *result)
0052 {
0053     int listen_fd = -1, cli_fd = -1, accept_fd = -1;
0054     char buf[1000];
0055     int err = -1;
0056     int i, rv;
0057 
0058     listen_fd = start_server(AF_INET6, SOCK_STREAM, LO_ADDR6, 0, 0);
0059     if (CHECK(listen_fd == -1, "start_server", "listen_fd:%d errno:%d\n",
0060           listen_fd, errno))
0061         goto done;
0062 
0063     cli_fd = connect_to_fd(listen_fd, 0);
0064     if (CHECK(cli_fd == -1, "connect_to_fd(listen_fd)",
0065           "cli_fd:%d errno:%d\n", cli_fd, errno))
0066         goto done;
0067 
0068     accept_fd = accept(listen_fd, NULL, NULL);
0069     if (CHECK(accept_fd == -1, "accept(listen_fd)",
0070           "accept_fd:%d errno:%d\n", accept_fd, errno))
0071         goto done;
0072 
0073     /* Send 1000B of '+'s from cli_fd -> accept_fd */
0074     for (i = 0; i < 1000; i++)
0075         buf[i] = '+';
0076 
0077     rv = send(cli_fd, buf, 1000, 0);
0078     if (CHECK(rv != 1000, "send(cli_fd)", "rv:%d errno:%d\n", rv, errno))
0079         goto done;
0080 
0081     rv = recv(accept_fd, buf, 1000, 0);
0082     if (CHECK(rv != 1000, "recv(accept_fd)", "rv:%d errno:%d\n", rv, errno))
0083         goto done;
0084 
0085     /* Send 500B of '.'s from accept_fd ->cli_fd */
0086     for (i = 0; i < 500; i++)
0087         buf[i] = '.';
0088 
0089     rv = send(accept_fd, buf, 500, 0);
0090     if (CHECK(rv != 500, "send(accept_fd)", "rv:%d errno:%d\n", rv, errno))
0091         goto done;
0092 
0093     rv = recv(cli_fd, buf, 500, 0);
0094     if (CHECK(rv != 500, "recv(cli_fd)", "rv:%d errno:%d\n", rv, errno))
0095         goto done;
0096 
0097     /*
0098      * shutdown accept first to guarantee correct ordering for
0099      * bytes_received and bytes_acked when we go to verify the results.
0100      */
0101     shutdown(accept_fd, SHUT_WR);
0102     err = recv(cli_fd, buf, 1, 0);
0103     if (CHECK(err, "recv(cli_fd) for fin", "err:%d errno:%d\n", err, errno))
0104         goto done;
0105 
0106     shutdown(cli_fd, SHUT_WR);
0107     err = recv(accept_fd, buf, 1, 0);
0108     CHECK(err, "recv(accept_fd) for fin", "err:%d errno:%d\n", err, errno);
0109 done:
0110     if (accept_fd != -1)
0111         close(accept_fd);
0112     if (cli_fd != -1)
0113         close(cli_fd);
0114     if (listen_fd != -1)
0115         close(listen_fd);
0116 
0117     if (!err)
0118         verify_result(result);
0119 }
0120 
0121 void test_tcpbpf_user(void)
0122 {
0123     struct test_tcpbpf_kern *skel;
0124     int cg_fd = -1;
0125 
0126     skel = test_tcpbpf_kern__open_and_load();
0127     if (CHECK(!skel, "open and load skel", "failed"))
0128         return;
0129 
0130     cg_fd = test__join_cgroup(CG_NAME);
0131     if (CHECK(cg_fd < 0, "test__join_cgroup(" CG_NAME ")",
0132           "cg_fd:%d errno:%d", cg_fd, errno))
0133         goto err;
0134 
0135     skel->links.bpf_testcb = bpf_program__attach_cgroup(skel->progs.bpf_testcb, cg_fd);
0136     if (!ASSERT_OK_PTR(skel->links.bpf_testcb, "attach_cgroup(bpf_testcb)"))
0137         goto err;
0138 
0139     run_test(&skel->bss->global);
0140 
0141 err:
0142     if (cg_fd != -1)
0143         close(cg_fd);
0144     test_tcpbpf_kern__destroy(skel);
0145 }