File Index
Files and directories
Sign in
FILE

cgroup_preorder.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/cgroup_preorder.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
  3#include <test_progs.h>
  4#include "cgroup_helpers.h"
  5#include "cgroup_preorder.skel.h"
  6
  7static int run_getsockopt_test(int cg_parent, int cg_child, int sock_fd, bool all_preorder)
  8{
  9	LIBBPF_OPTS(bpf_prog_attach_opts, opts);
 10	enum bpf_attach_type prog_c_atype, prog_c2_atype, prog_p_atype, prog_p2_atype;
 11	int prog_c_fd, prog_c2_fd, prog_p_fd, prog_p2_fd;
 12	struct cgroup_preorder *skel = NULL;
 13	struct bpf_program *prog;
 14	__u8 *result, buf;
 15	socklen_t optlen;
 16	int err = 0;
 17
 18	skel = cgroup_preorder__open_and_load();
 19	if (!ASSERT_OK_PTR(skel, "cgroup_preorder__open_and_load"))
 20		return 0;
 21
 22	buf = 0x00;
 23	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
 24	if (!ASSERT_OK(err, "setsockopt"))
 25		goto close_skel;
 26
 27	opts.flags = BPF_F_ALLOW_MULTI;
 28	if (all_preorder)
 29		opts.flags |= BPF_F_PREORDER;
 30	prog = skel->progs.child;
 31	prog_c_fd = bpf_program__fd(prog);
 32	prog_c_atype = bpf_program__expected_attach_type(prog);
 33	err = bpf_prog_attach_opts(prog_c_fd, cg_child, prog_c_atype, &opts);
 34	if (!ASSERT_OK(err, "bpf_prog_attach_opts-child"))
 35		goto close_skel;
 36
 37	opts.flags = BPF_F_ALLOW_MULTI | BPF_F_PREORDER;
 38	prog = skel->progs.child_2;
 39	prog_c2_fd = bpf_program__fd(prog);
 40	prog_c2_atype = bpf_program__expected_attach_type(prog);
 41	err = bpf_prog_attach_opts(prog_c2_fd, cg_child, prog_c2_atype, &opts);
 42	if (!ASSERT_OK(err, "bpf_prog_attach_opts-child_2"))
 43		goto detach_child;
 44
 45	optlen = 1;
 46	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
 47	if (!ASSERT_OK(err, "getsockopt"))
 48		goto detach_child_2;
 49
 50	result = skel->bss->result;
 51	if (all_preorder)
 52		ASSERT_TRUE(result[0] == 1 && result[1] == 2, "child only");
 53	else
 54		ASSERT_TRUE(result[0] == 2 && result[1] == 1, "child only");
 55
 56	skel->bss->idx = 0;
 57	memset(result, 0, 4);
 58
 59	opts.flags = BPF_F_ALLOW_MULTI;
 60	if (all_preorder)
 61		opts.flags |= BPF_F_PREORDER;
 62	prog = skel->progs.parent;
 63	prog_p_fd = bpf_program__fd(prog);
 64	prog_p_atype = bpf_program__expected_attach_type(prog);
 65	err = bpf_prog_attach_opts(prog_p_fd, cg_parent, prog_p_atype, &opts);
 66	if (!ASSERT_OK(err, "bpf_prog_attach_opts-parent"))
 67		goto detach_child_2;
 68
 69	opts.flags = BPF_F_ALLOW_MULTI | BPF_F_PREORDER;
 70	prog = skel->progs.parent_2;
 71	prog_p2_fd = bpf_program__fd(prog);
 72	prog_p2_atype = bpf_program__expected_attach_type(prog);
 73	err = bpf_prog_attach_opts(prog_p2_fd, cg_parent, prog_p2_atype, &opts);
 74	if (!ASSERT_OK(err, "bpf_prog_attach_opts-parent_2"))
 75		goto detach_parent;
 76
 77	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
 78	if (!ASSERT_OK(err, "getsockopt"))
 79		goto detach_parent_2;
 80
 81	if (all_preorder)
 82		ASSERT_TRUE(result[0] == 3 && result[1] == 4 && result[2] == 1 && result[3] == 2,
 83			    "parent and child");
 84	else
 85		ASSERT_TRUE(result[0] == 4 && result[1] == 2 && result[2] == 1 && result[3] == 3,
 86			    "parent and child");
 87
 88detach_parent_2:
 89	ASSERT_OK(bpf_prog_detach2(prog_p2_fd, cg_parent, prog_p2_atype),
 90		  "bpf_prog_detach2-parent_2");
 91detach_parent:
 92	ASSERT_OK(bpf_prog_detach2(prog_p_fd, cg_parent, prog_p_atype),
 93		  "bpf_prog_detach2-parent");
 94detach_child_2:
 95	ASSERT_OK(bpf_prog_detach2(prog_c2_fd, cg_child, prog_c2_atype),
 96		  "bpf_prog_detach2-child_2");
 97detach_child:
 98	ASSERT_OK(bpf_prog_detach2(prog_c_fd, cg_child, prog_c_atype),
 99		  "bpf_prog_detach2-child");
100close_skel:
101	cgroup_preorder__destroy(skel);
102	return err;
103}
104
105void test_cgroup_preorder(void)
106{
107	int cg_parent = -1, cg_child = -1, sock_fd = -1;
108
109	cg_parent = test__join_cgroup("/parent");
110	if (!ASSERT_GE(cg_parent, 0, "join_cgroup /parent"))
111		goto out;
112
113	cg_child = test__join_cgroup("/parent/child");
114	if (!ASSERT_GE(cg_child, 0, "join_cgroup /parent/child"))
115		goto out;
116
117	sock_fd = socket(AF_INET, SOCK_STREAM, 0);
118	if (!ASSERT_GE(sock_fd, 0, "socket"))
119		goto out;
120
121	ASSERT_OK(run_getsockopt_test(cg_parent, cg_child, sock_fd, false), "getsockopt_test_1");
122	ASSERT_OK(run_getsockopt_test(cg_parent, cg_child, sock_fd, true), "getsockopt_test_2");
123
124out:
125	close(sock_fd);
126	close(cg_child);
127	close(cg_parent);
128}
~/ Read-only file preview.