1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.*/ 3 4 #define _GNU_SOURCE 5 #include <unistd.h> 6 #include <sys/syscall.h> 7 #include <sys/types.h> 8 #include <test_progs.h> 9 #include "cgrp_ls_tp_btf.skel.h" 10 #include "cgrp_ls_recursion.skel.h" 11 #include "cgrp_ls_attach_cgroup.skel.h" 12 #include "cgrp_ls_negative.skel.h" 13 #include "network_helpers.h" 14 15 struct socket_cookie { 16 __u64 cookie_key; 17 __u32 cookie_value; 18 }; 19 20 static void test_tp_btf(int cgroup_fd) 21 { 22 struct cgrp_ls_tp_btf *skel; 23 long val1 = 1, val2 = 0; 24 int err; 25 26 skel = cgrp_ls_tp_btf__open_and_load(); 27 if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) 28 return; 29 30 /* populate a value in map_b */ 31 err = bpf_map_update_elem(bpf_map__fd(skel->maps.map_b), &cgroup_fd, &val1, BPF_ANY); 32 if (!ASSERT_OK(err, "map_update_elem")) 33 goto out; 34 35 /* check value */ 36 err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.map_b), &cgroup_fd, &val2); 37 if (!ASSERT_OK(err, "map_lookup_elem")) 38 goto out; 39 if (!ASSERT_EQ(val2, 1, "map_lookup_elem, invalid val")) 40 goto out; 41 42 /* delete value */ 43 err = bpf_map_delete_elem(bpf_map__fd(skel->maps.map_b), &cgroup_fd); 44 if (!ASSERT_OK(err, "map_delete_elem")) 45 goto out; 46 47 skel->bss->target_pid = syscall(SYS_gettid); 48 49 err = cgrp_ls_tp_btf__attach(skel); 50 if (!ASSERT_OK(err, "skel_attach")) 51 goto out; 52 53 syscall(SYS_gettid); 54 syscall(SYS_gettid); 55 56 skel->bss->target_pid = 0; 57 58 /* 3x syscalls: 1x attach and 2x gettid */ 59 ASSERT_EQ(skel->bss->enter_cnt, 3, "enter_cnt"); 60 ASSERT_EQ(skel->bss->exit_cnt, 3, "exit_cnt"); 61 ASSERT_EQ(skel->bss->mismatch_cnt, 0, "mismatch_cnt"); 62 out: 63 cgrp_ls_tp_btf__destroy(skel); 64 } 65 66 static void test_attach_cgroup(int cgroup_fd) 67 { 68 int server_fd = 0, client_fd = 0, err = 0; 69 socklen_t addr_len = sizeof(struct sockaddr_in6); 70 struct cgrp_ls_attach_cgroup *skel; 71 __u32 cookie_expected_value; 72 struct sockaddr_in6 addr; 73 struct socket_cookie val; 74 75 skel = cgrp_ls_attach_cgroup__open_and_load(); 76 if (!ASSERT_OK_PTR(skel, "skel_open")) 77 return; 78 79 skel->links.set_cookie = bpf_program__attach_cgroup( 80 skel->progs.set_cookie, cgroup_fd); 81 if (!ASSERT_OK_PTR(skel->links.set_cookie, "prog_attach")) 82 goto out; 83 84 skel->links.update_cookie_sockops = bpf_program__attach_cgroup( 85 skel->progs.update_cookie_sockops, cgroup_fd); 86 if (!ASSERT_OK_PTR(skel->links.update_cookie_sockops, "prog_attach")) 87 goto out; 88 89 skel->links.update_cookie_tracing = bpf_program__attach( 90 skel->progs.update_cookie_tracing); 91 if (!ASSERT_OK_PTR(skel->links.update_cookie_tracing, "prog_attach")) 92 goto out; 93 94 server_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0); 95 if (!ASSERT_GE(server_fd, 0, "start_server")) 96 goto out; 97 98 client_fd = connect_to_fd(server_fd, 0); 99 if (!ASSERT_GE(client_fd, 0, "connect_to_fd")) 100 goto close_server_fd; 101 102 err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.socket_cookies), 103 &cgroup_fd, &val); 104 if (!ASSERT_OK(err, "map_lookup(socket_cookies)")) 105 goto close_client_fd; 106 107 err = getsockname(client_fd, (struct sockaddr *)&addr, &addr_len); 108 if (!ASSERT_OK(err, "getsockname")) 109 goto close_client_fd; 110 111 cookie_expected_value = (ntohs(addr.sin6_port) << 8) | 0xFF; 112 ASSERT_EQ(val.cookie_value, cookie_expected_value, "cookie_value"); 113 114 close_client_fd: 115 close(client_fd); 116 close_server_fd: 117 close(server_fd); 118 out: 119 cgrp_ls_attach_cgroup__destroy(skel); 120 } 121 122 static void test_recursion(int cgroup_fd) 123 { 124 struct cgrp_ls_recursion *skel; 125 int err; 126 127 skel = cgrp_ls_recursion__open_and_load(); 128 if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) 129 return; 130 131 err = cgrp_ls_recursion__attach(skel); 132 if (!ASSERT_OK(err, "skel_attach")) 133 goto out; 134 135 /* trigger sys_enter, make sure it does not cause deadlock */ 136 syscall(SYS_gettid); 137 138 out: 139 cgrp_ls_recursion__destroy(skel); 140 } 141 142 static void test_negative(void) 143 { 144 struct cgrp_ls_negative *skel; 145 146 skel = cgrp_ls_negative__open_and_load(); 147 if (!ASSERT_ERR_PTR(skel, "skel_open_and_load")) { 148 cgrp_ls_negative__destroy(skel); 149 return; 150 } 151 } 152 153 void test_cgrp_local_storage(void) 154 { 155 int cgroup_fd; 156 157 cgroup_fd = test__join_cgroup("/cgrp_local_storage"); 158 if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /cgrp_local_storage")) 159 return; 160 161 if (test__start_subtest("tp_btf")) 162 test_tp_btf(cgroup_fd); 163 if (test__start_subtest("attach_cgroup")) 164 test_attach_cgroup(cgroup_fd); 165 if (test__start_subtest("recursion")) 166 test_recursion(cgroup_fd); 167 if (test__start_subtest("negative")) 168 test_negative(); 169 170 close(cgroup_fd); 171 } 172