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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/cgroup_mprog_opts.c
Extension
.c
Size
15836 bytes
Lines
618
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

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
#include <test_progs.h>
#include "cgroup_helpers.h"
#include "cgroup_mprog.skel.h"

static void assert_mprog_count(int cg, int atype, int expected)
{
	__u32 count = 0, attach_flags = 0;
	int err;

	err = bpf_prog_query(cg, atype, 0, &attach_flags,
			     NULL, &count);
	ASSERT_EQ(count, expected, "count");
	ASSERT_EQ(err, 0, "prog_query");
}

static void test_prog_attach_detach(int atype)
{
	LIBBPF_OPTS(bpf_prog_attach_opts, opta);
	LIBBPF_OPTS(bpf_prog_detach_opts, optd);
	LIBBPF_OPTS(bpf_prog_query_opts, optq);
	__u32 fd1, fd2, fd3, fd4, id1, id2, id3, id4;
	struct cgroup_mprog *skel;
	__u32 prog_ids[10];
	int cg, err;

	cg = test__join_cgroup("/prog_attach_detach");
	if (!ASSERT_GE(cg, 0, "join_cgroup /prog_attach_detach"))
		return;

	skel = cgroup_mprog__open_and_load();
	if (!ASSERT_OK_PTR(skel, "skel_load"))
		goto cleanup;

	fd1 = bpf_program__fd(skel->progs.getsockopt_1);
	fd2 = bpf_program__fd(skel->progs.getsockopt_2);
	fd3 = bpf_program__fd(skel->progs.getsockopt_3);
	fd4 = bpf_program__fd(skel->progs.getsockopt_4);

	id1 = id_from_prog_fd(fd1);
	id2 = id_from_prog_fd(fd2);
	id3 = id_from_prog_fd(fd3);
	id4 = id_from_prog_fd(fd4);

	assert_mprog_count(cg, atype, 0);

	LIBBPF_OPTS_RESET(opta,
		.flags = BPF_F_ALLOW_MULTI | BPF_F_BEFORE | BPF_F_AFTER,
		.expected_revision = 1,
	);

	/* ordering: [fd1] */
	err = bpf_prog_attach_opts(fd1, cg, atype, &opta);
	if (!ASSERT_EQ(err, 0, "prog_attach"))
		goto cleanup;

	assert_mprog_count(cg, atype, 1);

	LIBBPF_OPTS_RESET(opta,
		.flags = BPF_F_ALLOW_MULTI | BPF_F_BEFORE,
		.expected_revision = 2,
	);

	/* ordering: [fd2, fd1] */
	err = bpf_prog_attach_opts(fd2, cg, atype, &opta);
	if (!ASSERT_EQ(err, 0, "prog_attach"))
		goto cleanup1;

	assert_mprog_count(cg, atype, 2);

	LIBBPF_OPTS_RESET(opta,
		.flags = BPF_F_ALLOW_MULTI | BPF_F_AFTER,
		.relative_fd = fd2,
		.expected_revision = 3,
	);

	/* ordering: [fd2, fd3, fd1] */
	err = bpf_prog_attach_opts(fd3, cg, atype, &opta);
	if (!ASSERT_EQ(err, 0, "prog_attach"))
		goto cleanup2;

	assert_mprog_count(cg, atype, 3);

	LIBBPF_OPTS_RESET(opta,
		.flags = BPF_F_ALLOW_MULTI,
		.expected_revision = 4,
	);

	/* ordering: [fd2, fd3, fd1, fd4] */

Annotation

Implementation Notes