Skip to content

Commit 695dfde

Browse files
committed
Let's get the BPF party on
1 parent c5e4bd7 commit 695dfde

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

bpf/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# BPF samples
2+
3+
## Usage
4+
5+
使用对应文件
6+
7+
ln -s $PWD/demo_kern.c /usr/src/linux/samples/bpf
8+
ln -s $PWD/demo_user.c /usr/src/linux/samples/bpf
9+
10+
修改makefile(/usr/src/linux/samples/bpf/Makefile)
11+
12+
添加目标(demo)
13+
14+
tprogs-y += demo
15+
16+
demo依赖demo_user
17+
18+
demo-objs := demo_user.o $(TRACE_HELPERS)
19+
20+
编译对应的bpf模块
21+
22+
always-y += demo_kern.o
23+
24+
需要县编译好内核并安装头文件
25+
26+
cd /usr/src/linux
27+
make defconfig && make && make headers_install
28+
29+
编译bpf模块
30+
31+
make M=samples/bpf
32+
33+
或者在bpf目录编译
34+
35+
cd /usr/src/linux/samples/bpf && make
36+
37+
用file查看下编译输出文件(demo_user.o和demo_kern.o)
38+
39+
demo_user.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
40+
demo_kern.o: ELF 64-bit LSB relocatable, eBPF, version 1 (SYSV), with debug_info, not stripped
41+
42+
- demo_kern.c中的文件是被编译成eBPF的二进制文件,是要被eBPF虚拟机执行的代码
43+
- demo_user.c是将eBPF二进制文件加载到内核的代码

bpf/demo_kern.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <linux/ptrace.h>
2+
#include <linux/version.h>
3+
#include <uapi/linux/bpf.h>
4+
#include <uapi/linux/seccomp.h>
5+
#include <uapi/linux/unistd.h>
6+
#include <bpf/bpf_helpers.h>
7+
#include <bpf/bpf_tracing.h>
8+
9+
struct {
10+
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
11+
__uint(key_size, sizeof(u32));
12+
__uint(value_size, sizeof(u32));
13+
__uint(max_entries, 1024);
14+
} progs SEC(".maps");
15+
16+
/*
17+
* /sys/kernel/debug/tracing/events/syscalls/sys_enter_execve
18+
* 通过监控内核中系统调用execve
19+
* 当系统中调用了这个系统调用的话就会调用mybpfprog函数
20+
*
21+
* 编译好程序后执行./demo
22+
*
23+
* 然后打开一个新终端,输入一些命令即可看到结果
24+
*/
25+
SEC("tracepoint/syscalls/sys_enter_execve")
26+
int mybpfprog(struct pt_regs *ctx)
27+
{
28+
char msg[] = "Hello, BPF World!";
29+
30+
bpf_trace_printk(msg, sizeof(msg));
31+
32+
return 0;
33+
}
34+
35+
char _license[] SEC("license") = "GPL";
36+
u32 _version SEC("version") = LINUX_VERSION_CODE;

bpf/demo_user.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <linux/filter.h>
5+
#include <linux/seccomp.h>
6+
#include <sys/prctl.h>
7+
#include <bpf/bpf.h>
8+
#include <bpf/libbpf.h>
9+
#include <sys/resource.h>
10+
#include "trace_helpers.h"
11+
12+
int main(int argc, char *argv[])
13+
{
14+
struct bpf_link *link = NULL;
15+
struct bpf_program *prog;
16+
struct bpf_object *obj;
17+
int key, fd, progs_fd;
18+
const char *section;
19+
char filename[256];
20+
21+
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
22+
obj = bpf_object__open_file(filename, NULL);
23+
if (libbpf_get_error(obj)) {
24+
fprintf(stderr, "ERROR: opening BPF object file failed\n");
25+
return 0;
26+
}
27+
28+
prog = bpf_object__find_program_by_name(obj, "mybpfprog");
29+
if (!prog) {
30+
printf("finding a prog in obj file failed\n");
31+
goto cleanup;
32+
}
33+
34+
/* load BPF program */
35+
if (bpf_object__load(obj)) {
36+
fprintf(stderr, "ERROR: loading BPF object file failed\n");
37+
goto cleanup;
38+
}
39+
40+
link = bpf_program__attach(prog);
41+
if (libbpf_get_error(link)) {
42+
fprintf(stderr, "ERROR: bpf_program__attach failed\n");
43+
link = NULL;
44+
goto cleanup;
45+
}
46+
47+
progs_fd = bpf_object__find_map_fd_by_name(obj, "progs");
48+
if (progs_fd < 0) {
49+
fprintf(stderr, "ERROR: finding a map in obj file failed\n");
50+
goto cleanup;
51+
}
52+
53+
bpf_object__for_each_program(prog, obj) {
54+
section = bpf_program__section_name(prog);
55+
/* register only syscalls to PROG_ARRAY */
56+
if (sscanf(section, "kprobe/%d", &key) != 1)
57+
continue;
58+
59+
fd = bpf_program__fd(prog);
60+
bpf_map_update_elem(progs_fd, &key, &fd, BPF_ANY);
61+
}
62+
63+
read_trace_pipe();
64+
65+
cleanup:
66+
bpf_link__destroy(link);
67+
bpf_object__close(obj);
68+
return 0;
69+
}

0 commit comments

Comments
 (0)