简体   繁体   中英

How can I attached a BPF program to a kernel function via a kprobe?

The Cilium BPF and XDP Reference Guide describes how you can load a BPF program to a netdevice via the ip and tc commands. How would I attach a BPF program to a kernel function/userspace function in the same way?

TL;DR You can use the traditional kprobe API to trace a function, then perf_event_open + ioctl to attach a BPF program.

This is implemented in the load_and_attach function of file load_bpf.c in the kernel, and in the bpf_attach_kprobe and bpf_attach_tracing_event function of file libbpf.c in bcc.


You can see this in action when tracing the hello_world.py from bcc :

$ strace -s 100 python examples/hello_world.py
[...]
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_KPROBE, insn_cnt=15, insns=0x7f35716217d0, license="GPL", log_level=0, log_size=0, log_buf=0, kern_version=265728}, 72) = 3
openat(AT_FDCWD, "/sys/bus/event_source/devices/kprobe/type", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/sys/bus/event_source/devices/kprobe/format/retprobe", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/sys/kernel/debug/tracing/kprobe_events", O_WRONLY|O_APPEND) = 4
getpid()                                = 8121
write(4, "p:kprobes/p_sys_clone_bcc_8121 sys_clone", 40) = 40
close(4)                                = 0
openat(AT_FDCWD, "/sys/kernel/debug/tracing/events/kprobes/p_sys_clone_bcc_8121/id", O_RDONLY) = 4
read(4, "1846\n", 4096)                 = 5
close(4)                                = 0
perf_event_open({type=PERF_TYPE_TRACEPOINT, size=0 /* PERF_ATTR_SIZE_??? */, config=1846, ...}, -1, 0, -1, PERF_FLAG_FD_CLOEXEC) = 4
mmap(NULL, 36864, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 0) = 0x7f356c58b000
ioctl(4, PERF_EVENT_IOC_SET_BPF, 0x3)   = 0
ioctl(4, PERF_EVENT_IOC_ENABLE, 0)      = 0
openat(AT_FDCWD, "/sys/kernel/debug/tracing/trace_pipe", O_RDONLY) = 5
fstat(5, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
fstat(5, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(5, 
  1. The first syscall ( bpf ) loads the BPF program in the kernel.
  2. Then bcc follows the kprobe API to trace sys_clone by writing p:kprobes/p_sys_clone_bcc_8121 sys_clone in p:kprobes/p_sys_clone_bcc_8121 sys_clone .
  3. bcc retrieves, in p:kprobes/p_sys_clone_bcc_8121 sys_clone , an ID to use in perf_event_open .
  4. bcc calls perf_event_open with type PERF_TYPE_TRACEPOINT
  5. and attaches the loaded BPF program (referenced by fd 0x3 ) to that perf_event, with an PERF_EVENT_IOC_SET_BPF ioctl.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM