Centos-kernel-stream-9/tools/testing/selftests/bpf/prog_tests/cgroup_ancestor.c

142 lines
3.4 KiB
C
Raw Normal View History

selftests/bpf: convert test_skb_cgroup_id_user to test_progs JIRA: https://issues.redhat.com/browse/RHEL-63880 Conflicts: Context change due to missing commit 37a14cfd667a ("selftests/bpf: convert test_cgroup_storage to test_progs") Context change due to missing commit 61ecfdfce264 ("selftests/bpf: Retire test_sock_addr.(c|sh)") Add the definition of TC_ACT_OK to bpf_tracing_net.h (missing commit 02b4e126e6a5 ("bpf: selftests: test_tunnel: Use vmlinux.h declarations")) Pickup headers change from missing upstream commit 90a695c3d31e1 to fix compilation error. commit f957c230e173cf227566686015016d05f7102d27 Author: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Date: Tue Aug 13 14:45:08 2024 +0200 selftests/bpf: convert test_skb_cgroup_id_user to test_progs test_skb_cgroup_id_user allows testing skb cgroup id retrieval at different levels, but is not integrated in test_progs, so it is not run automatically in CI. The test overlaps a bit with cgroup_skb_sk_lookup_kern, which is integrated in test_progs and test extensively skb cgroup helpers, but there is still one major difference between the two tests which justifies the conversion: cgroup_skb_sk_lookup_kern deals with a BPF_PROG_TYPE_CGROUP_SKB (attached on a cgroup), while test_skb_cgroup_id_user deals with a BPF_PROG_TYPE_SCHED_CLS (attached on a qdisc) Convert test_skb_cgroup_id_user into test_progs framework in order to run it automatically in CI. The main differences with the original test are the following: - rename the test to make it shorter and more straightforward regarding tested feature - the wrapping shell script has been dropped since every setup step is now handled in the main C test file - the test has been renamed for a shorter name and reflecting the tested API - add dedicated assert log per level to ease test failure debugging - use global variables instead of maps to access bpf prog data Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Link: https://lore.kernel.org/r/20240813-convert_cgroup_tests-v4-4-a33c03458cf6@bootlin.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
2024-12-18 10:56:34 +00:00
// SPDX-License-Identifier: GPL-2.0
#include "test_progs.h"
#include "network_helpers.h"
#include "cgroup_helpers.h"
#include "cgroup_ancestor.skel.h"
#define CGROUP_PATH "/skb_cgroup_test"
#define TEST_NS "cgroup_ancestor_ns"
#define NUM_CGROUP_LEVELS 4
#define WAIT_AUTO_IP_MAX_ATTEMPT 10
#define DST_ADDR "::1"
#define DST_PORT 1234
#define MAX_ASSERT_NAME 32
struct test_data {
struct cgroup_ancestor *skel;
struct bpf_tc_hook qdisc;
struct bpf_tc_opts tc_attach;
struct nstoken *ns;
};
static int send_datagram(void)
{
unsigned char buf[] = "some random test data";
struct sockaddr_in6 addr = { .sin6_family = AF_INET6,
.sin6_port = htons(DST_PORT), };
int sock, n;
if (!ASSERT_EQ(inet_pton(AF_INET6, DST_ADDR, &addr.sin6_addr), 1,
"inet_pton"))
return -1;
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (!ASSERT_OK_FD(sock, "create socket"))
return sock;
selftests/bpf: Fix error compiling cgroup_ancestor.c with musl libc JIRA: https://issues.redhat.com/browse/RHEL-63880 commit 60f802e2d6e10df609a80962b13558b7455ab32b Author: Tony Ambardar <tony.ambardar@gmail.com> Date: Tue Oct 8 16:12:32 2024 -0700 selftests/bpf: Fix error compiling cgroup_ancestor.c with musl libc Existing code calls connect() with a 'struct sockaddr_in6 *' argument where a 'struct sockaddr *' argument is declared, yielding compile errors when building for mips64el/musl-libc: In file included from cgroup_ancestor.c:3: cgroup_ancestor.c: In function 'send_datagram': cgroup_ancestor.c:38:38: error: passing argument 2 of 'connect' from incompatible pointer type [-Werror=incompatible-pointer-types] 38 | if (!ASSERT_OK(connect(sock, &addr, sizeof(addr)), "connect")) { | ^~~~~ | | | struct sockaddr_in6 * ./test_progs.h:343:29: note: in definition of macro 'ASSERT_OK' 343 | long long ___res = (res); \ | ^~~ In file included from .../netinet/in.h:10, from .../arpa/inet.h:9, from ./test_progs.h:17: .../sys/socket.h:386:19: note: expected 'const struct sockaddr *' but argument is of type 'struct sockaddr_in6 *' 386 | int connect (int, const struct sockaddr *, socklen_t); | ^~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors This only compiles because of a glibc extension allowing declaration of the argument as a "transparent union" which includes both types above. Explicitly cast the argument to allow compiling for both musl and glibc. Cc: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Fixes: f957c230e173 ("selftests/bpf: convert test_skb_cgroup_id_user to test_progs") Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com> Reviewed-by: Alexis Lothoré <alexis.lothore@bootlin.com> Link: https://lore.kernel.org/r/20241008231232.634047-1-tony.ambardar@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
2024-12-18 16:42:39 +00:00
if (!ASSERT_OK(connect(sock, (struct sockaddr *)&addr, sizeof(addr)), "connect")) {
selftests/bpf: convert test_skb_cgroup_id_user to test_progs JIRA: https://issues.redhat.com/browse/RHEL-63880 Conflicts: Context change due to missing commit 37a14cfd667a ("selftests/bpf: convert test_cgroup_storage to test_progs") Context change due to missing commit 61ecfdfce264 ("selftests/bpf: Retire test_sock_addr.(c|sh)") Add the definition of TC_ACT_OK to bpf_tracing_net.h (missing commit 02b4e126e6a5 ("bpf: selftests: test_tunnel: Use vmlinux.h declarations")) Pickup headers change from missing upstream commit 90a695c3d31e1 to fix compilation error. commit f957c230e173cf227566686015016d05f7102d27 Author: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Date: Tue Aug 13 14:45:08 2024 +0200 selftests/bpf: convert test_skb_cgroup_id_user to test_progs test_skb_cgroup_id_user allows testing skb cgroup id retrieval at different levels, but is not integrated in test_progs, so it is not run automatically in CI. The test overlaps a bit with cgroup_skb_sk_lookup_kern, which is integrated in test_progs and test extensively skb cgroup helpers, but there is still one major difference between the two tests which justifies the conversion: cgroup_skb_sk_lookup_kern deals with a BPF_PROG_TYPE_CGROUP_SKB (attached on a cgroup), while test_skb_cgroup_id_user deals with a BPF_PROG_TYPE_SCHED_CLS (attached on a qdisc) Convert test_skb_cgroup_id_user into test_progs framework in order to run it automatically in CI. The main differences with the original test are the following: - rename the test to make it shorter and more straightforward regarding tested feature - the wrapping shell script has been dropped since every setup step is now handled in the main C test file - the test has been renamed for a shorter name and reflecting the tested API - add dedicated assert log per level to ease test failure debugging - use global variables instead of maps to access bpf prog data Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Link: https://lore.kernel.org/r/20240813-convert_cgroup_tests-v4-4-a33c03458cf6@bootlin.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
2024-12-18 10:56:34 +00:00
close(sock);
return -1;
}
n = sendto(sock, buf, sizeof(buf), 0, (const struct sockaddr *)&addr,
sizeof(addr));
close(sock);
return ASSERT_EQ(n, sizeof(buf), "send data") ? 0 : -1;
}
static int setup_network(struct test_data *t)
{
SYS(fail, "ip netns add %s", TEST_NS);
t->ns = open_netns(TEST_NS);
if (!ASSERT_OK_PTR(t->ns, "open netns"))
goto cleanup_ns;
SYS(close_ns, "ip link set lo up");
memset(&t->qdisc, 0, sizeof(t->qdisc));
t->qdisc.sz = sizeof(t->qdisc);
t->qdisc.attach_point = BPF_TC_EGRESS;
t->qdisc.ifindex = if_nametoindex("lo");
if (!ASSERT_NEQ(t->qdisc.ifindex, 0, "if_nametoindex"))
goto close_ns;
if (!ASSERT_OK(bpf_tc_hook_create(&t->qdisc), "qdisc add"))
goto close_ns;
memset(&t->tc_attach, 0, sizeof(t->tc_attach));
t->tc_attach.sz = sizeof(t->tc_attach);
t->tc_attach.prog_fd = bpf_program__fd(t->skel->progs.log_cgroup_id);
if (!ASSERT_OK(bpf_tc_attach(&t->qdisc, &t->tc_attach), "filter add"))
goto cleanup_qdisc;
return 0;
cleanup_qdisc:
bpf_tc_hook_destroy(&t->qdisc);
close_ns:
close_netns(t->ns);
cleanup_ns:
SYS_NOFAIL("ip netns del %s", TEST_NS);
fail:
return 1;
}
static void cleanup_network(struct test_data *t)
{
bpf_tc_detach(&t->qdisc, &t->tc_attach);
bpf_tc_hook_destroy(&t->qdisc);
close_netns(t->ns);
SYS_NOFAIL("ip netns del %s", TEST_NS);
}
static void check_ancestors_ids(struct test_data *t)
{
__u64 expected_ids[NUM_CGROUP_LEVELS];
char assert_name[MAX_ASSERT_NAME];
__u32 level;
expected_ids[0] = get_cgroup_id("/.."); /* root cgroup */
expected_ids[1] = get_cgroup_id("");
expected_ids[2] = get_cgroup_id(CGROUP_PATH);
expected_ids[3] = 0; /* non-existent cgroup */
for (level = 0; level < NUM_CGROUP_LEVELS; level++) {
snprintf(assert_name, MAX_ASSERT_NAME,
"ancestor id at level %d", level);
ASSERT_EQ(t->skel->bss->cgroup_ids[level], expected_ids[level],
assert_name);
}
}
void test_cgroup_ancestor(void)
{
struct test_data t;
int cgroup_fd;
t.skel = cgroup_ancestor__open_and_load();
if (!ASSERT_OK_PTR(t.skel, "open and load"))
return;
t.skel->bss->dport = htons(DST_PORT);
cgroup_fd = cgroup_setup_and_join(CGROUP_PATH);
if (cgroup_fd < 0)
goto cleanup_progs;
if (setup_network(&t))
goto cleanup_cgroups;
if (send_datagram())
goto cleanup_network;
check_ancestors_ids(&t);
cleanup_network:
cleanup_network(&t);
cleanup_cgroups:
close(cgroup_fd);
cleanup_cgroup_environment();
cleanup_progs:
cgroup_ancestor__destroy(t.skel);
}