ebpf package - github.com/cilium/ebpf - Go Packages (original) (raw)

Package ebpf is a toolkit for working with eBPF programs.

eBPF programs are small snippets of code which are executed directly in a VM in the Linux kernel, which makes them very fast and flexible. Many Linux subsystems now accept eBPF programs. This makes it possible to implement highly application specific logic inside the kernel, without having to modify the actual kernel itself.

This package is designed for long-running processes which want to use eBPF to implement part of their application logic. It has no run-time dependencies outside of the library and the Linux kernel itself. eBPF code should be compiled ahead of time using clang, and shipped with your application as any other resource.

Use the link subpackage to attach a loaded program to a hook in the kernel.

Note that losing all references to Map and Program resources will cause their underlying file descriptors to be closed, potentially removing those objects from the kernel. Always retain a reference by e.g. deferring a Close() of a Collection or LoadAndAssign object until application exit.

Special care needs to be taken when handling maps of type ProgramArray, as the kernel erases its contents when the last userspace or bpffs reference disappears, regardless of the map being in active use.

ExampleMarshaler shows how to use custom encoding with map methods.

package main

import ( "encoding" "fmt" "strings" )

// Assert that customEncoding implements the correct interfaces. var ( _ encoding.BinaryMarshaler = (*customEncoding)(nil) _ encoding.BinaryUnmarshaler = (*customEncoding)(nil) )

type customEncoding struct { data string }

func (ce *customEncoding) MarshalBinary() ([]byte, error) { return []byte(strings.ToUpper(ce.data)), nil }

func (ce *customEncoding) UnmarshalBinary(buf []byte) error { ce.data = string(buf) return nil }

// ExampleMarshaler shows how to use custom encoding with map methods. func main() { hash, err := NewMap(&MapSpec{ Type: Hash, KeySize: 5, ValueSize: 4, MaxEntries: 10, }) if err != nil { panic(err) } defer hash.Close()

if err := hash.Put(&customEncoding{"hello"}, uint32(111)); err != nil {
    panic(err)
}

var (
    key     customEncoding
    value   uint32
    entries = hash.Iterate()
)

for entries.Next(&key, &value) {
    fmt.Printf("key: %s, value: %d\n", key.data, value)
}

if err := entries.Err(); err != nil {
    panic(err)
}

}

ExampleSocketELF demonstrates how to load an eBPF program from an ELF, and attach it to a raw socket.

//go:build linux

package main

import ( "bytes" "encoding/binary" "flag" "fmt" "syscall" "time" "unsafe"

"github.com/cilium/ebpf"

)

var program = [...]byte{ 0177, 0105, 0114, 0106, 0002, 0001, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0367, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0340, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0010, 0000, 0001, 0000, 0277, 0026, 0000, 0000, 0000, 0000, 0000, 0000, 0060, 0000, 0000, 0000, 0027, 0000, 0000, 0000, 0143, 0012, 0374, 0377, 0000, 0000, 0000, 0000, 0141, 0141, 0004, 0000, 0000, 0000, 0000, 0000, 0125, 0001, 0010, 0000, 0004, 0000, 0000, 0000, 0277, 0242, 0000, 0000, 0000, 0000, 0000, 0000, 0007, 0002, 0000, 0000, 0374, 0377, 0377, 0377, 0030, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0205, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0025, 0000, 0002, 0000, 0000, 0000, 0000, 0000, 0141, 0141, 0000, 0000, 0000, 0000, 0000, 0000, 0333, 0020, 0000, 0000, 0000, 0000, 0000, 0000, 0267, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0225, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0107, 0120, 0114, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0065, 0000, 0000, 0000, 0000, 0000, 0003, 0000, 0150, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0034, 0000, 0000, 0000, 0020, 0000, 0006, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0110, 0000, 0000, 0000, 0020, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0014, 0000, 0000, 0000, 0020, 0000, 0005, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0023, 0000, 0000, 0000, 0020, 0000, 0005, 0000, 0024, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0070, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0000, 0056, 0164, 0145, 0170, 0164, 0000, 0155, 0141, 0160, 0163, 0000, 0155, 0171, 0137, 0155, 0141, 0160, 0000, 0164, 0145, 0163, 0164, 0137, 0155, 0141, 0160, 0000, 0137, 0154, 0151, 0143, 0145, 0156, 0163, 0145, 0000, 0056, 0163, 0164, 0162, 0164, 0141, 0142, 0000, 0056, 0163, 0171, 0155, 0164, 0141, 0142, 0000, 0114, 0102, 0102, 0060, 0137, 0063, 0000, 0056, 0162, 0145, 0154, 0163, 0157, 0143, 0153, 0145, 0164, 0061, 0000, 0142, 0160, 0146, 0137, 0160, 0162, 0157, 0147, 0061, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0045, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0210, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0122, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0006, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0006, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0170, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0074, 0000, 0000, 0000, 0011, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0170, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0007, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0007, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0270, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0050, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0035, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0340, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0055, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0350, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0220, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0030, 0000, 0000, 0000, 0000, 0000, 0000, 0000, }

// ExampleSocketELF demonstrates how to load an eBPF program from an ELF, // and attach it to a raw socket. func main() { const SO_ATTACH_BPF = 50

index := flag.Int("index", 0, "specify ethernet index")
flag.Parse()

spec, err := ebpf.LoadCollectionSpecFromReader(bytes.NewReader(program[:]))
if err != nil {
    panic(err)
}

var objs struct {
    Prog  *ebpf.Program `ebpf:"bpf_prog1"`
    Stats *ebpf.Map     `ebpf:"my_map"`
}

if err := spec.LoadAndAssign(&objs, nil); err != nil {
    panic(err)
}
defer objs.Prog.Close()
defer objs.Stats.Close()

sock, err := openRawSock(*index)
if err != nil {
    panic(err)
}
defer syscall.Close(sock)

if err := syscall.SetsockoptInt(sock, syscall.SOL_SOCKET, SO_ATTACH_BPF, objs.Prog.FD()); err != nil {
    panic(err)
}

fmt.Printf("Filtering on eth index: %d\n", *index)
fmt.Println("Packet stats:")

for {
    const (
        ICMP = 0x01
        TCP  = 0x06
        UDP  = 0x11
    )

    time.Sleep(time.Second)
    var icmp uint64
    var tcp uint64
    var udp uint64
    err := objs.Stats.Lookup(uint32(ICMP), &icmp)
    if err != nil {
        panic(err)
    }
    err = objs.Stats.Lookup(uint32(TCP), &tcp)
    if err != nil {
        panic(err)
    }
    err = objs.Stats.Lookup(uint32(UDP), &udp)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\r\033[m\tICMP: %d TCP: %d UDP: %d", icmp, tcp, udp)
}

}

func openRawSock(index int) (int, error) { sock, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, int(htons(syscall.ETH_P_ALL))) if err != nil { return 0, err } sll := syscall.SockaddrLinklayer{ Ifindex: index, Protocol: htons(syscall.ETH_P_ALL), } if err := syscall.Bind(sock, &sll); err != nil { return 0, err } return sock, nil }

// htons converts the unsigned short integer hostshort from host byte order to network byte order. func htons(i uint16) uint16 { b := make([]byte, 2) binary.BigEndian.PutUint16(b, i) return *(*uint16)(unsafe.Pointer(&b[0])) }

eBPF program types (Linux).

Attach types (Linux).

View Source

const ( AttachWindowsXDP = AttachType(platform.WindowsTag | iota + 1) AttachWindowsBind AttachWindowsCGroupInet4Connect AttachWindowsCGroupInet6Connect AttachWindowsCgroupInet4RecvAccept AttachWindowsCgroupInet6RecvAccept AttachWindowsCGroupSockOps AttachWindowsSample AttachWindowsXDPTest )

Attach types (Windows).

See https://github.com/microsoft/ebpf-for-windows/blob/main/include/ebpf_structs.h#L260

View Source

var ( ErrKeyNotExist = errors.New("key does not exist") ErrKeyExist = errors.New("key already exists") ErrIterationAborted = errors.New("iteration aborted") ErrMapIncompatible = errors.New("map spec is incompatible with existing map") )

Errors returned by Map and MapIterator methods.

ErrInvalidType is returned when the given type cannot be used as a Memory or Variable pointer.

ErrNotSupported is returned whenever the kernel doesn't support a feature.

ErrRestrictedKernel is returned when kernel address information is restricted by kernel.kptr_restrict and/or net.core.bpf_jit_harden sysctls.

EnableStats starts collecting runtime statistics of eBPF programs, like the amount of program executions and the cumulative runtime.

Specify a BPF_STATS_* constant to select which statistics to collect, likeunix.BPF_STATS_RUN_TIME. Closing the returned io.Closer will stop collecting statistics.

Collecting statistics may have a performance impact.

Requires at least Linux 5.8.

func MustPossibleCPU() int

MustPossibleCPU is a helper that wraps a call to PossibleCPU and panics if the error is non-nil.

PossibleCPU returns the max number of CPUs a system may possibly have Logical CPU numbers must be of the form 0-n

VariablePointer returns a pointer to a variable of type T backed by memory shared with the BPF program. Requires building the Go application with -tags ebpf_unsafe_memory_experiment.

T must contain only fixed-size, non-Go-pointer types: bools, floats, (u)int[8-64], arrays, and structs containing them. Structs must embedstructs.HostLayout. ErrInvalidType is returned if T is not a valid type.

AttachFlags of the eBPF program used in BPF_PROG_ATTACH command

AttachType of the eBPF program, needed to differentiate allowed context accesses in some newer program types like CGroupSockAddr. Should be set to AttachNone if not required. Will cause invalid argument (EINVAL) at program load time if set incorrectly.

const AttachNone AttachType = 0

AttachNone is an alias for AttachCGroupInetIngress for readability reasons.

AttachTypeForPlatform returns a platform specific attach type.

Use this if the library doesn't provide a constant yet.

BatchOptions batch map operations options

Mirrors libbpf struct bpf_map_batch_opts Currently BPF_F_FLAG is the only supported flag (for ElemFlags).

Collection is a collection of live BPF resources present in the kernel.

LoadCollection reads an object file and creates and loads its declared resources into the kernel.

Omitting Collection.Close() during application shutdown is an error. See the package documentation for details around Map and Program lifecycle.

func NewCollection(spec CollectionSpec) (Collection, error)

NewCollection creates a Collection from the given spec, creating and loading its declared resources into the kernel.

Omitting Collection.Close() during application shutdown is an error. See the package documentation for details around Map and Program lifecycle.

func NewCollectionWithOptions(spec CollectionSpec, opts CollectionOptions) (Collection, error)

NewCollectionWithOptions creates a Collection from the given spec using options, creating and loading its declared resources into the kernel.

Omitting Collection.Close() during application shutdown is an error. See the package documentation for details around Map and Program lifecycle.

func (coll *Collection) Assign(to interface{}) error

Assign the contents of a Collection to a struct.

This function bridges functionality between bpf2go generated code and any functionality better implemented in Collection.

'to' must be a pointer to a struct. A field of the struct is updated with values from Programs or Maps if it has an `ebpf` tag and its type is *Program or *Map. The tag's value specifies the name of the program or map as found in the CollectionSpec.

struct { Foo *ebpf.Program ebpf:"xdp_foo" Bar *ebpf.Map ebpf:"bar_map" Ignored int }

Returns an error if any of the eBPF objects can't be found, or if the same Map or Program is assigned multiple times.

Ownership and Close()ing responsibility is transferred to `to` for any successful assigns. On error `to` is left in an undefined state.

func (coll *Collection) Close()

Close frees all maps and programs associated with the collection.

The collection mustn't be used afterwards.

func (coll *Collection) DetachMap(name string) *Map

DetachMap removes the named map from the Collection.

This means that a later call to Close() will not affect this map.

Returns nil if no map of that name exists.

func (coll *Collection) DetachProgram(name string) *Program

DetachProgram removes the named program from the Collection.

This means that a later call to Close() will not affect this program.

Returns nil if no program of that name exists.

type CollectionOptions struct { Maps MapOptions Programs ProgramOptions

MapReplacements map[[string](/builtin#string)]*[Map](#Map)

}

CollectionOptions control loading a collection into the kernel.

Maps and Programs are passed to NewMapWithOptions and NewProgramsWithOptions.

CollectionSpec describes a collection.

LoadCollectionSpec parses an ELF file into a CollectionSpec.

LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec.

func (cs *CollectionSpec) Assign(to interface{}) error

Assign the contents of a CollectionSpec to a struct.

This function is a shortcut to manually checking the presence of maps and programs in a CollectionSpec. Consider using bpf2go if this sounds useful.

'to' must be a pointer to a struct. A field of the struct is updated with values from Programs, Maps or Variables if it has an `ebpf` tag and its type is *ProgramSpec, *MapSpec or *VariableSpec. The tag's value specifies the name of the program or map as found in the CollectionSpec.

struct { Foo *ebpf.ProgramSpec ebpf:"xdp_foo" Bar *ebpf.MapSpec ebpf:"bar_map" Var *ebpf.VariableSpec ebpf:"some_var" Ignored int }

Returns an error if any of the eBPF objects can't be found, or if the same Spec is assigned multiple times.

spec := &CollectionSpec{ Maps: map[string]*MapSpec{ "map1": { Type: Array, KeySize: 4, ValueSize: 4, MaxEntries: 1, }, }, Programs: map[string]*ProgramSpec{ "prog1": { Type: SocketFilter, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), asm.Return(), }, License: "MIT", }, }, }

type maps struct { Map *MapSpec ebpf:"map1" }

var specs struct { maps Program *ProgramSpec ebpf:"prog1" }

if err := spec.Assign(&specs); err != nil { panic(err) }

fmt.Println(specs.Program.Type) fmt.Println(specs.Map.Type)

Output:

SocketFilter Array

func (cs *CollectionSpec) Copy() *CollectionSpec

Copy returns a recursive copy of the spec.

func (*CollectionSpec) LoadAndAssign

func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error

LoadAndAssign loads Maps and Programs into the kernel and assigns them to a struct.

Omitting Map/Program.Close() during application shutdown is an error. See the package documentation for details around Map and Program lifecycle.

This function is a shortcut to manually checking the presence of maps and programs in a CollectionSpec. Consider using bpf2go if this sounds useful.

'to' must be a pointer to a struct. A field of the struct is updated with a Program or Map if it has an `ebpf` tag and its type is *Program or *Map. The tag's value specifies the name of the program or map as found in the CollectionSpec. Before updating the struct, the requested objects and their dependent resources are loaded into the kernel and populated with values if specified.

struct { Foo *ebpf.Program ebpf:"xdp_foo" Bar *ebpf.Map ebpf:"bar_map" Ignored int }

opts may be nil.

Returns an error if any of the fields can't be found, or if the same Map or Program is assigned multiple times.

spec := &CollectionSpec{ Maps: map[string]*MapSpec{ "map1": { Type: Array, KeySize: 4, ValueSize: 4, MaxEntries: 1, }, }, Programs: map[string]*ProgramSpec{ "prog1": { Type: SocketFilter, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), asm.Return(), }, License: "MIT", }, }, }

var objs struct { Program *Program ebpf:"prog1" Map *Map ebpf:"map1" }

if err := spec.LoadAndAssign(&objs, nil); err != nil { panic(err) } defer objs.Program.Close() defer objs.Map.Close()

func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error

RewriteConstants replaces the value of multiple constants.

The constant must be defined like so in the C program:

volatile const type foobar; volatile const type foobar = default;

Replacement values must be of the same length as the C sizeof(type). If necessary, they are marshalled according to the same rules as map values.

From Linux 5.5 the verifier will use constants to eliminate dead code.

Returns an error wrapping MissingConstantsError if a constant doesn't exist.

Deprecated: Use [CollectionSpec.Variables] to interact with constants instead. RewriteConstants is now a wrapper around the VariableSpec API.

RewriteMaps replaces all references to specific maps.

Use this function to use pre-existing maps instead of creating new ones when calling NewCollection. Any named maps are removed from CollectionSpec.Maps.

Returns an error if a named map isn't used in at least one program.

Deprecated: Pass CollectionOptions.MapReplacements when loading the Collection instead.

type LoadPinOptions struct {

ReadOnly  [bool](/builtin#bool)
WriteOnly [bool](/builtin#bool)


Flags [uint32](/builtin#uint32)

}

LoadPinOptions control how a pinned object is loaded.

Marshal returns a value suitable for BPF_OBJ_GET syscall file_flags parameter.

LogLevel controls the verbosity of the kernel's eBPF program verifier. These constants can be used for the ProgramOptions.LogLevel field.

Map represents a Map file descriptor.

It is not safe to close a map which is used by other goroutines.

Methods which take interface{} arguments by default encode them using binary.Read/Write in the machine's native endianness.

Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler if you require custom encoding.

Per CPU maps store a distinct value for each CPU. They are useful to collect metrics.

arr, err := NewMap(&MapSpec{ Type: PerCPUArray, KeySize: 4, ValueSize: 4, MaxEntries: 2, }) if err != nil { panic(err) } defer arr.Close()

possibleCPUs := MustPossibleCPU() perCPUValues := map[uint32]uint32{ 0: 4, 1: 5, }

for k, v := range perCPUValues { // We set each perCPU slots to the same value. values := make([]uint32, possibleCPUs) for i := range values { values[i] = v } if err := arr.Put(k, values); err != nil { panic(err) } }

for k := 0; k < 2; k++ { var values []uint32 if err := arr.Lookup(uint32(k), &values); err != nil { panic(err) } // Note we will print an unexpected message if this is not true. fmt.Printf("Value of key %v on all CPUs: %v\n", k, values[0]) } var ( key uint32 entries = arr.Iterate() )

var values []uint32 for entries.Next(&key, &values) { expected, ok := perCPUValues[key] if !ok { fmt.Printf("Unexpected key %v\n", key) continue }

for i, n := range values {
    if n != expected {
        fmt.Printf("Key %v, Value for cpu %v is %v not %v\n",
            key, i, n, expected)
    }
}

}

if err := entries.Err(); err != nil { panic(err) }

It is possible to use unsafe.Pointer to avoid marshalling and copy overhead. It is the responsibility of the caller to ensure the correct size of unsafe.Pointers.

Note that using unsafe.Pointer is only marginally faster than implementing Marshaler on the type.

hash, err := NewMap(&MapSpec{ Type: Hash, KeySize: 5, ValueSize: 4, MaxEntries: 10, }) if err != nil { panic(err) } defer hash.Close()

key := [5]byte{'h', 'e', 'l', 'l', 'o'} value := uint32(23)

if err := hash.Put(unsafe.Pointer(&key), unsafe.Pointer(&value)); err != nil { panic(err) }

value = 0 if err := hash.Lookup(unsafe.Pointer(&key), unsafe.Pointer(&value)); err != nil { panic("can't get value:" + err.Error()) }

fmt.Printf("The value is: %d\n", value)

LoadPinnedMap opens a Map from a pin (file) on the BPF virtual filesystem.

Requires at least Linux 4.5.

func NewMap(spec MapSpec) (Map, error)

NewMap creates a new Map.

It's equivalent to calling NewMapWithOptions with default options.

NewMapFromFD creates a Map around a raw fd.

You should not use fd after calling this function.

Requires at least Linux 4.13.

func NewMapFromID(id MapID) (*Map, error)

NewMapFromID returns the Map for a given map id. Returns [ErrNotExist] if there is no eBPF map with the given id.

Requires at least Linux 4.13.

func NewMapWithOptions(spec MapSpec, opts MapOptions) (Map, error)

NewMapWithOptions creates a new Map.

Creating a map for the first time will perform feature detection by creating small, temporary maps.

The caller is responsible for ensuring the process' rlimit is set sufficiently high for locking memory during map creation. This can be done by calling rlimit.RemoveMemlock() prior to calling NewMapWithOptions.

May return an error wrapping ErrMapIncompatible.

func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error)

BatchDelete batch deletes entries in the map by keys. "keys" must be of type slice, a pointer to a slice or buffer will not work.

func (m *Map) BatchLookup(cursor *MapBatchCursor, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error)

BatchLookup looks up many elements in a map at once.

"keysOut" and "valuesOut" must be of type slice, a pointer to a slice or buffer will not work. "cursor" is an pointer to an opaque handle. It must be non-nil. Pass "cursor" to subsequent calls of this function to continue the batching operation in the case of chunking.

Warning: This API is not very safe to use as the kernel implementation for batching relies on the user to be aware of subtle details with regarding to different map type implementations.

ErrKeyNotExist is returned when the batch lookup has reached the end of all possible results, even when partial results are returned. It should be used to evaluate when lookup is "done".

func (*Map) BatchLookupAndDelete added in v0.4.0

func (m *Map) BatchLookupAndDelete(cursor *MapBatchCursor, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error)

BatchLookupAndDelete looks up many elements in a map at once,

It then deletes all those elements. "keysOut" and "valuesOut" must be of type slice, a pointer to a slice or buffer will not work. "cursor" is an pointer to an opaque handle. It must be non-nil. Pass "cursor" to subsequent calls of this function to continue the batching operation in the case of chunking.

Warning: This API is not very safe to use as the kernel implementation for batching relies on the user to be aware of subtle details with regarding to different map type implementations.

ErrKeyNotExist is returned when the batch lookup has reached the end of all possible results, even when partial results are returned. It should be used to evaluate when lookup is "done".

func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error)

BatchUpdate updates the map with multiple keys and values simultaneously. "keys" and "values" must be of type slice, a pointer to a slice or buffer will not work.

func (m Map) Clone() (Map, error)

Clone creates a duplicate of the Map.

Closing the duplicate does not affect the original, and vice versa. Changes made to the map are reflected by both instances however. If the original map was pinned, the cloned map will not be pinned by default.

Cloning a nil Map returns nil.

Close the Map's underlying file descriptor, which could unload the Map from the kernel if it is not pinned or in use by a loaded Program.

func (m *Map) Delete(key interface{}) error

Delete removes a value.

Returns ErrKeyNotExist if the key does not exist.

FD gets the file descriptor of the Map.

Calling this function is invalid after Close has been called.

Flags returns the flags of the map.

Freeze prevents a map to be modified from user space.

It makes no changes to kernel-side restrictions.

func (*Map) Handle added in v0.16.0

Handle returns a reference to the Map's type information in the kernel.

Returns ErrNotSupported if the kernel has no BTF support, or if there is no BTF associated with the Map.

Info returns metadata about the map. This was first introduced in Linux 4.5, but newer kernels support more MapInfo fields with the introduction of more features. See MapInfo and its methods for more details.

Returns an error wrapping ErrNotSupported if the kernel supports neither BPF_OBJ_GET_INFO_BY_FD nor reading map information from /proc/self/fdinfo.

func (m *Map) IsPinned() bool

IsPinned returns true if the map has a non-empty pinned path.

func (m *Map) Iterate() *MapIterator

Iterate traverses a map.

It's safe to create multiple iterators at the same time.

It's not possible to guarantee that all keys in a map will be returned if there are concurrent modifications to the map.

ExampleMap_Iterate demonstrates how to iterate over all entries in a map.

hash, err := NewMap(&MapSpec{ Type: Hash, KeySize: 5, ValueSize: 4, MaxEntries: 10, Contents: []MapKV{ {"hello", uint32(21)}, {"world", uint32(42)}, }, }) if err != nil { panic(err) } defer hash.Close()

var ( key string value uint32 entries = hash.Iterate() )

values := make(map[string]uint32) for entries.Next(&key, &value) { // Order of keys is non-deterministic due to randomized map seed values[key] = value }

if err := entries.Err(); err != nil { panic(fmt.Sprint("Iterator encountered an error:", err)) }

for k, v := range values { fmt.Printf("key: %s, value: %d\n", k, v) }

It is possible to iterate nested maps and program arrays by unmarshaling into a *Map or *Program.

inner := &MapSpec{ Type: Array, KeySize: 4, ValueSize: 4, MaxEntries: 2, Contents: []MapKV{ {uint32(0), uint32(1)}, {uint32(1), uint32(2)}, }, } im, err := NewMap(inner) if err != nil { panic(err) } defer im.Close()

outer := &MapSpec{ Type: ArrayOfMaps, InnerMap: inner, KeySize: 4, ValueSize: 4, MaxEntries: 10, Contents: []MapKV{ {uint32(0), im}, }, } arrayOfMaps, err := NewMap(outer) if errors.Is(err, internal.ErrNotSupported) { // Fake the output if on very old kernel. fmt.Println("outerKey: 0") fmt.Println("\tinnerKey 0 innerValue 1") fmt.Println("\tinnerKey 1 innerValue 2") return } if err != nil { panic(err) } defer arrayOfMaps.Close()

var ( key uint32 m *Map entries = arrayOfMaps.Iterate() ) for entries.Next(&key, &m) { // Make sure that the iterated map is closed after // we are done. defer m.Close()

// Order of keys is non-deterministic due to randomized map seed
fmt.Printf("outerKey: %v\n", key)

var innerKey, innerValue uint32
items := m.Iterate()
for items.Next(&innerKey, &innerValue) {
    fmt.Printf("\tinnerKey %v innerValue %v\n", innerKey, innerValue)
}
if err := items.Err(); err != nil {
    panic(fmt.Sprint("Inner Iterator encountered an error:", err))
}

}

if err := entries.Err(); err != nil { panic(fmt.Sprint("Iterator encountered an error:", err)) }

KeySize returns the size of the map key in bytes.

func (m *Map) Lookup(key, valueOut interface{}) error

Lookup retrieves a value from a Map.

Calls Close() on valueOut if it is of type **Map or **Program, and *valueOut is not nil.

Returns an error if the key doesn't exist, see ErrKeyNotExist.

func (*Map) LookupAndDelete

func (m *Map) LookupAndDelete(key, valueOut interface{}) error

LookupAndDelete retrieves and deletes a value from a Map.

Returns ErrKeyNotExist if the key doesn't exist.

func (*Map) LookupAndDeleteWithFlags added in v0.8.0

func (m *Map) LookupAndDeleteWithFlags(key, valueOut interface{}, flags MapLookupFlags) error

LookupAndDeleteWithFlags retrieves and deletes a value from a Map.

Passing LookupLock flag will look up and delete the value of a spin-locked map without returning the lock. This must be specified if the elements contain a spinlock.

Returns ErrKeyNotExist if the key doesn't exist.

func (m *Map) LookupBytes(key interface{}) ([]byte, error)

LookupBytes gets a value from Map.

Returns a nil value if a key doesn't exist.

func (m *Map) LookupWithFlags(key, valueOut interface{}, flags MapLookupFlags) error

LookupWithFlags retrieves a value from a Map with flags.

Passing LookupLock flag will look up the value of a spin-locked map without returning the lock. This must be specified if the elements contain a spinlock.

Calls Close() on valueOut if it is of type **Map or **Program, and *valueOut is not nil.

Returns an error if the key doesn't exist, see ErrKeyNotExist.

MaxEntries returns the maximum number of elements the map can hold.

func (m Map) Memory() (Memory, error)

Memory returns a memory-mapped region for the Map. The Map must have been created with the BPF_F_MMAPABLE flag. Repeated calls to Memory return the same mapping. Callers are responsible for coordinating access to Memory.

func (m *Map) NextKey(key, nextKeyOut interface{}) error

NextKey finds the key following an initial key.

See NextKeyBytes for details.

Returns ErrKeyNotExist if there is no next key.

hash, err := NewMap(&MapSpec{ Type: Hash, KeySize: 5, ValueSize: 4, MaxEntries: 10, Contents: []MapKV{ {"hello", uint32(21)}, {"world", uint32(42)}, }, }) if err != nil { panic(err) } defer hash.Close()

var cur, next string var keys []string

for err = hash.NextKey(nil, &next); ; err = hash.NextKey(cur, &next) { if errors.Is(err, ErrKeyNotExist) { break } if err != nil { panic(err) } keys = append(keys, next) cur = next }

// Order of keys is non-deterministic due to randomized map seed sort.Strings(keys) fmt.Printf("Keys are %v\n", keys)

func (m *Map) NextKeyBytes(key interface{}) ([]byte, error)

NextKeyBytes returns the key following an initial key as a byte slice.

Passing nil will return the first key.

Use Iterate if you want to traverse all entries in the map.

Returns nil if there are no more keys.

func (m *Map) Put(key, value interface{}) error

Put replaces or creates a value in map.

It is equivalent to calling Update with UpdateAny.

func (m *Map) Type() MapType

Type returns the underlying type of the map.

Unpin removes the persisted state for the map from the BPF virtual filesystem.

Failed calls to Unpin will not alter the state returned by IsPinned.

Unpinning an unpinned Map returns nil.

Update changes the value of a key.

ValueSize returns the size of the map value in bytes.

type MapBatchCursor struct {

}

MapBatchCursor represents a starting point for a batch operation.

MapID represents the unique ID of an eBPF map

func MapGetNextID(startID MapID) (MapID, error)

MapGetNextID returns the ID of the next eBPF map.

Returns ErrNotExist, if there is no next eBPF map.

MapInfo describes a map.

BTFID returns the BTF ID associated with the Map.

The ID is only valid as long as the associated Map is kept alive. Available from 4.18.

The bool return value indicates whether this optional field is available and populated. (The field may be available but not populated if the kernel supports the field but the Map was loaded without BTF information.)

func (mi *MapInfo) Frozen() bool

Frozen indicates whether Map.Freeze was called on this map. If true, modifications from user space are not allowed.

Available from 5.2. Requires access to procfs.

If the kernel doesn't support map freezing, this field will always be false.

ID returns the map ID.

Available from 4.13.

The bool return value indicates whether this optional field is available.

MapExtra returns an opaque field whose meaning is map-specific.

Available from 5.16.

The bool return value indicates whether this optional field is available and populated, if it was specified during Map creation.

Memlock returns an approximate number of bytes allocated to this map.

Available from 4.10.

The bool return value indicates whether this optional field is available.

type MapIterator struct {

}

MapIterator iterates a Map.

See Map.Iterate.

Err returns any encountered error.

The method must be called after Next returns nil.

Returns ErrIterationAborted if it wasn't possible to do a full iteration.

func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool

Next decodes the next key and value.

Iterating a hash map from which keys are being deleted is not safe. You may see the same key multiple times. Iteration may also abort with an error, see IsIterationAborted.

Returns false if there are no more entries. You must check the result of Err afterwards.

See Map.Get for further caveats around valueOut.

type MapKV struct { Key interface{} Value interface{} }

MapKV is used to initialize the contents of a Map.

MapLookupFlags controls the behaviour of the map lookup calls.

LookupLock look up the value of a spin-locked map.

type MapOptions struct {

PinPath        [string](/builtin#string)
LoadPinOptions [LoadPinOptions](#LoadPinOptions)

}

MapOptions control loading a map into the kernel.

MapSpec defines a Map.

func (ms *MapSpec) Compatible(m *Map) error

Compatible returns nil if an existing map may be used instead of creating one from the spec.

Returns an error wrapping ErrMapIncompatible otherwise.

func (ms *MapSpec) Copy() *MapSpec

Copy returns a copy of the spec.

MapSpec.Contents is a shallow copy.

MapType indicates the type map structure that will be initialized in the kernel.

const ( UnspecifiedMap MapType = MapType(platform.LinuxTag | iota)

Hash

Array


ProgramArray


PerfEventArray


PerCPUHash


PerCPUArray


StackTrace


CGroupArray


LRUHash


LRUCPUHash


LPMTrie


ArrayOfMaps


HashOfMaps

DevMap

SockMap

CPUMap

XSKMap

SockHash

CGroupStorage

ReusePortSockArray

PerCPUCGroupStorage

Queue

Stack

SkStorage

DevMapHash


StructOpsMap

RingBuf

InodeStorage

TaskStorage

BloomFilter

UserRingbuf

CgroupStorage

Arena

)

All the various map types that can be created

const ( WindowsHash MapType = MapType(platform.WindowsTag | iota + 1) WindowsArray WindowsProgramArray WindowsPerCPUHash WindowsPerCPUArray WindowsHashOfMaps WindowsArrayOfMaps WindowsLRUHash WindowsLPMTrie WindowsQueue WindowsLRUCPUHash WindowsStack WindowsRingBuf )

Map types (Windows).

MapTypeForPlatform returns a platform specific map type.

Use this if the library doesn't provide a constant yet.

MapUpdateFlags controls the behaviour of the Map.Update call.

The exact semantics depend on the specific MapType.

const (

UpdateAny [MapUpdateFlags](#MapUpdateFlags) = [iota](/builtin#iota)

UpdateNoExist [MapUpdateFlags](#MapUpdateFlags) = 1 << ([iota](/builtin#iota) - 1)

UpdateExist

UpdateLock

)

Memory implements accessing a Map's memory without making any syscalls. Pay attention to the difference between Go and C struct alignment rules. Usestructs.HostLayout on supported Go versions to help with alignment.

Note on memory coherence: avoid using packed structs in memory shared between user space and eBPF C programs. This drops a struct's memory alignment to 1, forcing the compiler to use single-byte loads and stores for field accesses. This may lead to partially-written data to be observed from user space.

On most architectures, the memmove implementation used by Go's copy() will access data in word-sized chunks. If paired with a matching access pattern on the eBPF C side (and if using default memory alignment), accessing shared memory without atomics or other synchronization primitives should be sound for individual values. For accesses beyond a single value, the usual concurrent programming rules apply.

func (mm *Memory) ReadOnly() bool

ReadOnly returns true if the memory-mapped region is read-only.

func (mm *Memory) Size() int

Size returns the size of the memory-mapped region in bytes.

type MissingConstantsError struct {

Constants [][string](/builtin#string)

}

MissingConstantsError is returned by CollectionSpec.RewriteConstants.

PinType determines whether a map is pinned into a BPFFS.

const ( PinNone PinType = iota

PinByName

)

Valid pin types.

Mirrors enum libbpf_pin_type.

type Program struct {

VerifierLog [string](/builtin#string)

}

Program represents BPF program loaded into the kernel.

It is not safe to close a Program which is used by other goroutines.

Use NewProgramWithOptions if you'd like to get the verifier output for a program, or if you want to change the buffer size used when generating error messages.

spec := &ProgramSpec{ Type: SocketFilter, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), asm.Return(), }, License: "MIT", }

prog, err := NewProgramWithOptions(spec, ProgramOptions{ LogLevel: LogLevelInstruction, }) if err != nil { panic(err) } defer prog.Close()

fmt.Println("The verifier output is:") fmt.Println(prog.VerifierLog)

It's possible to read a program directly from a ProgramArray.

progArray, err := LoadPinnedMap("/path/to/map", nil) if err != nil { panic(err) } defer progArray.Close()

// Load a single program var prog *Program if err := progArray.Lookup(uint32(0), &prog); err != nil { panic(err) } defer prog.Close()

fmt.Println("first prog:", prog)

// Iterate all programs var ( key uint32 entries = progArray.Iterate() )

for entries.Next(&key, &prog) { fmt.Println(key, "is", prog) }

if err := entries.Err(); err != nil { panic(err) }

LoadPinnedProgram loads a Program from a pin (file) on the BPF virtual filesystem.

Requires at least Linux 4.11.

func NewProgram(spec ProgramSpec) (Program, error)

NewProgram creates a new Program.

See NewProgramWithOptions for details.

Returns a VerifierError containing the full verifier log if the program is rejected by the kernel.

NewProgramFromFD creates a Program around a raw fd.

You should not use fd after calling this function.

Requires at least Linux 4.13. Returns an error on Windows.

func NewProgramFromID(id ProgramID) (*Program, error)

NewProgramFromID returns the Program for a given program id. Returns [ErrNotExist] if there is no eBPF program with the given id.

Requires at least Linux 4.13.

func NewProgramWithOptions(spec ProgramSpec, opts ProgramOptions) (Program, error)

NewProgramWithOptions creates a new Program.

Loading a program for the first time will perform feature detection by loading small, temporary programs.

Returns a VerifierError containing the full verifier log if the program is rejected by the kernel.

Benchmark runs the Program with the given input for a number of times and returns the time taken per iteration.

Returns the result of the last execution of the program and the time per run or an error. reset is called whenever the benchmark syscall is interrupted, and should be set to testing.B.ResetTimer or similar.

This function requires at least Linux 4.12.

BindMap binds map to the program and is only released once program is released.

This may be used in cases where metadata should be associated with the program which otherwise does not contain any references to the map.

Clone creates a duplicate of the Program.

Closing the duplicate does not affect the original, and vice versa.

Cloning a nil Program returns nil.

Close the Program's underlying file descriptor, which could unload the program from the kernel if it is not pinned or attached to a kernel hook.

func (p *Program) FD() int

FD gets the file descriptor of the Program.

It is invalid to call this function after Close has been called.

func (*Program) Handle added in v0.9.1

Handle returns a reference to the program's type information in the kernel.

Returns ErrNotSupported if the kernel has no BTF support, or if there is no BTF associated with the program.

Info returns metadata about the program.

Requires at least 4.10.

func (p *Program) IsPinned() bool

IsPinned returns true if the Program has a non-empty pinned path.

Run runs the Program in kernel with given RunOptions.

Note: the same restrictions from Test apply.

Stats returns runtime statistics about the Program. Requires BPF statistics collection to be enabled, see EnableStats.

Requires at least Linux 5.8.

Test runs the Program in the kernel with the given input and returns the value returned by the eBPF program.

Note: the kernel expects at least 14 bytes input for an ethernet header for XDP and SKB programs.

This function requires at least Linux 4.12.

func (p *Program) Type() ProgramType

Type returns the underlying type of the program.

Unpin removes the persisted state for the Program from the BPF virtual filesystem.

Failed calls to Unpin will not alter the state returned by IsPinned.

Unpinning an unpinned Program returns nil.

ProgramID represents the unique ID of an eBPF program.

func ProgramGetNextID(startID ProgramID) (ProgramID, error)

ProgramGetNextID returns the ID of the next eBPF program.

Returns ErrNotExist, if there is no next eBPF program.

ProgramInfo describes a Program's immutable metadata. For runtime statistics, see ProgramStats.

BTFID returns the BTF ID associated with the program.

The ID is only valid as long as the associated program is kept alive. Available from 5.0.

The bool return value indicates whether this optional field is available and populated. (The field may be available but not populated if the kernel supports the field but the program was loaded without BTF information.)

CreatedByUID returns the Uid that created the program.

Available from 4.15.

The bool return value indicates whether this optional field is available.

FuncInfos returns the offset and function information of all (sub)programs in a BPF program.

Available from 5.0.

Returns an error wrapping ErrRestrictedKernel if function information is restricted by sysctls.

Requires CAP_SYS_ADMIN or equivalent for reading BTF information. Returns ErrNotSupported if the program was created without BTF or if the kernel doesn't support the field.

ID returns the program ID.

Available from 4.13.

The bool return value indicates whether this optional field is available.

Instructions returns the 'xlated' instruction stream of the program after it has been verified and rewritten by the kernel. These instructions cannot be loaded back into the kernel as-is, this is mainly used for inspecting loaded programs for troubleshooting, dumping, etc.

For example, map accesses are made to reference their kernel map IDs, not the FDs they had when the program was inserted. Note that before the introduction of bpf_insn_prepare_dump in kernel 4.16, xlated instructions were not sanitized, making the output even less reusable and less likely to round-trip or evaluate to the same program Tag.

The first instruction is marked as a symbol using the Program's name.

If available, the instructions will be annotated with metadata from the BTF. This includes line information and function information. Reading this metadata requires CAP_SYS_ADMIN or equivalent. If capability is unavailable, the instructions will be returned without metadata.

Returns an error wrapping ErrRestrictedKernel if instructions are restricted by sysctls.

Available from 4.13. Requires CAP_BPF or equivalent for plain instructions. Requires CAP_SYS_ADMIN for instructions with metadata.

JitedFuncLens returns the insns length of each function in the JITed program.

Available from 4.18.

The bool return value indicates whether this optional field is available.

JitedInsns returns the JITed machine native instructions of the program.

Available from 4.13.

The bool return value indicates whether this optional field is available.

JitedKsymAddrs returns the ksym addresses of the BPF program, including its subprograms. The addresses correspond to their symbols in /proc/kallsyms.

Available from 4.18. Note that before 5.x, this field can be empty for programs without subprograms (bpf2bpf calls).

The bool return value indicates whether this optional field is available.

When a kernel address can't fit into uintptr (which is usually the case when running 32 bit program on a 64 bit kernel), this returns an empty slice and a false.

JitedLineInfos returns the JITed line infos of the program.

Available from 5.0.

The bool return value indicates whether this optional field is available.

JitedSize returns the size of the program's JIT-compiled machine code in bytes, which is the actual code executed on the host's CPU. This field requires the BPF JIT compiler to be enabled.

Returns an error wrapping ErrRestrictedKernel if jited program size is restricted by sysctls.

Available from 4.13. Reading this metadata requires CAP_BPF or equivalent.

LineInfos returns the BTF line information of the program.

Available from 5.0.

Returns an error wrapping ErrRestrictedKernel if line infos are restricted by sysctls.

Requires CAP_SYS_ADMIN or equivalent for reading BTF information. Returns ErrNotSupported if the program was created without BTF or if the kernel doesn't support the field.

LoadTime returns when the program was loaded since boot time.

Available from 4.15.

The bool return value indicates whether this optional field is available.

func (pi *ProgramInfo) MapIDs() ([]MapID, bool)

MapIDs returns the maps related to the program.

Available from 4.15.

The bool return value indicates whether this optional field is available.

ProgramInfo returns an approximate number of bytes allocated to this program.

Available from 4.10.

The bool return value indicates whether this optional field is available.

TranslatedSize returns the size of the program's translated instructions in bytes, after it has been verified and rewritten by the kernel.

Returns an error wrapping ErrRestrictedKernel if translated instructions are restricted by sysctls.

Available from 4.13. Reading this metadata requires CAP_BPF or equivalent.

VerifiedInstructions returns the number verified instructions in the program.

Available from 5.16.

The bool return value indicates whether this optional field is available.

type ProgramOptions struct {

LogLevel [LogLevel](#LogLevel)


LogSizeStart [uint32](/builtin#uint32)


LogDisabled [bool](/builtin#bool)


KernelTypes *[btf](/github.com/cilium/ebpf@v0.20.0/btf).[Spec](/github.com/cilium/ebpf@v0.20.0/btf#Spec)


ExtraRelocationTargets []*[btf](/github.com/cilium/ebpf@v0.20.0/btf).[Spec](/github.com/cilium/ebpf@v0.20.0/btf#Spec)

}

ProgramOptions control loading a program into the kernel.

ProgramSpec defines a Program.

func (ps *ProgramSpec) Copy() *ProgramSpec

Copy returns a copy of the spec.

Tag calculates the kernel tag for a series of instructions.

Use asm.Instructions.Tag if you need to calculate for non-native endianness.

spec := &ProgramSpec{ Type: SocketFilter, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), asm.Return(), }, License: "MIT", }

prog, _ := NewProgram(spec) info, _ := prog.Info() tag, _ := spec.Tag()

if info.Tag != tag { fmt.Printf("The tags don't match: %s != %s\n", info.Tag, tag) } else { fmt.Println("The programs are identical, tag is", tag) }

ProgramStats contains runtime statistics for a single Program, returned byProgram.Stats.

Will contain mostly zero values if the collection of statistics is not enabled, see EnableStats.

ProgramType of the eBPF program

ProgramTypeForPlatform returns a platform specific program type.

Use this if the library doesn't provide a constant yet.

type RunOptions struct {

Data [][byte](/builtin#byte)

DataOut [][byte](/builtin#byte)

Context interface{}

ContextOut interface{}


Repeat [uint32](/builtin#uint32)

Flags [uint32](/builtin#uint32)


CPU [uint32](/builtin#uint32)


Reset func()

}

Various options for Run'ing a Program

Variable is a convenience wrapper for modifying global variables of a Collection after loading it into the kernel. Operations on a Variable are performed using direct memory access, bypassing the BPF map syscall API.

On kernels older than 5.5, most interactions with Variable returnErrNotSupported.

Get writes the value of the Variable to the provided output. The output must be a pointer to a value whose size matches the Variable.

func (v *Variable) ReadOnly() bool

ReadOnly returns true if the Variable represents a variable that is read-only after loading the Collection into the kernel.

On systems without BPF_F_MMAPABLE support, ReadOnly always returns true.

Set the value of the Variable to the provided input. The input must marshal to the same length as the size of the Variable.

Size returns the size of the variable.

Type returns the btf.Var representing the variable in its data section. This is useful for inspecting the variable's decl tags and the type information of the inner type.

Returns nil if the original ELF object did not contain BTF information.

type VariableSpec struct {

}

VariableSpec is a convenience wrapper for modifying global variables of a CollectionSpec before loading it into the kernel.

All operations on a VariableSpec's underlying MapSpec are performed in the host's native endianness.

func (s *VariableSpec) Constant() bool

Constant returns true if the VariableSpec represents a variable that is read-only from the perspective of the BPF program.

Get writes the value of the VariableSpec to the provided output using the host's native endianness.

MapName returns the name of the underlying MapSpec.

Offset returns the offset of the variable in the underlying MapSpec.

Set sets the value of the VariableSpec to the provided input using the host's native endianness.

Size returns the size of the variable in bytes.

Type returns the btf.Var representing the variable in its data section. This is useful for inspecting the variable's decl tags and the type information of the inner type.

Returns nil if the original ELF object did not contain BTF information.

VerifierError is returned by NewProgram and NewProgramWithOptions if a program is rejected by the verifier.

Use errors.As to access the error.

VerifierLog understands a variety of formatting flags.

err := internal.ErrorWithLog( "catastrophe", syscall.ENOSPC, []byte("first\nsecond\nthird"), )

fmt.Printf("With %%s: %s\n", err) fmt.Printf("All log lines: %+v\n", err) fmt.Printf("First line: %+1v\n", err) fmt.Printf("Last two lines: %-2v\n", err)

Output:

With %s: catastrophe: no space left on device: third (2 line(s) omitted) All log lines: catastrophe: no space left on device: first second third First line: catastrophe: no space left on device: first (2 line(s) omitted) Last two lines: catastrophe: no space left on device: (1 line(s) omitted) second third

Print the full verifier log when loading a program fails.

_, err := NewProgram(&ProgramSpec{ Type: SocketFilter, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), // Missing Return }, License: "MIT", })

var ve *VerifierError if errors.As(err, &ve) { // Using %+v will print the whole verifier error, not just the last // few lines. fmt.Printf("Verifier error: %+v\n", ve) }