goebpf

package module
v0.0.0-...-e5e17f5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2024 License: GPL-2.0 Imports: 20 Imported by: 16

README

Go eBPF

Build Status Go Report Card Documentation

A nice and convenient way to work with eBPF programs / perf events from Go.

Requirements

  • Go 1.11+
  • Linux Kernel 4.15+

Supported eBPF features

  • eBPF programs
    • SocketFilter
    • XDP
    • Kprobe / Kretprobe
    • tc-cls (tc-act is partially implemented, currently)
  • Perf Events

Support for other program types / features can be added in future. Meanwhile your contributions are warmly welcomed.. :)

Installation

# Main library
go get github.com/dropbox/goebpf

# Mock version (if needed)
go get github.com/dropbox/goebpf/goebpf_mock

Quick start

Consider very simple example of Read / Load / Attach

    // In order to be simple this examples does not handle errors
    bpf := goebpf.NewDefaultEbpfSystem()
    // Read clang compiled binary
    bpf.LoadElf("test.elf")
    // Load XDP program into kernel (name matches function name in C)
    xdp := bpf.GetProgramByName("xdp_test")
    xdp.Load()
    // Attach to interface
    xdp.Attach("eth0")
    defer xdp.Detach()
    // Work with maps
    test := bpf.GetMapByName("test")
    value, _ := test.LookupInt(0)
    fmt.Printf("Value at index 0 of map 'test': %d\n", value)

Like it? Check our examples

Perf Events

Currently library has support for one, most popular use case of perf_events: where eBPF map key maps to cpu_id. So eBPF and go parts actually bind cpu_id to map index. It maybe as simple as:

    // Define special, perf_events map where key maps to CPU_ID
    BPF_MAP_DEF(perfmap) = {
        .map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
        .max_entries = 128,     // Max supported CPUs
    };
    BPF_MAP_ADD(perfmap);

    // ...

    // Emit perf event with "data" to map "perfmap" where index is current CPU_ID
    bpf_perf_event_output(ctx, &perfmap, BPF_F_CURRENT_CPU, &data, sizeof(data));

And the go part:

    perf, err := goebpf.NewPerfEvents("perfmap")
    // 4096 is ring buffer size
    perfEvents, err := perf.StartForAllProcessesAndCPUs(4096)
    defer perf.Stop()

    for {
        select {
            case data := <-perfEvents:
                fmt.Println(data)
        }
    }

Looks simple? Check our full XDP dump example

Kprobes

Library currently has support for kprobes and kretprobes. It can be as simple as:

    // kprobe handler function
    SEC("kprobe/guess_execve")
    int execve_entry(struct pt_regs *ctx) {
      // ...
      buf_perf_output(ctx);
      return 0;
    }

And the go part:

	// Cleanup old probes
	err := goebpf.CleanupProbes()

	// Attach all probe programs
	for _, prog := range bpf.GetPrograms() {
		err := prog.Attach(nil)
	}

	// Create perf events
	eventsMap := p.bpf.GetMapByName("events")
	p.pe, err = goebpf.NewPerfEvents(eventsMap)
	events, err := p.pe.StartForAllProcessesAndCPUs(4096)
	defer events.Stop()

	for {
		select {
		case data := <-events:
			fmt.Println(data) // kProbe event
		}
	}

Simple? Check exec dump example

Good readings

Documentation

Overview

Package goebpf provides simple and convenient interface to Linux eBPF system.

Overview

Extended Berkeley Packet Filter (eBPF) is a highly flexible and efficient virtual machine in the Linux kernel allowing to execute bytecode at various hook points in a safe manner. It is actually close to kernel modules which can provide the same functionality, but without cost of kernel panic if something went wrong.

The library is intended to simplify work with eBPF programs. It takes care of low level routine implementation to make it easy to load/run/manage eBPF programs. Currently supported functionality: - Read / parse clang/llmv compiled binaries for eBPF programs / maps - Creates / loads eBPF program / eBPF maps into kernel - Provides simple interface to interact with eBPF maps - Has mock versions of eBPF objects (program, map, etc) in order to make writing unittests simple.

XDP

eXpress Data Path - provides a bare metal, high performance, programmable packet processing at the closest at possible point to network driver. That makes it ideal for speed without compromising programmability. Key benefits includes following:

- It does not require any specialized hardware (program works in kernel’s "VM") - It does not require kernel bypass - It does not replace the TCP/IP stack

Considering very simple and highly effective way to DROP all packets from given source IPv4 address:

XDP program (written in C):

// Simple map to count dropped packets
BPF_MAP_DEF(drops) = {
    .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
    .key_size = 4,
    .value_size = 8,
    .max_entries = 1,
};
BPF_MAP_ADD(drops);

SEC("xdp")
int xdp_drop(struct xdp_md *ctx)
{
    if (found) { // If some condition (e.g. SRC IP) matches...
        __u32 idx = 0;
        // Increase stat by 1
        __u64 *stat = bpf_map_lookup_elem(&drops, &idx);
        if (stat) {
            *stat += 1;
        }
        return XDP_DROP;
    }
    return XDP_PASS;
}

Once compiled can be used by goebpf in the following way:

bpf := goebpf.NewDefaultEbpfSystem()
err := bpf.LoadElf("xdp.elf")
program := bpf.GetProgramByName("xdp_drop") // name matches function name in C
err = program.Load() // Load program into kernel
err = program.Attach("eth0") // Attach to interface
defer program.Detach()

// Interact with program is simply done through maps:
drops := bpf.GetMapByName("drops") // name also matches BPF_MAP_ADD(drops)
val, err := drops.LookupInt(0) // Get value from map at index 0
if err == nil {
    fmt.Printf("Drops: %d\n", val)
}

PerfEvents

Perf Events (originally Performance Counters for Linux) is powerful kernel instrument for tracing, profiling and a lot of other cases like general events to user space.

Usually it is implemented using special eBPF map type "BPF_MAP_TYPE_PERF_EVENT_ARRAY" as a container to send events into.

A simple example could be to log all TCP SYN packets into user space from XDP program:

BPF_MAP_DEF(perfmap) = {
	.map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
	.max_entries = 128,  // Up to 128 CPUs
};
BPF_MAP_ADD(perfmap);

SEC("xdp")
int xdp_dump(struct xdp_md *ctx) {
	// ...
	if (tcp->syn) {
		// Log event to user space
		bpf_perf_event_output(ctx, &perfmap, BPF_F_CURRENT_CPU, &evt, sizeof(evt));
	}
}

bpf := goebpf.NewDefaultEbpfSystem()
bpf.LoadElf("xdp.elf")
program := bpf.GetProgramByName("xdp_dump") // name matches function name in C
err = program.Load() // Load program into kernel
err = program.Attach("eth0") // Attach to interface
defer program.Detach()

// Start listening to Perf Events
perf, err := goebpf.NewPerfEvents(perfmap)
// 4096 is ring buffer size
perfEvents, err := perf.StartForAllProcessesAndCPUs(4096)
defer perf.Stop()

for {
	select {
		case eventData := <-perfEvents:
			fmt.Println(eventData)
	}
}

Kprobes

There are currently two types of supported probes: kprobes, and kretprobes (also called return probes). A kprobe can be inserted on virtually any instruction in the kernel. A return probe fires when a specified function returns.

For example, you can trigger eBPF code to run when a kernel function starts by attaching the program to a “kprobe” event. Because it runs in the kernel, eBPF code is extremely high performance.

A simple example could be to log all process execution events into user space from Kprobe program:

BPF_MAP_DEF(events) = {
	.map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
	.max_entries = 1024,
};
BPF_MAP_ADD(events);

SEC("kprobe/guess_execve")
int execve_entry(struct pt_regs *ctx) {
	// ...
	event_t e = {0};
	e.ktime_ns = bpf_ktime_get_ns();
	e.pid = bpf_get_current_pid_tgid() >> 32;
	e.uid = bpf_get_current_uid_gid() >> 32;
	e.gid = bpf_get_current_uid_gid();
	bpf_get_current_comm(&e.comm, sizeof(e.comm));

	buf_write(buf, (void *)&e, sizeof(e));
	buf_strcat(buf, (void *)args[0]);
	buf_strcat_argv(buf, (void *)args[1]);
	buf_perf_output(ctx);

	return 0;
}

// Cleanup old probes
err := goebpf.CleanupProbes()

// Load eBPF compiled binary
bpf := goebpf.NewDefaultEbpfSystem()
bpf.LoadElf("kprobe.elf")
program := bpf.GetProgramByName("kprobe") // name matches function name in C

// Attach kprobes
err = p.AttachProbes()
// Detach them once done
defer p.DetachProbes()

Index

Constants

View Source
const (
	// MapSectionName is name of ELF section for maps
	MapSectionName = "maps"
	// LicenseSectionName is name of ELF section for license info
	LicenseSectionName = "license"
)
View Source
const (
	SocketFilterDeny  SocketFilterResult = C.SOCKET_FILTER_DENY
	SocketFilterAllow SocketFilterResult = C.SOCKET_FILTER_ALLOW

	SocketAttachTypeFilter    SocketFilterAttachType = SO_ATTACH_BPF
	SocketAttachTypeReusePort SocketFilterAttachType = SO_ATTACH_REUSEPORT_EBPF

	// Constants from Linux kernel, they dont' present in "golang.org/x/sys/unix"
	SO_ATTACH_BPF            = 50
	SO_ATTACH_REUSEPORT_EBPF = 52
	SO_DETACH_FILTER         = 27
)
View Source
const (
	// TcProgramTypeCls is the `tc filter` program type
	TcProgramTypeCls TcProgramType = iota
	// TcProgramTypeAct is the `tc action` program type
	// Please note, support for this is currently not implemented
	TcProgramTypeAct

	// HANDLE_INGRESS_QDISC is the handle always used by the ingress or clsact
	// qdisc.
	HANDLE_INGRESS_QDISC uint32 = 0xFFFF0000

	// HANDLE_FILTER_BASE is the lowest handle value that will be used by a
	// filter installed by this library. Ideally this should not conflict with
	// filters that might be installed by another script.
	//
	// It should be possible to install multiple filters, including in the
	// same direction, and run them concurrently.
	HANDLE_FILTER_BASE uint32 = 0x1600
)

Variables

This section is empty.

Functions

func CleanupProbes

func CleanupProbes() error

CleanupProbes attempts to detach all kprobe entries containing our namespace string.

func CreateLPMtrieKey

func CreateLPMtrieKey(s string) *net.IPNet

CreateLPMtrieKey converts string representation of CIDR into net.IPNet in order to support special eBPF map type: LPMtrie ("Longest Prefix Match Trie") Can be used to match single IPv4/6 address with multiple CIDRs, like

m.Insert(CreateLPMtrieKey("192.168.0.0/16"), "value16")
m.Insert(CreateLPMtrieKey("192.168.0.0/24"), "value24")

value, err := m.LookupString(CreateLPMtrieKey("192.168.0.10"))

IP 192.168.0.10 matches both CIDRs, however lookup value will be "value24" since /24 prefix is smaller than /16

func GetNumOfPossibleCpus

func GetNumOfPossibleCpus() (int, error)

GetNumOfPossibleCpus returns number of CPU available to eBPF program NOTE: this is not the same as runtime.NumCPU()

func KeyValueToBytes

func KeyValueToBytes(ival interface{}, size int) ([]byte, error)

KeyValueToBytes coverts interface representation of key/value into bytes

func KtimeToTime

func KtimeToTime(ktime uint64) time.Time

KtimeToTime converts kernel time (nanoseconds since boot) to time.Time

func ListProbes

func ListProbes() ([]string, error)

ListProbes returns a list of the systems attached kprobes as returned by debugfs.

func NewMmapRingBuffer

func NewMmapRingBuffer(ptr unsafe.Pointer) *mmapRingBuffer

NewMmapRingBuffer creates mmapRingBuffer instance from pre-created mmap memory pointer ptr

func NullTerminatedStringToString

func NullTerminatedStringToString(val []byte) string

NullTerminatedStringToString is helper to convert null terminated string to GO string

func ParseFlexibleIntegerLittleEndian

func ParseFlexibleIntegerLittleEndian(rawVal []byte) uint64

ParseFlexibleIntegerLittleEndian converts flexible amount of bytes into little endian integer, e.g.: {1} -> 1 {0xe8, 0x3} -> 10000

Types

type BaseProgram

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

BaseProgram is common shared fields of eBPF programs

func (*BaseProgram) Close

func (prog *BaseProgram) Close() error

Close unloads program from kernel

func (*BaseProgram) GetFd

func (prog *BaseProgram) GetFd() int

GetFd returns program's file description

func (*BaseProgram) GetLicense

func (prog *BaseProgram) GetLicense() string

GetLicense returns program's license

func (*BaseProgram) GetName

func (prog *BaseProgram) GetName() string

GetName returns program name as defined in C code

func (*BaseProgram) GetSection

func (prog *BaseProgram) GetSection() string

GetSection returns section name for the program

func (*BaseProgram) GetSize

func (prog *BaseProgram) GetSize() int

GetSize returns eBPF bytecode size in bytes

func (*BaseProgram) GetType

func (prog *BaseProgram) GetType() ProgramType

GetType returns program type

func (*BaseProgram) Load

func (prog *BaseProgram) Load() error

Load loads program into linux kernel

func (*BaseProgram) Pin

func (prog *BaseProgram) Pin(path string) error

Pin saves ("pins") file description into special file on filesystem so it can be accessed from other processes. WARNING: destination filesystem must be mounted as "bpf" (mount -t bpf)

type EbpfMap

type EbpfMap struct {

	// Map name, picked up automatically by loader from ELF section
	Name       string
	Type       MapType
	KeySize    int
	ValueSize  int
	MaxEntries int
	Flags      int
	// Name of eBPF map used as template for all inner maps. Only for array/hash of maps
	InnerMapName string
	InnerMapFd   int
	// Persistent eBPF map use case: contains path to special file in filesystem.
	// WARNING: filesystem must be mounted as BPF
	PersistentPath string
	// contains filtered or unexported fields
}

EbpfMap is structure to define eBPF map

func NewMapFromExistingMapByFd

func NewMapFromExistingMapByFd(fd int) (*EbpfMap, error)

NewMapFromExistingMapByFd creates eBPF map from already existing map by fd available to current process (i.e. created by it). In other words it will work only on maps created by current process.

func NewMapFromExistingMapById

func NewMapFromExistingMapById(id int) (*EbpfMap, error)

NewMapFromExistingMapById creates eBPF map from BPF object ID. BPF object ID is a kernel mechanism to let non owner process to use BPF objects. Common use case - tooling for troubleshoot / inspect existing BPF objects in the kernel.

func NewMapFromExistingMapByPath

func NewMapFromExistingMapByPath(path string) (*EbpfMap, error)

NewMapFromExistingMapMapByPath creates eBPF map from a pinned BPF object path. Pinned BPF object is a kernel mechanism to let non owner process to use BPF objects. Common use case - tooling for troubleshoot / inspect existing BPF objects in the kernel.

func (*EbpfMap) CloneTemplate

func (m *EbpfMap) CloneTemplate() Map

CloneTemplate creates new instance of eBPF map using current map parameters. Main use case is work with array/hash of maps:

// Create new map based on template
newItem := templateMap.CloneTemplate()
newItem.Create()
// Insert item into array of maps
superMap.Insert(1, newItem)

func (*EbpfMap) Close

func (m *EbpfMap) Close() error

Close destroy eBPF map (removes it from kernel)

func (*EbpfMap) Create

func (m *EbpfMap) Create() error

Create creates map in kernel

func (*EbpfMap) Delete

func (m *EbpfMap) Delete(ikey interface{}) error

Delete deletes element by given ikey. Array based types are not supported.

func (*EbpfMap) GetFd

func (m *EbpfMap) GetFd() int

GetFd returns fd (file descriptor) of eBPF map

func (*EbpfMap) GetName

func (m *EbpfMap) GetName() string

GetName returns map name

func (*EbpfMap) GetNextKey

func (m *EbpfMap) GetNextKey(ikey interface{}) ([]byte, error)

GetNextKey looks up next key in the map. returns 'next_key' on success, 'err' on failure (or last key in map - no next key available). when 'nil' is passed to this method, the first key in the map is returned.

func (*EbpfMap) GetNextKeyInt

func (m *EbpfMap) GetNextKeyInt(ikey interface{}) (int, error)

GetNextKeyInt looks up next key in the map and returns it as int.

func (*EbpfMap) GetNextKeyString

func (m *EbpfMap) GetNextKeyString(ikey interface{}) (string, error)

GetNextKeyString looks up next key in the map and returns it as a golang string.

func (*EbpfMap) GetNextKeyUint64

func (m *EbpfMap) GetNextKeyUint64(ikey interface{}) (uint64, error)

GetNextKeyUint64 looks up next key in the map and returns it as uint64.

func (*EbpfMap) GetType

func (m *EbpfMap) GetType() MapType

GetType returns map type

func (*EbpfMap) Insert

func (m *EbpfMap) Insert(ikey interface{}, ivalue interface{}) error

Insert inserts value into eBPF map at given ikey. Supported key/value types are: int, uint8, uint16, uint32, int32, uint64, string, []byte, net.IPNet

func (*EbpfMap) Lookup

func (m *EbpfMap) Lookup(ikey interface{}) ([]byte, error)

Lookup performs lookup and returns array of bytes WARNING: For Per-CPU array/hash map return value will contain data from all CPUs, i.e. length = roundUp(valueSize, 8) * nCPU

func (*EbpfMap) LookupInt

func (m *EbpfMap) LookupInt(ikey interface{}) (int, error)

LookupInt performs lookup and returns integer WARNING: For Per-CPU array/hash returns sum of values from all CPUs

func (*EbpfMap) LookupString

func (m *EbpfMap) LookupString(ikey interface{}) (string, error)

LookupString perform lookup and returns GO string from NULL terminated C string WARNING: Does NOT work for Per-CPU maps (not an real use case?).

func (*EbpfMap) LookupUint64

func (m *EbpfMap) LookupUint64(ikey interface{}) (uint64, error)

LookupUint64 performs lookup and returns uint64 WARNING: For Per-CPU array/hash returns sum of values from all CPUs

func (*EbpfMap) Update

func (m *EbpfMap) Update(ikey interface{}, ivalue interface{}) error

Update updates (replaces) element at given ikey. Supported ivalue types are: int, uint8, uint16, uint32, int32, uint64, string, []byte, net.IPNet

Element must be inserted before for non array types (map, hash)

func (*EbpfMap) Upsert

func (m *EbpfMap) Upsert(ikey interface{}, ivalue interface{}) error

Upsert updates (replaces) or inserts element at given ikey. Supported ivalue types are: int, uint8, uint16, uint32, int32, uint64, string, []byte, net.IPNet

type KprobeAttachType

type KprobeAttachType int

KprobeAttachType specified whether a Kprobe program is attached as an entry or exit probe.

const (
	KprobeAttachTypeEntry KprobeAttachType = iota
	KprobeAttachTypeReturn
)

func (KprobeAttachType) Prefix

func (t KprobeAttachType) Prefix() string

Prefix returns the string prefix used by debugfs actions.

func (KprobeAttachType) String

func (t KprobeAttachType) String() string

String returns a human readable string for a kprobe attach type.

type Map

type Map interface {
	Create() error
	GetFd() int
	GetName() string
	GetType() MapType
	Close() error
	// Makes a copy of map definition. This will NOT create map, just copies definition, "template".
	// Useful for array/map of maps use case
	CloneTemplate() Map
	// Generic lookup. Accepts any type which will be
	// converted to []byte eventually, returns bytes
	Lookup(interface{}) ([]byte, error)
	// The same, but does casting of return value to int / uint64
	LookupInt(interface{}) (int, error)
	LookupUint64(interface{}) (uint64, error)
	// The same, but does casting of return value to string
	LookupString(interface{}) (string, error)
	Insert(interface{}, interface{}) error
	Update(interface{}, interface{}) error
	Upsert(interface{}, interface{}) error
	Delete(interface{}) error
	// Implementation of bpf_map_get_next_key
	GetNextKey(interface{}) ([]byte, error)
	GetNextKeyString(interface{}) (string, error)
	GetNextKeyInt(interface{}) (int, error)
	GetNextKeyUint64(interface{}) (uint64, error)
}

Map defines interface to interact with eBPF maps

type MapType

type MapType int

MapType is eBPF map type enum

const (
	MapTypeHash                MapType = C.BPF_MAP_TYPE_HASH
	MapTypeArray               MapType = C.BPF_MAP_TYPE_ARRAY
	MapTypeProgArray           MapType = C.BPF_MAP_TYPE_PROG_ARRAY
	MapTypePerfEventArray      MapType = C.BPF_MAP_TYPE_PERF_EVENT_ARRAY
	MapTypePerCPUHash          MapType = C.BPF_MAP_TYPE_PERCPU_HASH
	MapTypePerCPUArray         MapType = C.BPF_MAP_TYPE_PERCPU_ARRAY
	MapTypeStackTrace          MapType = C.BPF_MAP_TYPE_STACK_TRACE
	MapTypeCgroupArray         MapType = C.BPF_MAP_TYPE_CGROUP_ARRAY
	MapTypeLRUHash             MapType = C.BPF_MAP_TYPE_LRU_HASH
	MapTypeLRUPerCPUHash       MapType = C.BPF_MAP_TYPE_LRU_PERCPU_HASH
	MapTypeLPMTrie             MapType = C.BPF_MAP_TYPE_LPM_TRIE
	MapTypeArrayOfMaps         MapType = C.BPF_MAP_TYPE_ARRAY_OF_MAPS
	MapTypeHashOfMaps          MapType = C.BPF_MAP_TYPE_HASH_OF_MAPS
	MapTypeDevMap              MapType = C.BPF_MAP_TYPE_DEVMAP
	MapTypeSockMap             MapType = C.BPF_MAP_TYPE_SOCKMAP
	MapTypeCPUMap              MapType = C.BPF_MAP_TYPE_CPUMAP
	MapTypeXSKMap              MapType = C.BPF_MAP_TYPE_XSKMAP
	MapTypeSockHash            MapType = C.BPF_MAP_TYPE_SOCKHASH
	MapTypeCGroupStorage       MapType = C.BPF_MAP_TYPE_CGROUP_STORAGE
	MapTypeReusePortSockArray  MapType = C.BPF_MAP_TYPE_REUSEPORT_SOCKARRAY
	MapTypePerCpuCGroupStorage MapType = C.BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE
	MapTypeQueue               MapType = C.BPF_MAP_TYPE_QUEUE
	MapTypeStack               MapType = C.BPF_MAP_TYPE_STACK
	MapTypeSKStorage           MapType = C.BPF_MAP_TYPE_SK_STORAGE
)

Supported eBPF map types.

func (MapType) String

func (t MapType) String() string

Returns user friendly name for MapType

type PerfEvents

type PerfEvents struct {
	// Statistics
	EventsReceived   int
	EventsLost       int
	EventsUnknowType int

	// PollTimeoutMs is timeout for blocking call of poll()
	// Defaults to 100ms
	PollTimeoutMs int
	// contains filtered or unexported fields
}

PerfEvents is a way to interact with Linux's PerfEvents for eBPF cases.

func NewPerfEvents

func NewPerfEvents(m Map) (*PerfEvents, error)

NewPerfEvents creates new instance of PerfEvents for eBPF map "m". "m" must be a type of "MapTypePerfEventArray"

func (*PerfEvents) StartForAllProcessesAndCPUs

func (pe *PerfEvents) StartForAllProcessesAndCPUs(bufferSize int) (<-chan []byte, error)

StartForAllProcessesAndCPUs starts PerfEvent polling on all CPUs for all system processes This mode requires specially organized map: index matches CPU ID. "bufferSize" is ring buffer size for perfEvents. Per CPU. All updates will be sent into returned channel.

func (*PerfEvents) Stop

func (pe *PerfEvents) Stop()

Stop stops event polling loop

type Program

type Program interface {
	// Load program into Linux kernel
	Load() error
	// Pin (save, share) program into given location.
	// Location must be mounted as bpffs (mount bpffs -t bpffs /some/location)
	Pin(path string) error
	// Unload program from kernel
	Close() error
	// Attach program to something - depends on program type.
	// - XDP: Attach to network interface (data - iface name, or XdpAttachParams)
	// - SocketFilter: Attach to socket (data - socket fd)
	Attach(data interface{}) error
	// Detach previously attached program
	Detach() error
	// Returns program name as it defined in C code
	GetName() string
	// Returns section name for the program
	GetSection() string
	// Returns program file descriptor (given by kernel)
	GetFd() int
	// Returns size of program in bytes
	GetSize() int
	// Returns program's license
	GetLicense() string
	// Returns program type
	GetType() ProgramType
}

Program defines eBPF program interface

type ProgramInfo

type ProgramInfo struct {
	Name             string
	Tag              string // Program tag (unclear what this for)
	Type             ProgramType
	Id               int // ID - external ID of program (to refer object)
	Fd               int // fd - local process fd to be able to access the object.
	JitedProgramLen  int // Size of program in CPU instructions
	XlatedProgramLen int // Size of program in bytecode
	LoadTime         time.Time
	CreatedByUid     int            // UID of creator
	Maps             map[string]Map // Associated eBPF maps
}

ProgramInfo - information of already loaded eBPF program info

Main use case is to inspect already loaded into kernel programs.

func GetProgramInfoByFd

func GetProgramInfoByFd(fd int) (*ProgramInfo, error)

GetProgramInfoByFd queries information about already loaded eBPF program by fd (fd belongs to local process, cannot be shared)

func GetProgramInfoById

func GetProgramInfoById(id int) (*ProgramInfo, error)

GetProgramInfoById queries information about already loaded eBPF program by external ID.

func GetProgramInfoByPath

func GetProgramInfoByPath(path string) (*ProgramInfo, error)

GetProgramInfoByPath queries information about already loaded eBPF program by using its pinned path in the filesystem.

type ProgramType

type ProgramType int

ProgramType is eBPF program types enum

const (
	ProgramTypeUnspec ProgramType = iota
	ProgramTypeSocketFilter
	ProgramTypeKprobe
	ProgramTypeSchedCls
	ProgramTypeSchedAct
	ProgramTypeTracepoint
	ProgramTypeXdp
	ProgramTypePerfEvent
	ProgramTypeCgroupSkb
	ProgramTypeCgroupSock
	ProgramTypeLwtIn
	ProgramTypeLwtOut
	ProgramTypeLwtXmit
	ProgramTypeSockOps
)

Must be in sync with enum bpf_prog_type from <linux/bpf.h>

func (ProgramType) String

func (t ProgramType) String() string

type SocketFilterAttachParams

type SocketFilterAttachParams struct {
	// SocketFd is socket file descriptor returned by unix.Socket(...)
	SocketFd int
	// AttachType is one of SocketAttachTypeFilter / SocketAttachTypeReusePort
	// depending on use case
	AttachType SocketFilterAttachType
}

SocketFilterAttachParams is accepted as argument to Program.Attach()

type SocketFilterAttachType

type SocketFilterAttachType int

SocketFilterAttachType is either SO_ATTACH_BPF or SO_ATTACH_REUSEPORT_EBPF

func (SocketFilterAttachType) String

func (t SocketFilterAttachType) String() string

type SocketFilterResult

type SocketFilterResult int

SocketFilterResult is eBPF program return code enum

func (SocketFilterResult) String

func (t SocketFilterResult) String() string

type System

type System interface {
	// Read previously compiled eBPF program at the given path
	LoadElf(path string) error
	// Read previously compiled eBPF program from an io.ReaderAt
	Load(reader io.ReaderAt) error
	// Get all defined eBPF maps
	GetMaps() map[string]Map
	// Returns Map or nil if not found
	GetMapByName(name string) Map
	// Get all eBPF programs
	GetPrograms() map[string]Program
	// Returns Program or nil if not found
	GetProgramByName(name string) Program
}

System defines interface for eBPF system - top level interface to interact with eBPF system

func NewDefaultEbpfSystem

func NewDefaultEbpfSystem() System

NewDefaultEbpfSystem creates default eBPF system

type TcAttachParams

type TcAttachParams struct {
	// Interface is the name of the network interface to which the program should
	// be attached, i.e. "eth0".
	Interface string

	// Direction is either TcDirectionIngress or TcDirectionEgress.
	Direction TcFlowDirection

	// DirectAction indicates to the linux tc stack whether the eBPF program gets
	// to choose what happens to the packet through its return value. If false, the
	// packet always continues through the filter chain, which is preferred for
	// programs that only log things (i.e. aren't used for altering or classifying
	// traffic).
	DirectAction bool

	// EntryPoint is the name of the symbol (C function) to load from the eBPF
	// program.
	EntryPoint string

	// ClobberIngress tells this library whether to allow replacement of the
	// ingress qdisc with clsact. This could interfere with an existing tc
	// configuration, so the operator is encouraged to tread with caution if
	// enabling this option.
	//
	// If this option is set to false, the clsact qdisc will be installed if
	// no ingress qdisc is presently installed.
	ClobberIngress bool
}

TcAttachParams is attachment parameters dictating where and how the eBPF program is attached. The current behavior is to attach to the "egress" and "ingress" pseudo-qdiscs created by clsact.

type TcFlowDirection

type TcFlowDirection int

TcFlowDirection indicates whether the program goes into the egress or ingress side of the clsact pseudo-qdisc. Filters have different parent handles which are also determined by the value of the direction property.

const (
	TcDirectionIngress TcFlowDirection = iota
	TcDirectionEgress
)

func (TcFlowDirection) Parent

func (t TcFlowDirection) Parent() uint32

Parent() converts a TcFlowDirection() to the parent qdisc handle that must be used for a filter.

func (TcFlowDirection) String

func (t TcFlowDirection) String() string

type TcProgramType

type TcProgramType int

TcProgramType selects a way how TC program will be attached it can either be BPF_PROG_TYPE_SCHED_CLS or BPF_PROG_TYPE_SCHED_ACT

func (TcProgramType) String

func (t TcProgramType) String() string

type XdpAttachMode

type XdpAttachMode int

XdpAttachMode selects a way how XDP program will be attached to interface

const (
	// XdpAttachModeNone stands for "best effort" - kernel automatically
	// selects best mode (would try Drv first, then fallback to Generic).
	// NOTE: Kernel will not fallback to Generic XDP if NIC driver failed
	//       to install XDP program.
	XdpAttachModeNone XdpAttachMode = 0
	// XdpAttachModeSkb is "generic", kernel mode, less performant comparing to native,
	// but does not requires driver support.
	XdpAttachModeSkb XdpAttachMode = (1 << 1)
	// XdpAttachModeDrv is native, driver mode (support from driver side required)
	XdpAttachModeDrv XdpAttachMode = (1 << 2)
	// XdpAttachModeHw suitable for NICs with hardware XDP support
	XdpAttachModeHw XdpAttachMode = (1 << 3)
)

type XdpAttachParams

type XdpAttachParams struct {
	// Interface is string name of interface to attach program to
	Interface string
	// Mode is one of XdpAttachMode.
	Mode XdpAttachMode
}

XdpAttachParams used to pass parameters to Attach() call.

type XdpResult

type XdpResult int

XdpResult is eBPF program return code enum

const (
	XdpAborted  XdpResult = C.XDP_ABORTED
	XdpDrop     XdpResult = C.XDP_DROP
	XdpPass     XdpResult = C.XDP_PASS
	XdpTx       XdpResult = C.XDP_TX
	XdpRedirect XdpResult = C.XDP_REDIRECT
)

XDP program return codes

func (XdpResult) String

func (t XdpResult) String() string

Directories

Path Synopsis
examples
wrapper
Package wrapper is wrapper for "cross compiled" XDP in order to call it right from GO P.S. this should be as part of *_test.go files, however, GO does not support using import "C" from tests...
Package wrapper is wrapper for "cross compiled" XDP in order to call it right from GO P.S. this should be as part of *_test.go files, however, GO does not support using import "C" from tests...

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL