Skip to content

Latest commit

 

History

History
112 lines (84 loc) · 2.53 KB

cilium-ebpf-go.md

File metadata and controls

112 lines (84 loc) · 2.53 KB

Cilium ebpf go lib

  • asm 包含一个基本的汇编生成器。
  • link 允许将附加的 eBPF 程序挂载到各类 hooks 上。
  • perf 提供从 PERF_EVENT_ARRAY 读取对应的数据。
  • cmd/bpf2go 将 eBPF 程序嵌入到 Go 代码中。

godoc 地址: https://godoc.org/github.com/cilium/ebpf

bpf2go

可以实现将 C 代码编写的 bpf 程序编译成 Go 代码。

test.c

// +build ignore

char __license[] __attribute__((section("license"), used)) = "MIT";

__attribute__((section("socket"), used)) int filter() { return 0; }

将 C 文件编译成 Go 代码

# go build -o bpf2go
# export GOPACKAGE="sock"   // 定义生产 go 代码的包名
# ./bpf2go -cc=clang -makebase="" -target=bpf sock test.c
Compiled /root/go/src/github.com/cilium/ebpf/cmd/bpf2go/test_bpf.o
Wrote /root/go/src/github.com/cilium/ebpf/cmd/bpf2go/sock_bpf.go

# 最后会生成 test_bpf.o 和 sock_bpf.go

生成的 sock_bpf.go 完整代码如下:

// Code generated by bpf2go; DO NOT EDIT.

package aa

import (
	"bytes"
	"fmt"
	"io"

	"github.com/cilium/ebpf"
)

type sockSpecs struct {
	ProgramFilter *ebpf.ProgramSpec `ebpf:"filter"`
}

func newSockSpecs() (*sockSpecs, error) {
	reader := bytes.NewReader(_SockBytes)
	spec, err := ebpf.LoadCollectionSpecFromReader(reader)
	if err != nil {
		return nil, fmt.Errorf("can't load sock: %w", err)
	}

	specs := new(sockSpecs)
	if err := spec.Assign(specs); err != nil {
		return nil, fmt.Errorf("can't assign sock: %w", err)
	}

	return specs, nil
}

func (s *sockSpecs) CollectionSpec() *ebpf.CollectionSpec {
	return &ebpf.CollectionSpec{
		Programs: map[string]*ebpf.ProgramSpec{
			"filter": s.ProgramFilter,
		},
		Maps: map[string]*ebpf.MapSpec{},
	}
}

func (s *sockSpecs) Load(opts *ebpf.CollectionOptions) (*sockObjects, error) {
	var objs sockObjects
	if err := s.CollectionSpec().LoadAndAssign(&objs, opts); err != nil {
		return nil, err
	}
	return &objs, nil
}

func (s *sockSpecs) Copy() *sockSpecs {
	return &sockSpecs{
		ProgramFilter: s.ProgramFilter.Copy(),
	}
}

type sockObjects struct {
	ProgramFilter *ebpf.Program `ebpf:"filter"`
}

func (o *sockObjects) Close() error {
	for _, closer := range []io.Closer{
		o.ProgramFilter,
	} {
		if err := closer.Close(); err != nil {
			return err
		}
	}
	return nil
}

// Do not access this directly.
var _SockBytes = []byte("0x....")