An open API service indexing awesome lists of open source software.

https://github.com/v420v/ego

Go compiler for eBPF
https://github.com/v420v/ego

compiler ebpf go

Last synced: 22 days ago
JSON representation

Go compiler for eBPF

Awesome Lists containing this project

README

          

# eGo - eBPF in Pure Go

**Write eBPF programs in Go. Get a regular `.bpf.o` that any BPF loader can load.**

eGo is a Go-to-eBPF compiler. You write a subset of Go; it emits a
`clang -target bpf`-compatible ELF object — BTF, CO-RE relocations, and
all. The BPF backend, BTF encoder, and CO-RE relocator are all pure Go.

```
your_program.go ← //go:build ego
│ ego build

your_program.bpf.o ← standard BPF ELF + BTF + CO-RE relocs
│ any BPF loader: libbpf (C), libbpf-rs / aya (Rust),
│ cilium/ebpf (Go), libbpf-python / bcc (Python), bpftool, …

kernel: verifier → JIT → run
```

eGo owns ELF emission. The output is a normal BPF ELF, so any existing loader in any language works. The examples in this repo use `cilium/ebpf`
because the project is Go-leaning, but nothing about eGo's output is Go-specific.

## Install

```sh
go install github.com/v420v/ego/cmd/ego@latest
```

Or from source:
```sh
make build # → bin/ego
make examples # build every example to .bpf.o
```

## Hello, XDP

```go
//go:build ego
package bpf

import (
"github.com/v420v/ego/stdlib/maps"
"github.com/v420v/ego/stdlib/xdp"
)

var PacketCount = maps.PerCPUArray[uint64]{MaxEntries: 1}

//ego:program type=xdp
func Count(ctx *xdp.Context) xdp.Action {
var key uint32 = 0
if v := PacketCount.Lookup(&key); v != nil {
*v = *v + 1
}
return xdp.Pass
}
```

Build:

```sh
ego build -o counter.bpf.o ./path/to/pkg
```

Load with whatever BPF loader you already use. Examples:

```go
// Go — github.com/cilium/ebpf
spec, _ := ebpf.LoadCollectionSpec("counter.bpf.o")
coll, _ := ebpf.NewCollection(spec)
defer coll.Close()
l, _ := link.AttachXDP(link.XDPOptions{
Program: coll.Programs["Count"], Interface: ifaceIdx,
})
defer l.Close()
```

```c
// C — libbpf
struct bpf_object *obj = bpf_object__open_file("counter.bpf.o", NULL);
bpf_object__load(obj);
struct bpf_program *prog = bpf_object__find_program_by_name(obj, "Count");
bpf_program__attach_xdp(prog, ifindex);
```

```sh
# Shell — bpftool, no userspace code at all
bpftool prog loadall counter.bpf.o /sys/fs/bpf/counter
bpftool net attach xdp pinned /sys/fs/bpf/counter/Count dev eth0
```

The `.bpf.o` is the same standard ELF in every case.

## License

MIT.