samples, bpf: Add automated test for cgroup filter attachments
This patch adds the sample program test_cgrp2_attach2. This program is similar to test_cgrp2_attach, but it performs automated testing of the cgroupv2 BPF attached filters. It runs the following checks: * Simple filter attachment * Application of filters to child cgroups * Overriding filters on child cgroups * Checking that this still works when the parent filter is removed The filters that are used here are simply allow all / deny all filters, so it isn't checking the actual functionality of the filters, but rather the behaviour around detachment / attachment. If net_cls is enabled, this test will fail. Signed-off-by: Sargun Dhillon <sargun@sargun.me> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1a922fee66
commit
9b474ecee5
2 changed files with 134 additions and 0 deletions
|
@ -23,6 +23,7 @@ hostprogs-y += map_perf_test
|
|||
hostprogs-y += test_overhead
|
||||
hostprogs-y += test_cgrp2_array_pin
|
||||
hostprogs-y += test_cgrp2_attach
|
||||
hostprogs-y += test_cgrp2_attach2
|
||||
hostprogs-y += test_cgrp2_sock
|
||||
hostprogs-y += test_cgrp2_sock2
|
||||
hostprogs-y += xdp1
|
||||
|
@ -54,6 +55,7 @@ map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o
|
|||
test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o
|
||||
test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o
|
||||
test_cgrp2_attach-objs := libbpf.o test_cgrp2_attach.o
|
||||
test_cgrp2_attach2-objs := libbpf.o test_cgrp2_attach2.o cgroup_helpers.o
|
||||
test_cgrp2_sock-objs := libbpf.o test_cgrp2_sock.o
|
||||
test_cgrp2_sock2-objs := bpf_load.o libbpf.o test_cgrp2_sock2.o
|
||||
xdp1-objs := bpf_load.o libbpf.o xdp1_user.o
|
||||
|
|
132
samples/bpf/test_cgrp2_attach2.c
Normal file
132
samples/bpf/test_cgrp2_attach2.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/* eBPF example program:
|
||||
*
|
||||
* - Creates arraymap in kernel with 4 bytes keys and 8 byte values
|
||||
*
|
||||
* - Loads eBPF program
|
||||
*
|
||||
* The eBPF program accesses the map passed in to store two pieces of
|
||||
* information. The number of invocations of the program, which maps
|
||||
* to the number of packets received, is stored to key 0. Key 1 is
|
||||
* incremented on each iteration by the number of bytes stored in
|
||||
* the skb.
|
||||
*
|
||||
* - Attaches the new program to a cgroup using BPF_PROG_ATTACH
|
||||
*
|
||||
* - Every second, reads map[0] and map[1] to see how many bytes and
|
||||
* packets were seen on any socket of tasks in the given cgroup.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <linux/bpf.h>
|
||||
|
||||
#include "libbpf.h"
|
||||
#include "cgroup_helpers.h"
|
||||
|
||||
#define FOO "/foo"
|
||||
#define BAR "/foo/bar/"
|
||||
#define PING_CMD "ping -c1 -w1 127.0.0.1"
|
||||
|
||||
static int prog_load(int verdict)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_insn prog[] = {
|
||||
BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */
|
||||
BPF_EXIT_INSN(),
|
||||
};
|
||||
|
||||
ret = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SKB,
|
||||
prog, sizeof(prog), "GPL", 0);
|
||||
|
||||
if (ret < 0) {
|
||||
log_err("Loading program");
|
||||
printf("Output from verifier:\n%s\n-------\n", bpf_log_buf);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int drop_prog, allow_prog, foo = 0, bar = 0, rc = 0;
|
||||
|
||||
allow_prog = prog_load(1);
|
||||
if (!allow_prog)
|
||||
goto err;
|
||||
|
||||
drop_prog = prog_load(0);
|
||||
if (!drop_prog)
|
||||
goto err;
|
||||
|
||||
if (setup_cgroup_environment())
|
||||
goto err;
|
||||
|
||||
/* Create cgroup /foo, get fd, and join it */
|
||||
foo = create_and_get_cgroup(FOO);
|
||||
if (!foo)
|
||||
goto err;
|
||||
|
||||
if (join_cgroup(FOO))
|
||||
goto err;
|
||||
|
||||
if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS)) {
|
||||
log_err("Attaching prog to /foo");
|
||||
goto err;
|
||||
}
|
||||
|
||||
assert(system(PING_CMD) != 0);
|
||||
|
||||
/* Create cgroup /foo/bar, get fd, and join it */
|
||||
bar = create_and_get_cgroup(BAR);
|
||||
if (!bar)
|
||||
goto err;
|
||||
|
||||
if (join_cgroup(BAR))
|
||||
goto err;
|
||||
|
||||
assert(system(PING_CMD) != 0);
|
||||
|
||||
if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS)) {
|
||||
log_err("Attaching prog to /foo/bar");
|
||||
goto err;
|
||||
}
|
||||
|
||||
assert(system(PING_CMD) == 0);
|
||||
|
||||
|
||||
if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) {
|
||||
log_err("Detaching program from /foo/bar");
|
||||
goto err;
|
||||
}
|
||||
|
||||
assert(system(PING_CMD) != 0);
|
||||
|
||||
if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS)) {
|
||||
log_err("Attaching prog to /foo/bar");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) {
|
||||
log_err("Detaching program from /foo");
|
||||
goto err;
|
||||
}
|
||||
|
||||
assert(system(PING_CMD) == 0);
|
||||
|
||||
goto out;
|
||||
|
||||
err:
|
||||
rc = 1;
|
||||
|
||||
out:
|
||||
close(foo);
|
||||
close(bar);
|
||||
cleanup_cgroup_environment();
|
||||
return rc;
|
||||
}
|
Loading…
Reference in a new issue