tools/testing/selftests/bpf/prog_tests/cgroup_ancestor.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/cgroup_ancestor.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/cgroup_ancestor.c
Extension
.c
Size
3466 bytes
Lines
142
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

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;

	if (!ASSERT_OK(connect(sock, (struct sockaddr *)&addr, sizeof(addr)), "connect")) {
		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,

Annotation

Implementation Notes