Merge tag 'io_uring-5.13-2021-05-14' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / prog_tests / cgroup_attach_autodetach.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <test_progs.h>
4
5 #include "cgroup_helpers.h"
6
7 #define PING_CMD        "ping -q -c1 -w1 127.0.0.1 > /dev/null"
8
9 static char bpf_log_buf[BPF_LOG_BUF_SIZE];
10
11 static int prog_load(void)
12 {
13         struct bpf_insn prog[] = {
14                 BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = 1 */
15                 BPF_EXIT_INSN(),
16         };
17         size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
18
19         return bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
20                                prog, insns_cnt, "GPL", 0,
21                                bpf_log_buf, BPF_LOG_BUF_SIZE);
22 }
23
24 void test_cgroup_attach_autodetach(void)
25 {
26         __u32 duration = 0, prog_cnt = 4, attach_flags;
27         int allow_prog[2] = {-1};
28         __u32 prog_ids[2] = {0};
29         void *ptr = NULL;
30         int cg = 0, i;
31         int attempts;
32
33         for (i = 0; i < ARRAY_SIZE(allow_prog); i++) {
34                 allow_prog[i] = prog_load();
35                 if (CHECK(allow_prog[i] < 0, "prog_load",
36                           "verifier output:\n%s\n-------\n", bpf_log_buf))
37                         goto err;
38         }
39
40         if (CHECK_FAIL(setup_cgroup_environment()))
41                 goto err;
42
43         /* create a cgroup, attach two programs and remember their ids */
44         cg = create_and_get_cgroup("/cg_autodetach");
45         if (CHECK_FAIL(cg < 0))
46                 goto err;
47
48         if (CHECK_FAIL(join_cgroup("/cg_autodetach")))
49                 goto err;
50
51         for (i = 0; i < ARRAY_SIZE(allow_prog); i++)
52                 if (CHECK(bpf_prog_attach(allow_prog[i], cg,
53                                           BPF_CGROUP_INET_EGRESS,
54                                           BPF_F_ALLOW_MULTI),
55                           "prog_attach", "prog[%d], errno=%d\n", i, errno))
56                         goto err;
57
58         /* make sure that programs are attached and run some traffic */
59         if (CHECK(bpf_prog_query(cg, BPF_CGROUP_INET_EGRESS, 0, &attach_flags,
60                                  prog_ids, &prog_cnt),
61                   "prog_query", "errno=%d\n", errno))
62                 goto err;
63         if (CHECK_FAIL(system(PING_CMD)))
64                 goto err;
65
66         /* allocate some memory (4Mb) to pin the original cgroup */
67         ptr = malloc(4 * (1 << 20));
68         if (CHECK_FAIL(!ptr))
69                 goto err;
70
71         /* close programs and cgroup fd */
72         for (i = 0; i < ARRAY_SIZE(allow_prog); i++) {
73                 close(allow_prog[i]);
74                 allow_prog[i] = -1;
75         }
76
77         close(cg);
78         cg = 0;
79
80         /* leave the cgroup and remove it. don't detach programs */
81         cleanup_cgroup_environment();
82
83         /* wait for the asynchronous auto-detachment.
84          * wait for no more than 5 sec and give up.
85          */
86         for (i = 0; i < ARRAY_SIZE(prog_ids); i++) {
87                 for (attempts = 5; attempts >= 0; attempts--) {
88                         int fd = bpf_prog_get_fd_by_id(prog_ids[i]);
89
90                         if (fd < 0)
91                                 break;
92
93                         /* don't leave the fd open */
94                         close(fd);
95
96                         if (CHECK_FAIL(!attempts))
97                                 goto err;
98
99                         sleep(1);
100                 }
101         }
102
103 err:
104         for (i = 0; i < ARRAY_SIZE(allow_prog); i++)
105                 if (allow_prog[i] >= 0)
106                         close(allow_prog[i]);
107         if (cg)
108                 close(cg);
109         free(ptr);
110         cleanup_cgroup_environment();
111 }