Commit | Line | Data |
---|---|---|
25763b3c | 1 | // SPDX-License-Identifier: GPL-2.0-only |
9e6e60ec | 2 | /* Copyright (c) 2016 Sargun Dhillon <sargun@sargun.me> |
9e6e60ec SD |
3 | */ |
4 | ||
5 | #define _GNU_SOURCE | |
6 | #include <stdio.h> | |
9e6e60ec | 7 | #include <unistd.h> |
2bf3e2ef | 8 | #include <bpf/bpf.h> |
3677d0a1 | 9 | #include <bpf/libbpf.h> |
1a922fee | 10 | #include "cgroup_helpers.h" |
9e6e60ec | 11 | |
1a922fee | 12 | #define CGROUP_PATH "/my-cgroup" |
9e6e60ec SD |
13 | |
14 | int main(int argc, char **argv) | |
15 | { | |
9e6e60ec | 16 | pid_t remote_pid, local_pid = getpid(); |
68be98e0 | 17 | int cg2 = -1, idx = 0, rc = 1; |
3677d0a1 DL |
18 | struct bpf_link *link = NULL; |
19 | struct bpf_program *prog; | |
3677d0a1 | 20 | struct bpf_object *obj; |
1a922fee | 21 | char filename[256]; |
3677d0a1 | 22 | int map_fd[2]; |
9e6e60ec | 23 | |
d4fffba4 | 24 | snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]); |
3677d0a1 DL |
25 | obj = bpf_object__open_file(filename, NULL); |
26 | if (libbpf_get_error(obj)) { | |
27 | fprintf(stderr, "ERROR: opening BPF object file failed\n"); | |
28 | return 0; | |
29 | } | |
30 | ||
31 | prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); | |
32 | if (!prog) { | |
33 | printf("finding a prog in obj file failed\n"); | |
34 | goto cleanup; | |
35 | } | |
36 | ||
37 | /* load BPF program */ | |
38 | if (bpf_object__load(obj)) { | |
39 | fprintf(stderr, "ERROR: loading BPF object file failed\n"); | |
40 | goto cleanup; | |
41 | } | |
42 | ||
43 | map_fd[0] = bpf_object__find_map_fd_by_name(obj, "cgroup_map"); | |
44 | map_fd[1] = bpf_object__find_map_fd_by_name(obj, "perf_map"); | |
45 | if (map_fd[0] < 0 || map_fd[1] < 0) { | |
46 | fprintf(stderr, "ERROR: finding a map in obj file failed\n"); | |
47 | goto cleanup; | |
48 | } | |
49 | ||
50 | link = bpf_program__attach(prog); | |
51 | if (libbpf_get_error(link)) { | |
52 | fprintf(stderr, "ERROR: bpf_program__attach failed\n"); | |
53 | link = NULL; | |
54 | goto cleanup; | |
9e6e60ec SD |
55 | } |
56 | ||
1a922fee SD |
57 | if (setup_cgroup_environment()) |
58 | goto err; | |
9e6e60ec | 59 | |
1a922fee | 60 | cg2 = create_and_get_cgroup(CGROUP_PATH); |
9e6e60ec | 61 | |
a8911d6d | 62 | if (cg2 < 0) |
1a922fee | 63 | goto err; |
9e6e60ec | 64 | |
d40fc181 | 65 | if (bpf_map_update_elem(map_fd[0], &idx, &cg2, BPF_ANY)) { |
9e6e60ec | 66 | log_err("Adding target cgroup to map"); |
1a922fee | 67 | goto err; |
9e6e60ec SD |
68 | } |
69 | ||
1a922fee SD |
70 | if (join_cgroup(CGROUP_PATH)) |
71 | goto err; | |
72 | ||
9e6e60ec SD |
73 | /* |
74 | * The installed helper program catched the sync call, and should | |
75 | * write it to the map. | |
76 | */ | |
77 | ||
78 | sync(); | |
d40fc181 | 79 | bpf_map_lookup_elem(map_fd[1], &idx, &remote_pid); |
9e6e60ec SD |
80 | |
81 | if (local_pid != remote_pid) { | |
82 | fprintf(stderr, | |
83 | "BPF Helper didn't write correct PID to map, but: %d\n", | |
84 | remote_pid); | |
1a922fee | 85 | goto err; |
9e6e60ec SD |
86 | } |
87 | ||
88 | /* Verify the negative scenario; leave the cgroup */ | |
1a922fee SD |
89 | if (join_cgroup("/")) |
90 | goto err; | |
9e6e60ec SD |
91 | |
92 | remote_pid = 0; | |
d40fc181 | 93 | bpf_map_update_elem(map_fd[1], &idx, &remote_pid, BPF_ANY); |
9e6e60ec SD |
94 | |
95 | sync(); | |
d40fc181 | 96 | bpf_map_lookup_elem(map_fd[1], &idx, &remote_pid); |
9e6e60ec SD |
97 | |
98 | if (local_pid == remote_pid) { | |
99 | fprintf(stderr, "BPF cgroup negative test did not work\n"); | |
1a922fee | 100 | goto err; |
9e6e60ec SD |
101 | } |
102 | ||
3677d0a1 | 103 | rc = 0; |
9e6e60ec | 104 | |
3677d0a1 | 105 | err: |
68be98e0 DL |
106 | if (cg2 != -1) |
107 | close(cg2); | |
108 | ||
1a922fee | 109 | cleanup_cgroup_environment(); |
3677d0a1 DL |
110 | |
111 | cleanup: | |
112 | bpf_link__destroy(link); | |
113 | bpf_object__close(obj); | |
1a922fee | 114 | return rc; |
9e6e60ec | 115 | } |