| .. | .. |
|---|
| 16 | 16 | |
|---|
| 17 | 17 | #include "test_tcpbpf.h" |
|---|
| 18 | 18 | |
|---|
| 19 | +/* 3 comes from one listening socket + both ends of the connection */ |
|---|
| 20 | +#define EXPECTED_CLOSE_EVENTS 3 |
|---|
| 21 | + |
|---|
| 19 | 22 | #define EXPECT_EQ(expected, actual, fmt) \ |
|---|
| 20 | 23 | do { \ |
|---|
| 21 | 24 | if ((expected) != (actual)) { \ |
|---|
| .. | .. |
|---|
| 23 | 26 | " Actual: %" fmt "\n" \ |
|---|
| 24 | 27 | " Expected: %" fmt "\n", \ |
|---|
| 25 | 28 | (actual), (expected)); \ |
|---|
| 26 | | - goto err; \ |
|---|
| 29 | + ret--; \ |
|---|
| 27 | 30 | } \ |
|---|
| 28 | 31 | } while (0) |
|---|
| 29 | 32 | |
|---|
| 30 | 33 | int verify_result(const struct tcpbpf_globals *result) |
|---|
| 31 | 34 | { |
|---|
| 32 | 35 | __u32 expected_events; |
|---|
| 36 | + int ret = 0; |
|---|
| 33 | 37 | |
|---|
| 34 | 38 | expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) | |
|---|
| 35 | 39 | (1 << BPF_SOCK_OPS_RWND_INIT) | |
|---|
| .. | .. |
|---|
| 48 | 52 | EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32); |
|---|
| 49 | 53 | EXPECT_EQ(0, result->good_cb_test_rv, PRIu32); |
|---|
| 50 | 54 | EXPECT_EQ(1, result->num_listen, PRIu32); |
|---|
| 55 | + EXPECT_EQ(EXPECTED_CLOSE_EVENTS, result->num_close_events, PRIu32); |
|---|
| 51 | 56 | |
|---|
| 52 | | - return 0; |
|---|
| 53 | | -err: |
|---|
| 54 | | - return -1; |
|---|
| 57 | + return ret; |
|---|
| 58 | +} |
|---|
| 59 | + |
|---|
| 60 | +int verify_sockopt_result(int sock_map_fd) |
|---|
| 61 | +{ |
|---|
| 62 | + __u32 key = 0; |
|---|
| 63 | + int ret = 0; |
|---|
| 64 | + int res; |
|---|
| 65 | + int rv; |
|---|
| 66 | + |
|---|
| 67 | + /* check setsockopt for SAVE_SYN */ |
|---|
| 68 | + rv = bpf_map_lookup_elem(sock_map_fd, &key, &res); |
|---|
| 69 | + EXPECT_EQ(0, rv, "d"); |
|---|
| 70 | + EXPECT_EQ(0, res, "d"); |
|---|
| 71 | + key = 1; |
|---|
| 72 | + /* check getsockopt for SAVED_SYN */ |
|---|
| 73 | + rv = bpf_map_lookup_elem(sock_map_fd, &key, &res); |
|---|
| 74 | + EXPECT_EQ(0, rv, "d"); |
|---|
| 75 | + EXPECT_EQ(1, res, "d"); |
|---|
| 76 | + return ret; |
|---|
| 55 | 77 | } |
|---|
| 56 | 78 | |
|---|
| 57 | 79 | static int bpf_find_map(const char *test, struct bpf_object *obj, |
|---|
| .. | .. |
|---|
| 70 | 92 | int main(int argc, char **argv) |
|---|
| 71 | 93 | { |
|---|
| 72 | 94 | const char *file = "test_tcpbpf_kern.o"; |
|---|
| 95 | + int prog_fd, map_fd, sock_map_fd; |
|---|
| 73 | 96 | struct tcpbpf_globals g = {0}; |
|---|
| 74 | 97 | const char *cg_path = "/foo"; |
|---|
| 75 | 98 | int error = EXIT_FAILURE; |
|---|
| 76 | 99 | struct bpf_object *obj; |
|---|
| 77 | | - int prog_fd, map_fd; |
|---|
| 78 | 100 | int cg_fd = -1; |
|---|
| 101 | + int retry = 10; |
|---|
| 79 | 102 | __u32 key = 0; |
|---|
| 80 | 103 | int rv; |
|---|
| 81 | 104 | |
|---|
| 82 | | - if (setup_cgroup_environment()) |
|---|
| 83 | | - goto err; |
|---|
| 84 | | - |
|---|
| 85 | | - cg_fd = create_and_get_cgroup(cg_path); |
|---|
| 86 | | - if (!cg_fd) |
|---|
| 87 | | - goto err; |
|---|
| 88 | | - |
|---|
| 89 | | - if (join_cgroup(cg_path)) |
|---|
| 105 | + cg_fd = cgroup_setup_and_join(cg_path); |
|---|
| 106 | + if (cg_fd < 0) |
|---|
| 90 | 107 | goto err; |
|---|
| 91 | 108 | |
|---|
| 92 | 109 | if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { |
|---|
| .. | .. |
|---|
| 110 | 127 | if (map_fd < 0) |
|---|
| 111 | 128 | goto err; |
|---|
| 112 | 129 | |
|---|
| 130 | + sock_map_fd = bpf_find_map(__func__, obj, "sockopt_results"); |
|---|
| 131 | + if (sock_map_fd < 0) |
|---|
| 132 | + goto err; |
|---|
| 133 | + |
|---|
| 134 | +retry_lookup: |
|---|
| 113 | 135 | rv = bpf_map_lookup_elem(map_fd, &key, &g); |
|---|
| 114 | 136 | if (rv != 0) { |
|---|
| 115 | 137 | printf("FAILED: bpf_map_lookup_elem returns %d\n", rv); |
|---|
| 116 | 138 | goto err; |
|---|
| 117 | 139 | } |
|---|
| 118 | 140 | |
|---|
| 141 | + if (g.num_close_events != EXPECTED_CLOSE_EVENTS && retry--) { |
|---|
| 142 | + printf("Unexpected number of close events (%d), retrying!\n", |
|---|
| 143 | + g.num_close_events); |
|---|
| 144 | + usleep(100); |
|---|
| 145 | + goto retry_lookup; |
|---|
| 146 | + } |
|---|
| 147 | + |
|---|
| 119 | 148 | if (verify_result(&g)) { |
|---|
| 120 | 149 | printf("FAILED: Wrong stats\n"); |
|---|
| 121 | 150 | goto err; |
|---|
| 122 | 151 | } |
|---|
| 123 | 152 | |
|---|
| 153 | + if (verify_sockopt_result(sock_map_fd)) { |
|---|
| 154 | + printf("FAILED: Wrong sockopt stats\n"); |
|---|
| 155 | + goto err; |
|---|
| 156 | + } |
|---|
| 157 | + |
|---|
| 124 | 158 | printf("PASSED!\n"); |
|---|
| 125 | 159 | error = 0; |
|---|
| 126 | 160 | err: |
|---|