cilium / ebpf

ebpf-go is a pure-Go library to read, modify and load eBPF programs and attach them to various hooks in the Linux kernel.
https://ebpf-go.dev
MIT License
6.33k stars 698 forks source link

bpf2go: ship common C headers #449

Open lmb opened 3 years ago

lmb commented 3 years ago

Once a user has discovered bpf2go they usually need to figure out where to get headers from. We can remove this pain point by shipping common headers via a go:embed directive. When invoking the binary we could extract those headers to a temporary directory and then add the directory as an include path to the clang invocation.

We can categorize headers as such:

  1. Linux BPF UAPI: linux/bpf.h, linux/bpf_common.h, etc. Available as GPL-2.0 WITH Linux-syscall-note.
  2. libbpf API: bpf/bpf_helpers.h, bpf/bpf_endian.h, etc. Available as LGPL-2.1 OR BSD-2-Clause.
  3. Linux "library" headers: definitions of struct iphdr etc. Various licenses, some GPL-only.
  4. libc headers: stdint.h, stdbool.h, etc. License depends on which libc you use, I've used musl in the past which is MIT. Suffers from the problem that BPF isn't a supported libc target so hacks are necessary.
  5. vmlinux.h: "the big one". Probably only compatible with GPLv2.

I think we can easily ship 1-2 based on https://github.com/cloudflare/rakelimit/tree/master/include (note linux/types.h which avoids pulling in a bunch of other Linux headers). 3-5 are difficult either because of licensing or because they are too big to ship.

Steps:

  1. Extend https://github.com/cilium/ebpf/blob/2113a5f7979dfd878db4e2fac2421565af45df41/examples/headers/update.sh to include (1) from above or adapt https://github.com/cloudflare/rakelimit/blob/master/include/Makefile
  2. Add a subdirectory to bpf2go which contains headers, and include them via go:embed
  3. Unpack headers at build time and add a -I to the clang invocation

Open questions:

ti-mo commented 3 years ago

We could always relicense bpf2go under the GPL. Since it's a CLI tool and not part of the build artifact, it should not be subject to the same linking restrictions as libraries are. Not a lawyer, though. :sweat_smile:

lmb commented 3 years ago

The problem isn't bpf2go, it's the user code using the headers.

anjmao commented 3 years ago

Since vmlinux.h is huge, shipping the whole header produces larger binaries. In libbpf-tools llvm-strip is used to removed unused objects https://github.com/iovisor/bcc/blob/master/libbpf-tools/Makefile#L4

I think bpf2go should support stripping too with flag. eg -strip which may require to have llvm-strip installed.

lmb commented 3 years ago

Good point, I think that is #429