# gobee

Bora Tanrıkulu's Go-to-BPF-C transpiler. Write your kernel-side BPF program in a strict subset of Go; gobee emits BPF C, runs clang, and generates typed Go bindings so the userspace driver works in terms of your own structs and program names instead of stringly-typed `coll.Programs["..."]` lookups.

The structural decision is the interesting part. Aya (Rust eBPF) gets there by *adding a new BPF backend to rustc* — feasible because rustc is built on LLVM. The Go compiler `gc` isn't, so adding a BPF backend would be a multi-year compiler project. gobee skips that work by **emitting C and reusing clang's mature BPF backend**, which gets you CO-RE, BTF, and verifier-friendly codegen for free. The cost is that clang stays in the user's toolchain.

## How it works

Pipeline:

1. **Type-check.** `go/types` runs over the input first so misuses surface at Go `file:line:col`, not somewhere downstream in clang's error stream.
2. **Transpile.** `gobee translate --bindings-dir ./bpf ./bpf/src` produces three artifacts per kernel source: `<stem>.bpf.c`, a sourcemap `<stem>.bpf.c.map`, and a typed `<stem>_bindings.go`.
3. **Compile.** User runs clang to produce `<stem>.bpf.o`. Same Makefile pattern as bpf2go.
4. **Load.** The generated `Load<Stem>` function calls into `cilium/ebpf` and runs [bpfvet](https://github.com/boratanrikulu/bpfvet) inside it. If the host kernel's too old for any helper the program uses, load fails fast with `bpf program needs kernel >= 5.8, host is 5.4` instead of opaque `EINVAL`. If the verifier rejects the program, the returned `*ebpf.VerifierError` is auto-annotated with `→ counter.go:18:5` markers pointing back to the Go source.

The emitted C is readable on purpose — when gobee emits something weird, you can see it.

## Surface coverage

8 program types (XDP, tracepoint, kprobe/kretprobe, uprobe/uretprobe, sock_ops, TC, cgroup_skb, LSM). 19 map types including ringbuf, perf_event_array, sk/task/inode storage, devmap/cpumap/xskmap. About 200 typed Go stubs auto-generated from libbpf v1.5.0 headers — the ones exercised by `example/helloworld/` and `example/sysmon/` are tested in real-kernel CI; the rest are unverified.

User-defined helper functions: top-level Go funcs without `//bpf:section` are emitted as `static __always_inline` C functions.

CO-RE is auto-detected — `BPF_CORE_READ` for kernel-internal struct fields (`task_struct`, `sock`, `inode`), direct `ctx->field` access for UAPI BPF context structs (`xdp_md`, `__sk_buff`, `bpf_sock_ops`). Exercised on Linux 6.x (Ubuntu 24.04 CI); older kernels not yet in the CI matrix. Cross-arch: Linux arm64 + amd64.

## What it explicitly won't do

- **Replace clang.** Reimplementing clang's BPF backend would cost years and gain nothing.
- **Replace `cilium/ebpf`.** The generated bindings sit on top of it.
- **Hide BPF.** The Go subset maps 1:1 to BPF C idioms. If you know BPF, gobee is thin sugar; if you don't, the manual is still required reading.
- **Run clang for you.** Compile, embed, and load remain user-owned — same pattern as `bpf2go`.

## Where it fits

Same author as [[bypassing-dpi-with-ebpf|gecit]] and [`bpfvet`](https://github.com/boratanrikulu/bpfvet); gobee uses bpfvet at load time and gecit demonstrates the kind of in-kernel networking BPF program (sock_ops SNI desync) gobee is aimed at making more pleasant to write. See [[bora-blog]] for the author's writing on this space.

For sandboxing context — the layer where this matters operationally — see [[ebpf-sock-ops]] and [[sandboxing-ai-agents]] (Layer 1 / kernel boundary discussion). Compare-and-contrast tools: `bpf2go` (the C+clang baseline) and [Aya](https://github.com/aya-rs/aya) (Rust via rustc BPF backend).

## Limitations

- macOS/Windows: gobee itself runs (pure Go), but compiling `.bpf.o` needs clang with the BPF target — Apple's bundled clang doesn't ship it, so `brew install llvm` or a Linux VM is required.
- Running the artifact: Linux on arm64 or amd64.
- Helper coverage outside the CI examples is unverified; expect issues on niche kernel helpers until the matrix expands.

## Repo

[github.com/boratanrikulu/gobee](https://github.com/boratanrikulu/gobee) · 25★ at ingest · MIT · created 2026-05-01.
