]> git.karo-electronics.de Git - karo-tx-linux.git/blob - samples/bpf/test_cgrp2_attach2.c
samples/bpf: Switch over to libbpf
[karo-tx-linux.git] / samples / bpf / test_cgrp2_attach2.c
1 /* eBPF example program:
2  *
3  * - Creates arraymap in kernel with 4 bytes keys and 8 byte values
4  *
5  * - Loads eBPF program
6  *
7  *   The eBPF program accesses the map passed in to store two pieces of
8  *   information. The number of invocations of the program, which maps
9  *   to the number of packets received, is stored to key 0. Key 1 is
10  *   incremented on each iteration by the number of bytes stored in
11  *   the skb.
12  *
13  * - Attaches the new program to a cgroup using BPF_PROG_ATTACH
14  *
15  * - Every second, reads map[0] and map[1] to see how many bytes and
16  *   packets were seen on any socket of tasks in the given cgroup.
17  */
18
19 #define _GNU_SOURCE
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <unistd.h>
25
26 #include <linux/bpf.h>
27
28 #include "libbpf.h"
29 #include "cgroup_helpers.h"
30
31 #define FOO             "/foo"
32 #define BAR             "/foo/bar/"
33 #define PING_CMD        "ping -c1 -w1 127.0.0.1"
34
35 char bpf_log_buf[BPF_LOG_BUF_SIZE];
36
37 static int prog_load(int verdict)
38 {
39         int ret;
40         struct bpf_insn prog[] = {
41                 BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */
42                 BPF_EXIT_INSN(),
43         };
44         size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
45
46         ret = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
47                                prog, insns_cnt, "GPL", 0,
48                                bpf_log_buf, BPF_LOG_BUF_SIZE);
49
50         if (ret < 0) {
51                 log_err("Loading program");
52                 printf("Output from verifier:\n%s\n-------\n", bpf_log_buf);
53                 return 0;
54         }
55         return ret;
56 }
57
58
59 int main(int argc, char **argv)
60 {
61         int drop_prog, allow_prog, foo = 0, bar = 0, rc = 0;
62
63         allow_prog = prog_load(1);
64         if (!allow_prog)
65                 goto err;
66
67         drop_prog = prog_load(0);
68         if (!drop_prog)
69                 goto err;
70
71         if (setup_cgroup_environment())
72                 goto err;
73
74         /* Create cgroup /foo, get fd, and join it */
75         foo = create_and_get_cgroup(FOO);
76         if (!foo)
77                 goto err;
78
79         if (join_cgroup(FOO))
80                 goto err;
81
82         if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS)) {
83                 log_err("Attaching prog to /foo");
84                 goto err;
85         }
86
87         assert(system(PING_CMD) != 0);
88
89         /* Create cgroup /foo/bar, get fd, and join it */
90         bar = create_and_get_cgroup(BAR);
91         if (!bar)
92                 goto err;
93
94         if (join_cgroup(BAR))
95                 goto err;
96
97         assert(system(PING_CMD) != 0);
98
99         if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS)) {
100                 log_err("Attaching prog to /foo/bar");
101                 goto err;
102         }
103
104         assert(system(PING_CMD) == 0);
105
106
107         if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) {
108                 log_err("Detaching program from /foo/bar");
109                 goto err;
110         }
111
112         assert(system(PING_CMD) != 0);
113
114         if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS)) {
115                 log_err("Attaching prog to /foo/bar");
116                 goto err;
117         }
118
119         if (bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) {
120                 log_err("Detaching program from /foo");
121                 goto err;
122         }
123
124         assert(system(PING_CMD) == 0);
125
126         goto out;
127
128 err:
129         rc = 1;
130
131 out:
132         close(foo);
133         close(bar);
134         cleanup_cgroup_environment();
135         return rc;
136 }