Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'selftests/bpf: Migrate test_tcpbpf_user to be a part of test_progs'

Alexander Duyck says:

====================
Move the test functionality from test_tcpbpf_user into the test_progs
framework so that it will be run any time the test_progs framework is run.
This will help to prevent future test escapes as the individual tests, such
as test_tcpbpf_user, are less likely to be run by developers and CI
tests.

As a part of moving it over the series goes through and updates the code to
make use of the existing APIs included in the test_progs framework. This is
meant to simplify and streamline the test code and avoid duplication of
effort.

v2: Dropped test_tcpbpf_user from .gitignore
Replaced CHECK_FAIL calls with CHECK calls
Minimized changes in patch 1 when moving the file
Updated stg mail command line to display renames in submission
Added shutdown logic to end of run_test function to guarantee close
Added patch that replaces the two maps with use of global variables
v3: Left err at -1 while we are performing send/recv calls w/ data
Drop extra labels from test_tcpbpf_user in favor of keeping err label
Dropped redundant zero init for tcpbpf_globals result and key
Dropped replacing of "printf(" with "fprintf(stderr, "
Fixed error in use of ASSERT_OK_PTR which was skipping of run_test
Replaced "{ 0 }" with "{}" in init of global in test_tcpbpf_kern.c
Added "Acked-by" from Martin KaiFai Lau and Andrii Nakryiko
====================

Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+157 -371
-1
tools/testing/selftests/bpf/.gitignore
··· 8 8 fixdep 9 9 test_dev_cgroup 10 10 /test_progs* 11 - test_tcpbpf_user 12 11 test_verifier_log 13 12 feature 14 13 test_sock
+1 -2
tools/testing/selftests/bpf/Makefile
··· 32 32 33 33 # Order correspond to 'make run_tests' order 34 34 TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 35 - test_verifier_log test_dev_cgroup test_tcpbpf_user \ 35 + test_verifier_log test_dev_cgroup \ 36 36 test_sock test_sockmap get_cgroup_id_user test_socket_cookie \ 37 37 test_cgroup_storage \ 38 38 test_netcnt test_tcpnotify_user test_sysctl \ ··· 163 163 $(OUTPUT)/test_sock_addr: cgroup_helpers.c 164 164 $(OUTPUT)/test_socket_cookie: cgroup_helpers.c 165 165 $(OUTPUT)/test_sockmap: cgroup_helpers.c 166 - $(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c 167 166 $(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c 168 167 $(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c 169 168 $(OUTPUT)/test_cgroup_storage: cgroup_helpers.c
+141
tools/testing/selftests/bpf/prog_tests/tcpbpf_user.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <test_progs.h> 3 + #include <network_helpers.h> 4 + 5 + #include "test_tcpbpf.h" 6 + #include "test_tcpbpf_kern.skel.h" 7 + 8 + #define LO_ADDR6 "::1" 9 + #define CG_NAME "/tcpbpf-user-test" 10 + 11 + static __u32 duration; 12 + 13 + static void verify_result(struct tcpbpf_globals *result) 14 + { 15 + __u32 expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) | 16 + (1 << BPF_SOCK_OPS_RWND_INIT) | 17 + (1 << BPF_SOCK_OPS_TCP_CONNECT_CB) | 18 + (1 << BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB) | 19 + (1 << BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) | 20 + (1 << BPF_SOCK_OPS_NEEDS_ECN) | 21 + (1 << BPF_SOCK_OPS_STATE_CB) | 22 + (1 << BPF_SOCK_OPS_TCP_LISTEN_CB)); 23 + 24 + /* check global map */ 25 + CHECK(expected_events != result->event_map, "event_map", 26 + "unexpected event_map: actual 0x%08x != expected 0x%08x\n", 27 + result->event_map, expected_events); 28 + 29 + ASSERT_EQ(result->bytes_received, 501, "bytes_received"); 30 + ASSERT_EQ(result->bytes_acked, 1002, "bytes_acked"); 31 + ASSERT_EQ(result->data_segs_in, 1, "data_segs_in"); 32 + ASSERT_EQ(result->data_segs_out, 1, "data_segs_out"); 33 + ASSERT_EQ(result->bad_cb_test_rv, 0x80, "bad_cb_test_rv"); 34 + ASSERT_EQ(result->good_cb_test_rv, 0, "good_cb_test_rv"); 35 + ASSERT_EQ(result->num_listen, 1, "num_listen"); 36 + 37 + /* 3 comes from one listening socket + both ends of the connection */ 38 + ASSERT_EQ(result->num_close_events, 3, "num_close_events"); 39 + 40 + /* check setsockopt for SAVE_SYN */ 41 + ASSERT_EQ(result->tcp_save_syn, 0, "tcp_save_syn"); 42 + 43 + /* check getsockopt for SAVED_SYN */ 44 + ASSERT_EQ(result->tcp_saved_syn, 1, "tcp_saved_syn"); 45 + } 46 + 47 + static void run_test(struct tcpbpf_globals *result) 48 + { 49 + int listen_fd = -1, cli_fd = -1, accept_fd = -1; 50 + char buf[1000]; 51 + int err = -1; 52 + int i, rv; 53 + 54 + listen_fd = start_server(AF_INET6, SOCK_STREAM, LO_ADDR6, 0, 0); 55 + if (CHECK(listen_fd == -1, "start_server", "listen_fd:%d errno:%d\n", 56 + listen_fd, errno)) 57 + goto done; 58 + 59 + cli_fd = connect_to_fd(listen_fd, 0); 60 + if (CHECK(cli_fd == -1, "connect_to_fd(listen_fd)", 61 + "cli_fd:%d errno:%d\n", cli_fd, errno)) 62 + goto done; 63 + 64 + accept_fd = accept(listen_fd, NULL, NULL); 65 + if (CHECK(accept_fd == -1, "accept(listen_fd)", 66 + "accept_fd:%d errno:%d\n", accept_fd, errno)) 67 + goto done; 68 + 69 + /* Send 1000B of '+'s from cli_fd -> accept_fd */ 70 + for (i = 0; i < 1000; i++) 71 + buf[i] = '+'; 72 + 73 + rv = send(cli_fd, buf, 1000, 0); 74 + if (CHECK(rv != 1000, "send(cli_fd)", "rv:%d errno:%d\n", rv, errno)) 75 + goto done; 76 + 77 + rv = recv(accept_fd, buf, 1000, 0); 78 + if (CHECK(rv != 1000, "recv(accept_fd)", "rv:%d errno:%d\n", rv, errno)) 79 + goto done; 80 + 81 + /* Send 500B of '.'s from accept_fd ->cli_fd */ 82 + for (i = 0; i < 500; i++) 83 + buf[i] = '.'; 84 + 85 + rv = send(accept_fd, buf, 500, 0); 86 + if (CHECK(rv != 500, "send(accept_fd)", "rv:%d errno:%d\n", rv, errno)) 87 + goto done; 88 + 89 + rv = recv(cli_fd, buf, 500, 0); 90 + if (CHECK(rv != 500, "recv(cli_fd)", "rv:%d errno:%d\n", rv, errno)) 91 + goto done; 92 + 93 + /* 94 + * shutdown accept first to guarantee correct ordering for 95 + * bytes_received and bytes_acked when we go to verify the results. 96 + */ 97 + shutdown(accept_fd, SHUT_WR); 98 + err = recv(cli_fd, buf, 1, 0); 99 + if (CHECK(err, "recv(cli_fd) for fin", "err:%d errno:%d\n", err, errno)) 100 + goto done; 101 + 102 + shutdown(cli_fd, SHUT_WR); 103 + err = recv(accept_fd, buf, 1, 0); 104 + CHECK(err, "recv(accept_fd) for fin", "err:%d errno:%d\n", err, errno); 105 + done: 106 + if (accept_fd != -1) 107 + close(accept_fd); 108 + if (cli_fd != -1) 109 + close(cli_fd); 110 + if (listen_fd != -1) 111 + close(listen_fd); 112 + 113 + if (!err) 114 + verify_result(result); 115 + } 116 + 117 + void test_tcpbpf_user(void) 118 + { 119 + struct test_tcpbpf_kern *skel; 120 + int cg_fd = -1; 121 + 122 + skel = test_tcpbpf_kern__open_and_load(); 123 + if (CHECK(!skel, "open and load skel", "failed")) 124 + return; 125 + 126 + cg_fd = test__join_cgroup(CG_NAME); 127 + if (CHECK(cg_fd < 0, "test__join_cgroup(" CG_NAME ")", 128 + "cg_fd:%d errno:%d", cg_fd, errno)) 129 + goto err; 130 + 131 + skel->links.bpf_testcb = bpf_program__attach_cgroup(skel->progs.bpf_testcb, cg_fd); 132 + if (!ASSERT_OK_PTR(skel->links.bpf_testcb, "attach_cgroup(bpf_testcb)")) 133 + goto err; 134 + 135 + run_test(&skel->bss->global); 136 + 137 + err: 138 + if (cg_fd != -1) 139 + close(cg_fd); 140 + test_tcpbpf_kern__destroy(skel); 141 + }
+13 -73
tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c
··· 14 14 #include <bpf/bpf_endian.h> 15 15 #include "test_tcpbpf.h" 16 16 17 - struct { 18 - __uint(type, BPF_MAP_TYPE_ARRAY); 19 - __uint(max_entries, 4); 20 - __type(key, __u32); 21 - __type(value, struct tcpbpf_globals); 22 - } global_map SEC(".maps"); 23 - 24 - struct { 25 - __uint(type, BPF_MAP_TYPE_ARRAY); 26 - __uint(max_entries, 2); 27 - __type(key, __u32); 28 - __type(value, int); 29 - } sockopt_results SEC(".maps"); 30 - 31 - static inline void update_event_map(int event) 32 - { 33 - __u32 key = 0; 34 - struct tcpbpf_globals g, *gp; 35 - 36 - gp = bpf_map_lookup_elem(&global_map, &key); 37 - if (gp == NULL) { 38 - struct tcpbpf_globals g = {0}; 39 - 40 - g.event_map |= (1 << event); 41 - bpf_map_update_elem(&global_map, &key, &g, 42 - BPF_ANY); 43 - } else { 44 - g = *gp; 45 - g.event_map |= (1 << event); 46 - bpf_map_update_elem(&global_map, &key, &g, 47 - BPF_ANY); 48 - } 49 - } 50 - 17 + struct tcpbpf_globals global = {}; 51 18 int _version SEC("version") = 1; 52 19 53 20 SEC("sockops") ··· 72 105 73 106 op = (int) skops->op; 74 107 75 - update_event_map(op); 108 + global.event_map |= (1 << op); 76 109 77 110 switch (op) { 78 111 case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: 79 112 /* Test failure to set largest cb flag (assumes not defined) */ 80 - bad_call_rv = bpf_sock_ops_cb_flags_set(skops, 0x80); 113 + global.bad_cb_test_rv = bpf_sock_ops_cb_flags_set(skops, 0x80); 81 114 /* Set callback */ 82 - good_call_rv = bpf_sock_ops_cb_flags_set(skops, 115 + global.good_cb_test_rv = bpf_sock_ops_cb_flags_set(skops, 83 116 BPF_SOCK_OPS_STATE_CB_FLAG); 84 - /* Update results */ 85 - { 86 - __u32 key = 0; 87 - struct tcpbpf_globals g, *gp; 88 - 89 - gp = bpf_map_lookup_elem(&global_map, &key); 90 - if (!gp) 91 - break; 92 - g = *gp; 93 - g.bad_cb_test_rv = bad_call_rv; 94 - g.good_cb_test_rv = good_call_rv; 95 - bpf_map_update_elem(&global_map, &key, &g, 96 - BPF_ANY); 97 - } 98 117 break; 99 118 case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: 100 119 skops->sk_txhash = 0x12345f; ··· 96 143 97 144 thdr = (struct tcphdr *)(header + offset); 98 145 v = thdr->syn; 99 - __u32 key = 1; 100 146 101 - bpf_map_update_elem(&sockopt_results, &key, &v, 102 - BPF_ANY); 147 + global.tcp_saved_syn = v; 103 148 } 104 149 } 105 150 break; ··· 107 156 break; 108 157 case BPF_SOCK_OPS_STATE_CB: 109 158 if (skops->args[1] == BPF_TCP_CLOSE) { 110 - __u32 key = 0; 111 - struct tcpbpf_globals g, *gp; 112 - 113 - gp = bpf_map_lookup_elem(&global_map, &key); 114 - if (!gp) 115 - break; 116 - g = *gp; 117 159 if (skops->args[0] == BPF_TCP_LISTEN) { 118 - g.num_listen++; 160 + global.num_listen++; 119 161 } else { 120 - g.total_retrans = skops->total_retrans; 121 - g.data_segs_in = skops->data_segs_in; 122 - g.data_segs_out = skops->data_segs_out; 123 - g.bytes_received = skops->bytes_received; 124 - g.bytes_acked = skops->bytes_acked; 162 + global.total_retrans = skops->total_retrans; 163 + global.data_segs_in = skops->data_segs_in; 164 + global.data_segs_out = skops->data_segs_out; 165 + global.bytes_received = skops->bytes_received; 166 + global.bytes_acked = skops->bytes_acked; 125 167 } 126 - g.num_close_events++; 127 - bpf_map_update_elem(&global_map, &key, &g, 128 - BPF_ANY); 168 + global.num_close_events++; 129 169 } 130 170 break; 131 171 case BPF_SOCK_OPS_TCP_LISTEN_CB: ··· 124 182 v = bpf_setsockopt(skops, IPPROTO_TCP, TCP_SAVE_SYN, 125 183 &save_syn, sizeof(save_syn)); 126 184 /* Update global map w/ result of setsock opt */ 127 - __u32 key = 0; 128 - 129 - bpf_map_update_elem(&sockopt_results, &key, &v, BPF_ANY); 185 + global.tcp_save_syn = v; 130 186 break; 131 187 default: 132 188 rv = -1;
-50
tools/testing/selftests/bpf/tcp_client.py
··· 1 - #!/usr/bin/env python3 2 - # 3 - # SPDX-License-Identifier: GPL-2.0 4 - # 5 - 6 - import sys, os, os.path, getopt 7 - import socket, time 8 - import subprocess 9 - import select 10 - 11 - def read(sock, n): 12 - buf = b'' 13 - while len(buf) < n: 14 - rem = n - len(buf) 15 - try: s = sock.recv(rem) 16 - except (socket.error) as e: return b'' 17 - buf += s 18 - return buf 19 - 20 - def send(sock, s): 21 - total = len(s) 22 - count = 0 23 - while count < total: 24 - try: n = sock.send(s) 25 - except (socket.error) as e: n = 0 26 - if n == 0: 27 - return count; 28 - count += n 29 - return count 30 - 31 - 32 - serverPort = int(sys.argv[1]) 33 - 34 - # create active socket 35 - sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 36 - try: 37 - sock.connect(('::1', serverPort)) 38 - except socket.error as e: 39 - sys.exit(1) 40 - 41 - buf = b'' 42 - n = 0 43 - while n < 1000: 44 - buf += b'+' 45 - n += 1 46 - 47 - sock.settimeout(1); 48 - n = send(sock, buf) 49 - n = read(sock, 500) 50 - sys.exit(0)
-80
tools/testing/selftests/bpf/tcp_server.py
··· 1 - #!/usr/bin/env python3 2 - # 3 - # SPDX-License-Identifier: GPL-2.0 4 - # 5 - 6 - import sys, os, os.path, getopt 7 - import socket, time 8 - import subprocess 9 - import select 10 - 11 - def read(sock, n): 12 - buf = b'' 13 - while len(buf) < n: 14 - rem = n - len(buf) 15 - try: s = sock.recv(rem) 16 - except (socket.error) as e: return b'' 17 - buf += s 18 - return buf 19 - 20 - def send(sock, s): 21 - total = len(s) 22 - count = 0 23 - while count < total: 24 - try: n = sock.send(s) 25 - except (socket.error) as e: n = 0 26 - if n == 0: 27 - return count; 28 - count += n 29 - return count 30 - 31 - 32 - SERVER_PORT = 12877 33 - MAX_PORTS = 2 34 - 35 - serverPort = SERVER_PORT 36 - serverSocket = None 37 - 38 - # create passive socket 39 - serverSocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 40 - 41 - try: serverSocket.bind(('::1', 0)) 42 - except socket.error as msg: 43 - print('bind fails: ' + str(msg)) 44 - 45 - sn = serverSocket.getsockname() 46 - serverPort = sn[1] 47 - 48 - cmdStr = ("./tcp_client.py %d &") % (serverPort) 49 - os.system(cmdStr) 50 - 51 - buf = b'' 52 - n = 0 53 - while n < 500: 54 - buf += b'.' 55 - n += 1 56 - 57 - serverSocket.listen(MAX_PORTS) 58 - readList = [serverSocket] 59 - 60 - while True: 61 - readyRead, readyWrite, inError = \ 62 - select.select(readList, [], [], 2) 63 - 64 - if len(readyRead) > 0: 65 - waitCount = 0 66 - for sock in readyRead: 67 - if sock == serverSocket: 68 - (clientSocket, address) = serverSocket.accept() 69 - address = str(address[0]) 70 - readList.append(clientSocket) 71 - else: 72 - sock.settimeout(1); 73 - s = read(sock, 1000) 74 - n = send(sock, buf) 75 - sock.close() 76 - serverSocket.close() 77 - sys.exit(0) 78 - else: 79 - print('Select timeout!') 80 - sys.exit(1)
+2
tools/testing/selftests/bpf/test_tcpbpf.h
··· 14 14 __u64 bytes_acked; 15 15 __u32 num_listen; 16 16 __u32 num_close_events; 17 + __u32 tcp_save_syn; 18 + __u32 tcp_saved_syn; 17 19 }; 18 20 #endif
-165
tools/testing/selftests/bpf/test_tcpbpf_user.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - #include <inttypes.h> 3 - #include <stdio.h> 4 - #include <stdlib.h> 5 - #include <unistd.h> 6 - #include <errno.h> 7 - #include <string.h> 8 - #include <linux/bpf.h> 9 - #include <sys/types.h> 10 - #include <bpf/bpf.h> 11 - #include <bpf/libbpf.h> 12 - 13 - #include "bpf_rlimit.h" 14 - #include "bpf_util.h" 15 - #include "cgroup_helpers.h" 16 - 17 - #include "test_tcpbpf.h" 18 - 19 - /* 3 comes from one listening socket + both ends of the connection */ 20 - #define EXPECTED_CLOSE_EVENTS 3 21 - 22 - #define EXPECT_EQ(expected, actual, fmt) \ 23 - do { \ 24 - if ((expected) != (actual)) { \ 25 - printf(" Value of: " #actual "\n" \ 26 - " Actual: %" fmt "\n" \ 27 - " Expected: %" fmt "\n", \ 28 - (actual), (expected)); \ 29 - ret--; \ 30 - } \ 31 - } while (0) 32 - 33 - int verify_result(const struct tcpbpf_globals *result) 34 - { 35 - __u32 expected_events; 36 - int ret = 0; 37 - 38 - expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) | 39 - (1 << BPF_SOCK_OPS_RWND_INIT) | 40 - (1 << BPF_SOCK_OPS_TCP_CONNECT_CB) | 41 - (1 << BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB) | 42 - (1 << BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) | 43 - (1 << BPF_SOCK_OPS_NEEDS_ECN) | 44 - (1 << BPF_SOCK_OPS_STATE_CB) | 45 - (1 << BPF_SOCK_OPS_TCP_LISTEN_CB)); 46 - 47 - EXPECT_EQ(expected_events, result->event_map, "#" PRIx32); 48 - EXPECT_EQ(501ULL, result->bytes_received, "llu"); 49 - EXPECT_EQ(1002ULL, result->bytes_acked, "llu"); 50 - EXPECT_EQ(1, result->data_segs_in, PRIu32); 51 - EXPECT_EQ(1, result->data_segs_out, PRIu32); 52 - EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32); 53 - EXPECT_EQ(0, result->good_cb_test_rv, PRIu32); 54 - EXPECT_EQ(1, result->num_listen, PRIu32); 55 - EXPECT_EQ(EXPECTED_CLOSE_EVENTS, result->num_close_events, PRIu32); 56 - 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; 77 - } 78 - 79 - static int bpf_find_map(const char *test, struct bpf_object *obj, 80 - const char *name) 81 - { 82 - struct bpf_map *map; 83 - 84 - map = bpf_object__find_map_by_name(obj, name); 85 - if (!map) { 86 - printf("%s:FAIL:map '%s' not found\n", test, name); 87 - return -1; 88 - } 89 - return bpf_map__fd(map); 90 - } 91 - 92 - int main(int argc, char **argv) 93 - { 94 - const char *file = "test_tcpbpf_kern.o"; 95 - int prog_fd, map_fd, sock_map_fd; 96 - struct tcpbpf_globals g = {0}; 97 - const char *cg_path = "/foo"; 98 - int error = EXIT_FAILURE; 99 - struct bpf_object *obj; 100 - int cg_fd = -1; 101 - int retry = 10; 102 - __u32 key = 0; 103 - int rv; 104 - 105 - cg_fd = cgroup_setup_and_join(cg_path); 106 - if (cg_fd < 0) 107 - goto err; 108 - 109 - if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { 110 - printf("FAILED: load_bpf_file failed for: %s\n", file); 111 - goto err; 112 - } 113 - 114 - rv = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_SOCK_OPS, 0); 115 - if (rv) { 116 - printf("FAILED: bpf_prog_attach: %d (%s)\n", 117 - error, strerror(errno)); 118 - goto err; 119 - } 120 - 121 - if (system("./tcp_server.py")) { 122 - printf("FAILED: TCP server\n"); 123 - goto err; 124 - } 125 - 126 - map_fd = bpf_find_map(__func__, obj, "global_map"); 127 - if (map_fd < 0) 128 - goto err; 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: 135 - rv = bpf_map_lookup_elem(map_fd, &key, &g); 136 - if (rv != 0) { 137 - printf("FAILED: bpf_map_lookup_elem returns %d\n", rv); 138 - goto err; 139 - } 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 - 148 - if (verify_result(&g)) { 149 - printf("FAILED: Wrong stats\n"); 150 - goto err; 151 - } 152 - 153 - if (verify_sockopt_result(sock_map_fd)) { 154 - printf("FAILED: Wrong sockopt stats\n"); 155 - goto err; 156 - } 157 - 158 - printf("PASSED!\n"); 159 - error = 0; 160 - err: 161 - bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); 162 - close(cg_fd); 163 - cleanup_cgroup_environment(); 164 - return error; 165 - }