ebpf icon indicating copy to clipboard operation
ebpf copied to clipboard

bpf2go: ship common C headers

Open lmb opened this issue 4 years ago • 4 comments

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:

  • Should headers be available by default, or only when a user passes a -with-headers flag? The former has better UX, but we then have to make sure that user provided include paths take precedence. It's also problematic if the user tries to compile against system installed kernel headers (not recommended, but does happen). We might have to start passing -nostdinc to clang by default, which could break builds.

lmb avatar Oct 13 '21 11:10 lmb

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:

ti-mo avatar Oct 14 '21 07:10 ti-mo

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

lmb avatar Oct 14 '21 09:10 lmb

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.

anjmao avatar Nov 06 '21 21:11 anjmao

Good point, I think that is #429

lmb avatar Nov 08 '21 10:11 lmb