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

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19-rc2 141 lines 3.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3#include "test_progs.h" 4#include "network_helpers.h" 5#include "cgroup_helpers.h" 6#include "cgroup_ancestor.skel.h" 7 8#define CGROUP_PATH "/skb_cgroup_test" 9#define TEST_NS "cgroup_ancestor_ns" 10#define NUM_CGROUP_LEVELS 4 11#define WAIT_AUTO_IP_MAX_ATTEMPT 10 12#define DST_ADDR "::1" 13#define DST_PORT 1234 14#define MAX_ASSERT_NAME 32 15 16struct test_data { 17 struct cgroup_ancestor *skel; 18 struct bpf_tc_hook qdisc; 19 struct bpf_tc_opts tc_attach; 20 struct nstoken *ns; 21}; 22 23static int send_datagram(void) 24{ 25 unsigned char buf[] = "some random test data"; 26 struct sockaddr_in6 addr = { .sin6_family = AF_INET6, 27 .sin6_port = htons(DST_PORT), }; 28 int sock, n; 29 30 if (!ASSERT_EQ(inet_pton(AF_INET6, DST_ADDR, &addr.sin6_addr), 1, 31 "inet_pton")) 32 return -1; 33 34 sock = socket(AF_INET6, SOCK_DGRAM, 0); 35 if (!ASSERT_OK_FD(sock, "create socket")) 36 return sock; 37 38 if (!ASSERT_OK(connect(sock, (struct sockaddr *)&addr, sizeof(addr)), "connect")) { 39 close(sock); 40 return -1; 41 } 42 43 n = sendto(sock, buf, sizeof(buf), 0, (const struct sockaddr *)&addr, 44 sizeof(addr)); 45 close(sock); 46 return ASSERT_EQ(n, sizeof(buf), "send data") ? 0 : -1; 47} 48 49static int setup_network(struct test_data *t) 50{ 51 SYS(fail, "ip netns add %s", TEST_NS); 52 t->ns = open_netns(TEST_NS); 53 if (!ASSERT_OK_PTR(t->ns, "open netns")) 54 goto cleanup_ns; 55 56 SYS(close_ns, "ip link set lo up"); 57 58 memset(&t->qdisc, 0, sizeof(t->qdisc)); 59 t->qdisc.sz = sizeof(t->qdisc); 60 t->qdisc.attach_point = BPF_TC_EGRESS; 61 t->qdisc.ifindex = if_nametoindex("lo"); 62 if (!ASSERT_NEQ(t->qdisc.ifindex, 0, "if_nametoindex")) 63 goto close_ns; 64 if (!ASSERT_OK(bpf_tc_hook_create(&t->qdisc), "qdisc add")) 65 goto close_ns; 66 67 memset(&t->tc_attach, 0, sizeof(t->tc_attach)); 68 t->tc_attach.sz = sizeof(t->tc_attach); 69 t->tc_attach.prog_fd = bpf_program__fd(t->skel->progs.log_cgroup_id); 70 if (!ASSERT_OK(bpf_tc_attach(&t->qdisc, &t->tc_attach), "filter add")) 71 goto cleanup_qdisc; 72 73 return 0; 74 75cleanup_qdisc: 76 bpf_tc_hook_destroy(&t->qdisc); 77close_ns: 78 close_netns(t->ns); 79cleanup_ns: 80 SYS_NOFAIL("ip netns del %s", TEST_NS); 81fail: 82 return 1; 83} 84 85static void cleanup_network(struct test_data *t) 86{ 87 bpf_tc_detach(&t->qdisc, &t->tc_attach); 88 bpf_tc_hook_destroy(&t->qdisc); 89 close_netns(t->ns); 90 SYS_NOFAIL("ip netns del %s", TEST_NS); 91} 92 93static void check_ancestors_ids(struct test_data *t) 94{ 95 __u64 expected_ids[NUM_CGROUP_LEVELS]; 96 char assert_name[MAX_ASSERT_NAME]; 97 __u32 level; 98 99 expected_ids[0] = get_cgroup_id("/.."); /* root cgroup */ 100 expected_ids[1] = get_cgroup_id(""); 101 expected_ids[2] = get_cgroup_id(CGROUP_PATH); 102 expected_ids[3] = 0; /* non-existent cgroup */ 103 104 for (level = 0; level < NUM_CGROUP_LEVELS; level++) { 105 snprintf(assert_name, MAX_ASSERT_NAME, 106 "ancestor id at level %d", level); 107 ASSERT_EQ(t->skel->bss->cgroup_ids[level], expected_ids[level], 108 assert_name); 109 } 110} 111 112void test_cgroup_ancestor(void) 113{ 114 struct test_data t; 115 int cgroup_fd; 116 117 t.skel = cgroup_ancestor__open_and_load(); 118 if (!ASSERT_OK_PTR(t.skel, "open and load")) 119 return; 120 121 t.skel->bss->dport = htons(DST_PORT); 122 cgroup_fd = cgroup_setup_and_join(CGROUP_PATH); 123 if (cgroup_fd < 0) 124 goto cleanup_progs; 125 126 if (setup_network(&t)) 127 goto cleanup_cgroups; 128 129 if (send_datagram()) 130 goto cleanup_network; 131 132 check_ancestors_ids(&t); 133 134cleanup_network: 135 cleanup_network(&t); 136cleanup_cgroups: 137 close(cgroup_fd); 138 cleanup_cgroup_environment(); 139cleanup_progs: 140 cgroup_ancestor__destroy(t.skel); 141}