ebpf-lab

Example code from Learning eBPF by Liz Rice, https://github.com/lizrice/learning-ebpf
git clone https://git.in0rdr.ch/ebpf-lab.git
Log | Files | Refs | Pull requests |Archive | README

hello-raw-tracepoint.py (2222B)


      1 #!/usr/bin/env python3
      2 from bcc import BPF
      3 import ctypes as ct
      4 
      5 # https://docs.kernel.org/trace/events.html
      6 # Tracepoints can be used without creating custom kernel modules
      7 # to register probe functions using the event tracing infrastructure.
      8 
      9 # eCHO Episode 74: eBPF Tail Calls
     10 # https://www.youtube.com/watch?v=3qLXw3E0YWg
     11 
     12 bpf_text = r"""
     13 #include <linux/sched.h>
     14 
     15 int noop() {
     16     return 0;
     17 }
     18 
     19 static int ignore_syscall() {
     20     return  0;
     21 }
     22 
     23 // eBPF tail calls allow for calling a series of functions w/o growing the stack
     24 // BPF_PROG_ARRAY is a map to index eBPF functions
     25 // https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#10-bpf_prog_array
     26 BPF_PROG_ARRAY(syscall, 300);
     27 
     28 // searchable list of syscalls
     29 // https://filippo.io/linux-syscall-table
     30 
     31 // https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#7-raw-tracepoints
     32 // https://github.com/torvalds/linux/blob/master/include/trace/events/syscalls.h
     33 RAW_TRACEPOINT_PROBE(sys_enter) {
     34     // printf() to the common trace_pipe (/sys/kernel/debug/tracing/trace_pipe)
     35     // https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#1-bpf_trace_printk
     36     bpf_trace_printk("syscall");
     37 
     38     // the syscall opcode id is the second argument
     39     // ctx is hidden by the macro RAW_TRACEPOINT_PROBE
     40     // https://github.com/torvalds/linux/blob/master/include/trace/events/syscalls.h
     41     int opcode = ctx->args[1];
     42     switch (opcode) {
     43         case 64:
     44             // eBPF stack only 512 bytes, don't repeat that too often
     45             ignore_syscall();
     46             break;
     47     }
     48 
     49     // perform a "tail call" to another function for each specified opcode
     50     // the mapping of tail call to opcode is done in userspace
     51     // func invocation on struct is not proper C, will be translated by BCC
     52     syscall.call(ctx, opcode);
     53 
     54     // this line will never be evaluated when the tail call succeeds
     55     bpf_trace_printk("Another syscall: %d", opcode);
     56 
     57     return 0;
     58 }
     59 """
     60 
     61 b = BPF(text=bpf_text)
     62 
     63 # fetch the program map
     64 prog_array = b.get_table("syscall")
     65 
     66 # map the 64 syscall to the ignore function in the program map
     67 noop_fn = b.load_func("noop", BPF.RAW_TRACEPOINT)
     68 prog_array[ct.c_int(64)] = ct.c_int(noop_fn.fd)
     69 
     70 b.trace_print()