README

libbpfgo

libbpfgo is a Go library that allows working with the Linux eBPF subsystem via libbpf. libbpf is a C library that's developed as part of the Linux kernel tree which provides an accessible layer of abstraction on top of the raw eBPF system APIs. libbpfgo is just a thin wrapper in Go around libbpf.

Installing

libbpfgo is using CGO to interop with libbpf and will expect to be linked with libbpf at run or link time. Simply importing libbpfgo is not enough to get started, and you will need to fulfill the required dependency in one of the following ways:

  1. Install the libbpf as a shared object in the system. Libbpf may already be packaged for you distribution, if not, you can build and install from source. More info here.
  2. Embed libbpf into your Go project as a vendored dependency. This means that the libbpf code is statically linked into the resulting binary, and there are no runtime dependencies. Tracee takes this approach and you can take example from it's Makefile.

Concepts

libbpfgo tries to make it natural for Go developers to use, by abstracting away C technicalities. For example, it will translate low level return codes into Go error, it will organize functionality around Go struct, and it will use channel as to let you consume events.

In a high level, this is a typical workflow for working with the library:

  1. Compile your bpf program into an object file.
  2. Initialize a Module struct - that is a unit of BPF functionality around your compiled object file.
  3. Load bpf programs from the object file using the BPFProg struct.
  4. Attach BPFProg to system facilities, for example to "raw tracepoints" or "kprobes" using the BPFProg's associated functions.
  5. Instantiate and manipulate BPF Maps via the BPFMap struct and it's associated methods.
  6. Instantiate and manipulate Perf Buffer for communicating events from your BPF program to the driving userspace program, using the PerfBuffer struct and it's associated objects.

Example

// initializing
import bpf "github.com/aquasecurity/tracee/libbpfgo"
...
bpfModule := bpf.NewModuleFromFile(bpfObjectPath)
bpfModule.BPFLoadObject()

// maps
mymap, _ := bpfModule.GetMap("mymap")
mymap.Update(key, value)

// perf buffer
pb, _ := bpfModule.InitPerfBuf("events", eventsChannel, lostEvChannel, buffSize)
pb.Start()
e := <-eventsChannel

There are many more methods supported and functionality available. We will be documenting this library more extensively in the future, but in the meantime, you can take a look at the libbpf_wrapper.go code to get an idea of what's possible, or look at the Tracee code as a consumer of this library, or just ask us by creating a new Discussion and we'd love to help.

Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const (
	BPFProgTypeUnspec uint32 = iota
	BPFProgTypeSocketFilter
	BPFProgTypeKprobe
	BPFProgTypeSchedCls
	BPFProgTypeSchedAct
	BPFProgTypeTracepoint
	BPFProgTypeXdp
	BPFProgTypePerfEvent
	BPFProgTypeCgroupSkb
	BPFProgTypeCgroupSock
	BPFProgTypeLwtIn
	BPFProgTypeLwtOut
	BPFProgTypeLwtXmit
	BPFProgTypeSockOps
	BPFProgTypeSkSkb
	BPFProgTypeCgroupDevice
	BPFProgTypeSkMsg
	BPFProgTypeRawTracepoint
	BPFProgTypeCgroupSockAddr
	BPFProgTypeLwtSeg6Local
	BPFProgTypeLircMode2
	BPFProgTypeSkReuseport
	BPFProgTypeFlowDissector
	BPFProgTypeCgroupSysctl
	BPFProgTypeRawTracepointWritable
	BPFProgTypeCgroupSockopt
	BPFProgTypeTracing
	BPFProgTypeStructOps
	BPFProgTypeExt
	BPFProgTypeLsm
	BPFProgTypeSkLookup
)

Variables

This section is empty.

Functions

func GetUnsafePointer

func GetUnsafePointer(data interface{}) (unsafe.Pointer, error)

Types

type BPFLink struct {
	// contains filtered or unexported fields
}

type BPFMap

type BPFMap struct {
	// contains filtered or unexported fields
}

func (*BPFMap) DeleteKey

func (b *BPFMap) DeleteKey(key interface{}) error

func (*BPFMap) GetMaxEntries

func (b *BPFMap) GetMaxEntries() uint32

    GetMaxEntries returns the map's capacity. Note: for ring buffer and perf buffer, maxEntries is the capacity in bytes.

    func (*BPFMap) GetValue

    func (b *BPFMap) GetValue(key interface{}, valueSize int) ([]byte, error)

    func (*BPFMap) Pin

    func (b *BPFMap) Pin(pinPath string) error

    func (*BPFMap) Resize

    func (b *BPFMap) Resize(maxEntries uint32) error

      Resize changes the map's capacity to maxEntries. It should be called after the module was initialized but prior to it being loaded with BPFLoadObject. Note: for ring buffer and perf buffer, maxEntries is the capacity in bytes.

      func (*BPFMap) SetPinPath

      func (b *BPFMap) SetPinPath(pinPath string) error

      func (*BPFMap) Unpin

      func (b *BPFMap) Unpin(pinPath string) error

      func (*BPFMap) Update

      func (b *BPFMap) Update(key, value interface{}) error

      type BPFProg

      type BPFProg struct {
      	// contains filtered or unexported fields
      }

      func (*BPFProg) AttachKprobe

      func (p *BPFProg) AttachKprobe(kp string) (*BPFLink, error)

        this API should be used for kernels > 4.17

        func (*BPFProg) AttachKprobeLegacy

        func (p *BPFProg) AttachKprobeLegacy(kp string) (*BPFLink, error)

        func (*BPFProg) AttachKretprobe

        func (p *BPFProg) AttachKretprobe(kp string) (*BPFLink, error)

          this API should be used for kernels > 4.17

          func (*BPFProg) AttachKretprobeLegacy

          func (p *BPFProg) AttachKretprobeLegacy(kp string) (*BPFLink, error)

          func (*BPFProg) AttachRawTracepoint

          func (p *BPFProg) AttachRawTracepoint(tpEvent string) (*BPFLink, error)

          func (*BPFProg) AttachTracepoint

          func (p *BPFProg) AttachTracepoint(tp string) (*BPFLink, error)

          func (*BPFProg) GetFd

          func (p *BPFProg) GetFd() C.int

          func (*BPFProg) GetType

          func (p *BPFProg) GetType() uint32

          func (*BPFProg) SetAutoload

          func (p *BPFProg) SetAutoload(autoload bool) error

          func (*BPFProg) SetTracepoint

          func (p *BPFProg) SetTracepoint() error

          type BPFProgType

          type BPFProgType uint32

            BPFProgType is an enum as defined in https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/bpf.h

            type LinkType

            type LinkType int
            const (
            	Tracepoint LinkType = iota
            	RawTracepoint
            	Kprobe
            	Kretprobe
            	KprobeLegacy
            	KretprobeLegacy
            )

            type Module

            type Module struct {
            	// contains filtered or unexported fields
            }

            func NewModuleFromBuffer

            func NewModuleFromBuffer(bpfObjBuff []byte, bpfObjName string) (*Module, error)

            func NewModuleFromFile

            func NewModuleFromFile(bpfObjFile string) (*Module, error)

            func (*Module) BPFLoadObject

            func (m *Module) BPFLoadObject() error

            func (*Module) Close

            func (m *Module) Close()

            func (*Module) GetMap

            func (m *Module) GetMap(mapName string) (*BPFMap, error)

            func (*Module) GetProgram

            func (m *Module) GetProgram(progName string) (*BPFProg, error)

            func (*Module) InitPerfBuf

            func (m *Module) InitPerfBuf(mapName string, eventsChan chan []byte, lostChan chan uint64, pageCnt int) (*PerfBuffer, error)

            func (*Module) InitRingBuf

            func (m *Module) InitRingBuf(mapName string, eventsChan chan []byte) (*RingBuffer, error)

            type PerfBuffer

            type PerfBuffer struct {
            	// contains filtered or unexported fields
            }

            func (*PerfBuffer) Close

            func (pb *PerfBuffer) Close()

            func (*PerfBuffer) Start

            func (pb *PerfBuffer) Start()

            func (*PerfBuffer) Stop

            func (pb *PerfBuffer) Stop()

            type RingBuffer

            type RingBuffer struct {
            	// contains filtered or unexported fields
            }

            func (*RingBuffer) Close

            func (rb *RingBuffer) Close()

            func (*RingBuffer) Start

            func (rb *RingBuffer) Start()

            func (*RingBuffer) Stop

            func (rb *RingBuffer) Stop()

            Directories

            Path Synopsis
            selftest