1 /* eBPF example program:
3 * - Creates arraymap in kernel with 4 bytes keys and 8 byte values
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
13 * - Attaches the new program to a cgroup using BPF_PROG_ATTACH
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.
26 #include <linux/bpf.h>
29 #include "cgroup_helpers.h"
32 #define BAR "/foo/bar/"
33 #define PING_CMD "ping -c1 -w1 127.0.0.1"
35 char bpf_log_buf
[BPF_LOG_BUF_SIZE
];
37 static int prog_load(int verdict
)
40 struct bpf_insn prog
[] = {
41 BPF_MOV64_IMM(BPF_REG_0
, verdict
), /* r0 = verdict */
44 size_t insns_cnt
= sizeof(prog
) / sizeof(struct bpf_insn
);
46 ret
= bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB
,
47 prog
, insns_cnt
, "GPL", 0,
48 bpf_log_buf
, BPF_LOG_BUF_SIZE
);
51 log_err("Loading program");
52 printf("Output from verifier:\n%s\n-------\n", bpf_log_buf
);
59 int main(int argc
, char **argv
)
61 int drop_prog
, allow_prog
, foo
= 0, bar
= 0, rc
= 0;
63 allow_prog
= prog_load(1);
67 drop_prog
= prog_load(0);
71 if (setup_cgroup_environment())
74 /* Create cgroup /foo, get fd, and join it */
75 foo
= create_and_get_cgroup(FOO
);
82 if (bpf_prog_attach(drop_prog
, foo
, BPF_CGROUP_INET_EGRESS
, 1)) {
83 log_err("Attaching prog to /foo");
87 printf("Attached DROP prog. This ping in cgroup /foo should fail...\n");
88 assert(system(PING_CMD
) != 0);
90 /* Create cgroup /foo/bar, get fd, and join it */
91 bar
= create_and_get_cgroup(BAR
);
98 printf("Attached DROP prog. This ping in cgroup /foo/bar should fail...\n");
99 assert(system(PING_CMD
) != 0);
101 if (bpf_prog_attach(allow_prog
, bar
, BPF_CGROUP_INET_EGRESS
, 1)) {
102 log_err("Attaching prog to /foo/bar");
106 printf("Attached PASS prog. This ping in cgroup /foo/bar should pass...\n");
107 assert(system(PING_CMD
) == 0);
109 if (bpf_prog_detach(bar
, BPF_CGROUP_INET_EGRESS
)) {
110 log_err("Detaching program from /foo/bar");
114 printf("Detached PASS from /foo/bar while DROP is attached to /foo.\n"
115 "This ping in cgroup /foo/bar should fail...\n");
116 assert(system(PING_CMD
) != 0);
118 if (bpf_prog_attach(allow_prog
, bar
, BPF_CGROUP_INET_EGRESS
, 1)) {
119 log_err("Attaching prog to /foo/bar");
123 if (bpf_prog_detach(foo
, BPF_CGROUP_INET_EGRESS
)) {
124 log_err("Detaching program from /foo");
128 printf("Attached PASS from /foo/bar and detached DROP from /foo.\n"
129 "This ping in cgroup /foo/bar should pass...\n");
130 assert(system(PING_CMD
) == 0);
132 if (bpf_prog_attach(allow_prog
, bar
, BPF_CGROUP_INET_EGRESS
, 1)) {
133 log_err("Attaching prog to /foo/bar");
137 if (!bpf_prog_attach(allow_prog
, bar
, BPF_CGROUP_INET_EGRESS
, 0)) {
139 log_err("Unexpected success attaching prog to /foo/bar");
143 if (bpf_prog_detach(bar
, BPF_CGROUP_INET_EGRESS
)) {
144 log_err("Detaching program from /foo/bar");
148 if (!bpf_prog_detach(foo
, BPF_CGROUP_INET_EGRESS
)) {
150 log_err("Unexpected success in double detach from /foo");
154 if (bpf_prog_attach(allow_prog
, foo
, BPF_CGROUP_INET_EGRESS
, 0)) {
155 log_err("Attaching non-overridable prog to /foo");
159 if (!bpf_prog_attach(allow_prog
, bar
, BPF_CGROUP_INET_EGRESS
, 0)) {
161 log_err("Unexpected success attaching non-overridable prog to /foo/bar");
165 if (!bpf_prog_attach(allow_prog
, bar
, BPF_CGROUP_INET_EGRESS
, 1)) {
167 log_err("Unexpected success attaching overridable prog to /foo/bar");
171 if (!bpf_prog_attach(allow_prog
, foo
, BPF_CGROUP_INET_EGRESS
, 1)) {
173 log_err("Unexpected success attaching overridable prog to /foo");
177 if (bpf_prog_attach(drop_prog
, foo
, BPF_CGROUP_INET_EGRESS
, 0)) {
178 log_err("Attaching different non-overridable prog to /foo");
190 cleanup_cgroup_environment();