Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Beginner's Guide to eBPF

Liz Rice
October 28, 2020

Beginner's Guide to eBPF

As seen at eBPF summit

See also github.com/lizrice/ebpf-beginners

Liz Rice

October 28, 2020
Tweet

More Decks by Liz Rice

Other Decks in Programming

Transcript

  1. A Beginner’s Guide to eBPF Programming Liz Rice @lizrice VP

    Open Source Engineering, Aqua Security October 28, 2020
  2. @lizrice man bpf eBPF programs can be written in a

    restricted C that is compiled (using the clang compiler) into eBPF bytecode. Various features are omitted from this restricted C, such as loops, global variables, variadic functions, floating-point numbers, and passing structures as function arguments.
  3. @lizrice man bpf eBPF programs can be written in a

    restricted C that is compiled (using the clang compiler) into eBPF bytecode. Various features are omitted from this restricted C, such as loops, global variables, variadic functions, floating-point numbers, and passing structures as function arguments. [eBPF Helper functions] are used by eBPF programs to interact with the system, or with the context in which they work. For instance, they can be used to print debugging messages... bpf_trace_printk() bpf_get_current_uid_gid() ...
  4. @lizrice man bpf Maps are a generic data structure for

    storage of different types of data. They allow sharing of data between eBPF kernel programs, and also between kernel and user-space applications.
  5. @lizrice man bpf Maps are a generic data structure for

    storage of different types of data. They allow sharing of data between eBPF kernel programs, and also between kernel and user-space applications. eBPF programs can be attached to different events.
  6. @lizrice Attach custom code to an event bpf(BPF_PROG_LOAD, …) =

    x perf_event_open(…) = y ioctl(y, PERF_EVENT_IOC_SET_BPF, x)
  7. @lizrice #!/usr/bin/python from bcc import BPF prog = """ int

    helloworld(void *ctx) { bpf_trace_printk("Hello world\\n"); return 0; } """ b = BPF(text=prog) clone = b.get_syscall_fnname("clone") b.attach_kprobe(event=clone, fn_name="helloworld") b.trace_print() github.com/lizrice/ebpf-beginners
  8. @lizrice #!/usr/bin/python from bcc import BPF from time import sleep

    prog = """ BPF_HASH(clones); int hello_world(void *ctx) { u64 uid; u64 counter = 0; u64 *p; uid = bpf_get_current_uid_gid() & 0xFFFFFFFF; p = clones.lookup(&uid); if (p != 0) { counter = *p; } counter++; clones.update(&uid, &counter); return 0; } """ b = BPF(text=prog) clone = b.get_syscall_fnname("clone") b.attach_kprobe(event=clone, fn_name="helloworld") while True: sleep(2) s = "" if len(b["clones"].items()): for k,v in b["clones"].items(): s += "ID {}: {}\t".format(k.value, v.value) print(s) else: print("No entries yet") github.com/lizrice/ebpf-beginners
  9. @lizrice ELF object file ◦ eBPF opcodes ◦ eBPF maps

    kernel verifier BPF vm maps user space bpf() system calls BPF_PROG_LOAD BPF_MAP_CREATE
  10. @lizrice ELF object file ◦ eBPF opcodes ◦ eBPF maps

    kernel verifier BPF vm maps user space bpf() system calls BPF_PROG_LOAD BPF_MAP_CREATE Attach BPF program to event
  11. @lizrice ELF object file ◦ eBPF opcodes ◦ eBPF maps

    kernel verifier BPF vm maps user space bpf() system calls BPF_PROG_LOAD BPF_MAP_CREATE Attach BPF program to event Read / write maps BPF_MAP_GET_NEXT_KEY BPF_MAP_LOOKUP_ELEM BPF_MAP_UPDATE_ELEM BPF_MAP_DELETE_ELEM