Documentation ¶
Overview ¶
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.
Example (CustomMarshaler) ¶
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 := createHash() 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) } }
Output: key: HELLO, value: 111
Example (ExtractDistance) ¶
ExampleExtractDistance shows how to attach an eBPF socket filter to extract the network distance of an IP host.
package main // This code is derived from https://github.com/cloudflare/cloudflare-blog/tree/master/2018-03-ebpf // // Copyright (c) 2015-2017 Cloudflare, Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of the Cloudflare, Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import ( "fmt" "net" "syscall" "github.com/cilium/ebpf" "github.com/cilium/ebpf/asm" ) // ExampleExtractDistance shows how to attach an eBPF socket filter to // extract the network distance of an IP host. func main() { filter, TTLs, err := newDistanceFilter() if err != nil { panic(err) } defer filter.Close() defer TTLs.Close() // Attach filter before the call to connect() dialer := net.Dialer{ Control: func(network, address string, c syscall.RawConn) (err error) { const SO_ATTACH_BPF = 50 err = c.Control(func(fd uintptr) { err = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, SO_ATTACH_BPF, filter.FD()) }) return err }, } conn, err := dialer.Dial("tcp", "1.1.1.1:53") if err != nil { panic(err) } conn.Close() minDist, err := minDistance(TTLs) if err != nil { panic(err) } fmt.Println("1.1.1.1:53 is", minDist, "hops away") } func newDistanceFilter() (*ebpf.Program, *ebpf.Map, error) { const ETH_P_IPV6 uint16 = 0x86DD ttls, err := ebpf.NewMap(&ebpf.MapSpec{ Type: ebpf.Hash, KeySize: 4, ValueSize: 8, MaxEntries: 4, }) if err != nil { return nil, nil, err } insns := asm.Instructions{ // r1 has ctx // r0 = ctx[16] (aka protocol) asm.LoadMem(asm.R0, asm.R1, 16, asm.Word), // Perhaps ipv6 asm.LoadImm(asm.R2, int64(ETH_P_IPV6), asm.DWord), asm.HostTo(asm.BE, asm.R2, asm.Half), asm.JEq.Reg(asm.R0, asm.R2, "ipv6"), // otherwise assume ipv4 // 8th byte in IPv4 is TTL // LDABS requires ctx in R6 asm.Mov.Reg(asm.R6, asm.R1), asm.LoadAbs(-0x100000+8, asm.Byte), asm.Ja.Label("store-ttl"), // 7th byte in IPv6 is Hop count // LDABS requires ctx in R6 asm.Mov.Reg(asm.R6, asm.R1).Sym("ipv6"), asm.LoadAbs(-0x100000+7, asm.Byte), // stash the load result into FP[-4] asm.StoreMem(asm.RFP, -4, asm.R0, asm.Word).Sym("store-ttl"), // stash the &FP[-4] into r2 asm.Mov.Reg(asm.R2, asm.RFP), asm.Add.Imm(asm.R2, -4), // r1 must point to map asm.LoadMapPtr(asm.R1, ttls.FD()), asm.FnMapLookupElem.Call(), // load ok? inc. Otherwise? jmp to mapupdate asm.JEq.Imm(asm.R0, 0, "update-map"), asm.Mov.Imm(asm.R1, 1), asm.StoreXAdd(asm.R0, asm.R1, asm.DWord), asm.Ja.Label("exit"), // MapUpdate // r1 has map ptr asm.LoadMapPtr(asm.R1, ttls.FD()).Sym("update-map"), // r2 has key -> &FP[-4] asm.Mov.Reg(asm.R2, asm.RFP), asm.Add.Imm(asm.R2, -4), // r3 has value -> &FP[-16] , aka 1 asm.StoreImm(asm.RFP, -16, 1, asm.DWord), asm.Mov.Reg(asm.R3, asm.RFP), asm.Add.Imm(asm.R3, -16), // r4 has flags, 0 asm.Mov.Imm(asm.R4, 0), asm.FnMapUpdateElem.Call(), // set exit code to -1, don't trunc packet asm.Mov.Imm(asm.R0, -1).Sym("exit"), asm.Return(), } prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ Name: "distance_filter", Type: ebpf.SocketFilter, License: "GPL", Instructions: insns, }) if err != nil { ttls.Close() return nil, nil, err } return prog, ttls, nil } func minDistance(TTLs *ebpf.Map) (int, error) { var ( entries = TTLs.Iterate() ttl uint32 minDist uint32 = 255 count uint64 ) for entries.Next(&ttl, &count) { var dist uint32 switch { case ttl > 128: dist = 255 - ttl case ttl > 64: dist = 128 - ttl case ttl > 32: dist = 64 - ttl default: dist = 32 - ttl } if minDist > dist { minDist = dist } } return int(minDist), entries.Err() }
Output:
Example (SocketELF) ¶
ExampleSocketELF demonstrates how to load an eBPF program from an ELF, and attach it to a raw socket.
//go:build linux // +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])) }
Output:
Index ¶
- Constants
- Variables
- func EnableStats(which uint32) (io.Closer, error)
- func SanitizeName(name string, replacement rune) string
- type AttachFlags
- type AttachType
- type BatchOptions
- type Collection
- type CollectionOptions
- type CollectionSpec
- func (cs *CollectionSpec) Assign(to interface{}) error
- func (cs *CollectionSpec) Copy() *CollectionSpec
- func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error
- func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
- func (cs *CollectionSpec) RewriteMaps(maps map[string]*Map) error
- type LoadPinOptions
- type Map
- func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error)
- func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error)
- func (m *Map) BatchLookupAndDelete(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error)
- func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error)
- func (m *Map) Clone() (*Map, error)
- func (m *Map) Close() error
- func (m *Map) Delete(key interface{}) error
- func (m *Map) FD() int
- func (m *Map) Flags() uint32
- func (m *Map) Freeze() error
- func (m *Map) ID() (MapID, error)deprecated
- func (m *Map) Info() (*MapInfo, error)
- func (m *Map) IsPinned() bool
- func (m *Map) Iterate() *MapIterator
- func (m *Map) KeySize() uint32
- func (m *Map) Lookup(key, valueOut interface{}) error
- func (m *Map) LookupAndDelete(key, valueOut interface{}) error
- func (m *Map) LookupBytes(key interface{}) ([]byte, error)
- func (m *Map) MaxEntries() uint32
- func (m *Map) NextKey(key, nextKeyOut interface{}) error
- func (m *Map) NextKeyBytes(key interface{}) ([]byte, error)
- func (m *Map) Pin(fileName string) error
- func (m *Map) Put(key, value interface{}) error
- func (m *Map) String() string
- func (m *Map) Type() MapType
- func (m *Map) Unpin() error
- func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error
- func (m *Map) ValueSize() uint32
- type MapID
- type MapInfo
- type MapIterator
- type MapKV
- type MapOptions
- type MapSpec
- type MapType
- type MapUpdateFlags
- type PinType
- type Program
- func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error)
- func NewProgram(spec *ProgramSpec) (*Program, error)
- func NewProgramFromFD(fd int) (*Program, error)
- func NewProgramFromID(id ProgramID) (*Program, error)
- func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error)
- func (p *Program) Attach(fd int, typ AttachType, flags AttachFlags) errordeprecated
- func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.Duration, error)
- func (p *Program) Clone() (*Program, error)
- func (p *Program) Close() error
- func (p *Program) Detach(fd int, typ AttachType, flags AttachFlags) errordeprecated
- func (p *Program) FD() int
- func (p *Program) ID() (ProgramID, error)deprecated
- func (p *Program) Info() (*ProgramInfo, error)
- func (p *Program) IsPinned() bool
- func (p *Program) Pin(fileName string) error
- func (p *Program) String() string
- func (p *Program) Test(in []byte) (uint32, []byte, error)
- func (p *Program) Type() ProgramType
- func (p *Program) Unpin() error
- type ProgramID
- type ProgramInfo
- type ProgramOptions
- type ProgramSpec
- type ProgramType
Examples ¶
Constants ¶
const DefaultVerifierLogSize = 64 * 1024
DefaultVerifierLogSize is the default number of bytes allocated for the verifier log.
Variables ¶
var ( ErrKeyNotExist = errors.New("key does not exist") ErrKeyExist = errors.New("key already exists") ErrIterationAborted = errors.New("iteration aborted") ErrMapIncompatible = errors.New("map's spec is incompatible with pinned map") )
Errors returned by Map and MapIterator methods.
var ErrNotExist = os.ErrNotExist
ErrNotExist is returned when loading a non-existing map or program.
Deprecated: use os.ErrNotExist instead.
var ErrNotSupported = internal.ErrNotSupported
ErrNotSupported is returned whenever the kernel doesn't support a feature.
Functions ¶
func EnableStats ¶ added in v0.4.0
EnableStats starts the measuring of the runtime and run counts of eBPF programs.
Collecting statistics can have an impact on the performance.
Requires at least 5.8.
func SanitizeName ¶
SanitizeName replaces all invalid characters in name with replacement. Passing a negative value for replacement will delete characters instead of replacing them. Use this to automatically generate valid names for maps and programs at runtime.
The set of allowed characters depends on the running kernel version. Dots are only allowed as of kernel 5.2.
Types ¶
type AttachFlags ¶
type AttachFlags uint32
AttachFlags of the eBPF program used in BPF_PROG_ATTACH command
type AttachType ¶
type AttachType uint32
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 ( AttachCGroupInetIngress AttachType = iota AttachCGroupInetEgress AttachCGroupInetSockCreate AttachCGroupSockOps AttachSkSKBStreamParser AttachSkSKBStreamVerdict AttachCGroupDevice AttachSkMsgVerdict AttachCGroupInet4Bind AttachCGroupInet6Bind AttachCGroupInet4Connect AttachCGroupInet6Connect AttachCGroupInet4PostBind AttachCGroupInet6PostBind AttachCGroupUDP4Sendmsg AttachCGroupUDP6Sendmsg AttachLircMode2 AttachFlowDissector AttachCGroupSysctl AttachCGroupUDP4Recvmsg AttachCGroupUDP6Recvmsg AttachCGroupGetsockopt AttachCGroupSetsockopt AttachTraceRawTp AttachTraceFEntry AttachTraceFExit AttachModifyReturn AttachLSMMac AttachTraceIter AttachCgroupInet4GetPeername AttachCgroupInet6GetPeername AttachCgroupInet4GetSockname AttachCgroupInet6GetSockname AttachXDPDevMap AttachCgroupInetSockRelease AttachXDPCPUMap AttachSkLookup AttachXDP AttachSkSKBVerdict AttachSkReuseportSelect AttachSkReuseportSelectOrMigrate AttachPerfEvent )
const AttachNone AttachType = 0
AttachNone is an alias for AttachCGroupInetIngress for readability reasons.
func (AttachType) String ¶
func (i AttachType) String() string
type BatchOptions ¶ added in v0.4.0
BatchOptions batch map operations options
Mirrors libbpf struct bpf_map_batch_opts Currently BPF_F_FLAG is the only supported flag (for ElemFlags).
type Collection ¶
Collection is a collection of Programs and Maps associated with their symbols
func LoadCollection ¶
func LoadCollection(file string) (*Collection, error)
LoadCollection parses an object file and converts it to a collection.
func NewCollection ¶
func NewCollection(spec *CollectionSpec) (*Collection, error)
NewCollection creates a Collection from a specification.
func NewCollectionWithOptions ¶
func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error)
NewCollectionWithOptions creates a Collection from a specification.
func (*Collection) Close ¶
func (coll *Collection) Close()
Close frees all maps and programs associated with the collection.
The collection mustn't be used afterwards.
func (*Collection) DetachMap ¶
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 (*Collection) DetachProgram ¶
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 ¶
type CollectionOptions struct { Maps MapOptions Programs ProgramOptions }
CollectionOptions control loading a collection into the kernel.
Maps and Programs are passed to NewMapWithOptions and NewProgramsWithOptions.
type CollectionSpec ¶
type CollectionSpec struct { Maps map[string]*MapSpec Programs map[string]*ProgramSpec // ByteOrder specifies whether the ELF was compiled for // big-endian or little-endian architectures. ByteOrder binary.ByteOrder }
CollectionSpec describes a collection.
func LoadCollectionSpec ¶
func LoadCollectionSpec(file string) (*CollectionSpec, error)
LoadCollectionSpec parses an ELF file into a CollectionSpec.
func LoadCollectionSpecFromReader ¶
func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error)
LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec.
func (*CollectionSpec) Assign ¶
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 or Maps if it has an `ebpf` tag and its type is *ProgramSpec or *MapSpec. 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"` Ignored int }
Returns an error if any of the eBPF objects can't be found, or if the same MapSpec or ProgramSpec is assigned multiple times.
Example ¶
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 (*CollectionSpec) Copy ¶
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.
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.
Example ¶
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) } fmt.Println(objs.Program.Type()) fmt.Println(objs.Map.Type())
Output: SocketFilter Array
func (*CollectionSpec) RewriteConstants ¶
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 if a constant doesn't exist.
func (*CollectionSpec) RewriteMaps ¶
func (cs *CollectionSpec) RewriteMaps(maps map[string]*Map) error
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.
type LoadPinOptions ¶ added in v0.5.0
type LoadPinOptions struct { // Request a read-only or write-only object. The default is a read-write // object. Only one of the flags may be set. ReadOnly bool WriteOnly bool // Raw flags for the syscall. Other fields of this struct take precedence. Flags uint32 }
LoadPinOptions control how a pinned object is loaded.
func (*LoadPinOptions) Marshal ¶ added in v0.5.0
func (lpo *LoadPinOptions) Marshal() uint32
Marshal returns a value suitable for BPF_OBJ_GET syscall file_flags parameter.
type Map ¶
type Map struct {
// contains filtered or unexported fields
}
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.
Example (PerCPU) ¶
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) } first := []uint32{4, 5} if err := arr.Put(uint32(0), first); err != nil { panic(err) } second := []uint32{2, 8} if err := arr.Put(uint32(1), second); err != nil { panic(err) } var values []uint32 if err := arr.Lookup(uint32(0), &values); err != nil { panic(err) } fmt.Println("First two values:", values[:2]) var ( key uint32 entries = arr.Iterate() ) for entries.Next(&key, &values) { // NB: sum can overflow, real code should check for this var sum uint32 for _, n := range values { sum += n } fmt.Printf("Sum of %d: %d\n", key, sum) } if err := entries.Err(); err != nil { panic(err) }
Output:
Example (ZeroCopy) ¶
It is possible to use unsafe.Pointer to avoid marshalling and copy overhead. It is the resposibility 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 := createHash() 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)
Output: The value is: 23
func LoadPinnedMap ¶
func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error)
LoadPinnedMap loads a Map from a BPF file.
func NewMap ¶
NewMap creates a new Map.
It's equivalent to calling NewMapWithOptions with default options.
func NewMapFromFD ¶
NewMapFromFD creates a map from a raw fd.
You should not use fd after calling this function.
func NewMapFromID ¶
NewMapFromID returns the map for a given id.
Returns ErrNotExist, if there is no eBPF map with the given id.
func NewMapWithOptions ¶
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 (*Map) BatchDelete ¶ added in v0.4.0
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 (*Map) BatchLookup ¶ added in v0.4.0
func (m *Map) BatchLookup(prevKey, nextKeyOut, 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. "prevKey" is the key to start the batch lookup from, it will *not* be included in the results. Use nil to start at the first key.
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(prevKey, nextKeyOut, 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. "prevKey" is the key to start the batch lookup from, it will *not* be included in the results. Use nil to start at the first key.
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) BatchUpdate ¶ added in v0.4.0
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 (*Map) Clone ¶
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.
func (*Map) FD ¶
FD gets the file descriptor of the Map.
Calling this function is invalid after Close has been called.
func (*Map) Freeze ¶
Freeze prevents a map to be modified from user space.
It makes no changes to kernel-side restrictions.
func (*Map) IsPinned ¶ added in v0.4.0
IsPinned returns true if the map has a non-empty pinned path.
func (*Map) Iterate ¶
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.
Example ¶
ExampleMap_Iterate demonstrates how to iterate over all entries in a map.
hash := createHash() defer hash.Close() if err := hash.Put("hello", uint32(21)); err != nil { panic(err) } if err := hash.Put("world", uint32(42)); err != nil { panic(err) } var ( key string value uint32 entries = hash.Iterate() ) for entries.Next(&key, &value) { // Order of keys is non-deterministic due to randomized map seed fmt.Printf("key: %s, value: %d\n", key, value) } if err := entries.Err(); err != nil { panic(fmt.Sprint("Iterator encountered an error:", err)) }
Output:
Example (NestedMapsAndProgramArrays) ¶
It is possible to iterate nested maps and program arrays by unmarshaling into a *Map or *Program.
var arrayOfMaps *Map // Set this up somehow var ( key uint32 m *Map entries = arrayOfMaps.Iterate() ) // Make sure that the iterated map is closed after // we are done. defer m.Close() for entries.Next(&key, &m) { // Order of keys is non-deterministic due to randomized map seed fmt.Printf("key: %v, map: %v\n", key, m) } if err := entries.Err(); err != nil { panic(fmt.Sprint("Iterator encountered an error:", err)) }
Output:
func (*Map) Lookup ¶
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 ¶
LookupAndDelete retrieves and deletes a value from a Map.
Returns ErrKeyNotExist if the key doesn't exist.
func (*Map) LookupBytes ¶
LookupBytes gets a value from Map.
Returns a nil value if a key doesn't exist.
func (*Map) MaxEntries ¶
MaxEntries returns the maximum number of elements the map can hold.
func (*Map) NextKey ¶
NextKey finds the key following an initial key.
See NextKeyBytes for details.
Returns ErrKeyNotExist if there is no next key.
Example ¶
hash := createHash() defer hash.Close() if err := hash.Put("hello", uint32(21)); err != nil { panic(err) } if err := hash.Put("world", uint32(42)); err != nil { panic(err) } var firstKey string if err := hash.NextKey(nil, &firstKey); err != nil { panic(err) } var nextKey string if err := hash.NextKey(firstKey, &nextKey); err != nil { panic(err) } // Order of keys is non-deterministic due to randomized map seed
Output:
func (*Map) NextKeyBytes ¶
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 (*Map) Pin ¶
Pin persists the map on the BPF virtual file system past the lifetime of the process that created it .
Calling Pin on a previously pinned map will overwrite the path, except when the new path already exists. Re-pinning across filesystems is not supported. You can Clone a map to pin it to a different path.
This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
func (*Map) Put ¶
Put replaces or creates a value in map.
It is equivalent to calling Update with UpdateAny.
func (*Map) Unpin ¶ added in v0.4.0
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.
func (*Map) Update ¶
func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error
Update changes the value of a key.
type MapID ¶
type MapID uint32
MapID represents the unique ID of an eBPF map
func MapGetNextID ¶
MapGetNextID returns the ID of the next eBPF map.
Returns ErrNotExist, if there is no next eBPF map.
type MapInfo ¶ added in v0.3.0
type MapInfo struct { Type MapType KeySize uint32 ValueSize uint32 MaxEntries uint32 Flags uint32 // Name as supplied by user space at load time. Name string // contains filtered or unexported fields }
MapInfo describes a map.
type MapIterator ¶
type MapIterator struct {
// contains filtered or unexported fields
}
MapIterator iterates a Map.
See Map.Iterate.
func (*MapIterator) Err ¶
func (mi *MapIterator) Err() error
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 (*MapIterator) Next ¶
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 ¶
type MapKV struct { Key interface{} Value interface{} }
MapKV is used to initialize the contents of a Map.
type MapOptions ¶
type MapOptions struct { // The base path to pin maps in if requested via PinByName. // Existing maps will be re-used if they are compatible, otherwise an // error is returned. PinPath string LoadPinOptions LoadPinOptions }
MapOptions control loading a map into the kernel.
type MapSpec ¶
type MapSpec struct { // Name is passed to the kernel as a debug aid. Must only contain // alpha numeric and '_' characters. Name string Type MapType KeySize uint32 ValueSize uint32 MaxEntries uint32 // Flags is passed to the kernel and specifies additional map // creation attributes. Flags uint32 // Automatically pin and load a map from MapOptions.PinPath. // Generates an error if an existing pinned map is incompatible with the MapSpec. Pinning PinType // Specify numa node during map creation // (effective only if unix.BPF_F_NUMA_NODE flag is set, // which can be imported from golang.org/x/sys/unix) NumaNode uint32 // The initial contents of the map. May be nil. Contents []MapKV // Whether to freeze a map after setting its initial contents. Freeze bool // InnerMap is used as a template for ArrayOfMaps and HashOfMaps InnerMap *MapSpec // Extra trailing bytes found in the ELF map definition when using structs // larger than libbpf's bpf_map_def. Must be empty before instantiating // the MapSpec into a Map. Extra bytes.Reader // The BTF associated with this map. BTF *btf.Map }
MapSpec defines a Map.
type MapType ¶
type MapType uint32
MapType indicates the type map structure that will be initialized in the kernel.
const ( UnspecifiedMap MapType = iota // Hash is a hash map Hash // Array is an array map Array // ProgramArray - A program array map is a special kind of array map whose map // values contain only file descriptors referring to other eBPF // programs. Thus, both the key_size and value_size must be // exactly four bytes. This map is used in conjunction with the // TailCall helper. ProgramArray // PerfEventArray - A perf event array is used in conjunction with PerfEventRead // and PerfEventOutput calls, to read the raw bpf_perf_data from the registers. PerfEventArray // PerCPUHash - This data structure is useful for people who have high performance // network needs and can reconcile adds at the end of some cycle, so that // hashes can be lock free without the use of XAdd, which can be costly. PerCPUHash // PerCPUArray - This data structure is useful for people who have high performance // network needs and can reconcile adds at the end of some cycle, so that // hashes can be lock free without the use of XAdd, which can be costly. // Each CPU gets a copy of this hash, the contents of all of which can be reconciled // later. PerCPUArray // StackTrace - This holds whole user and kernel stack traces, it can be retrieved with // GetStackID StackTrace // CGroupArray - This is a very niche structure used to help SKBInCGroup determine // if an skb is from a socket belonging to a specific cgroup CGroupArray // LRUHash - This allows you to create a small hash structure that will purge the // least recently used items rather than thow an error when you run out of memory LRUHash // LRUCPUHash - This is NOT like PerCPUHash, this structure is shared among the CPUs, // it has more to do with including the CPU id with the LRU calculation so that if a // particular CPU is using a value over-and-over again, then it will be saved, but if // a value is being retrieved a lot but sparsely across CPUs it is not as important, basically // giving weight to CPU locality over overall usage. LRUCPUHash // LPMTrie - This is an implementation of Longest-Prefix-Match Trie structure. It is useful, // for storing things like IP addresses which can be bit masked allowing for keys of differing // values to refer to the same reference based on their masks. See wikipedia for more details. LPMTrie // ArrayOfMaps - Each item in the array is another map. The inner map mustn't be a map of maps // itself. ArrayOfMaps // HashOfMaps - Each item in the hash map is another map. The inner map mustn't be a map of maps // itself. HashOfMaps // DevMap - Specialized map to store references to network devices. DevMap // SockMap - Specialized map to store references to sockets. SockMap // CPUMap - Specialized map to store references to CPUs. CPUMap // XSKMap - Specialized map for XDP programs to store references to open sockets. XSKMap // SockHash - Specialized hash to store references to sockets. SockHash // CGroupStorage - Special map for CGroups. CGroupStorage // ReusePortSockArray - Specialized map to store references to sockets that can be reused. ReusePortSockArray // PerCPUCGroupStorage - Special per CPU map for CGroups. PerCPUCGroupStorage // Queue - FIFO storage for BPF programs. Queue // Stack - LIFO storage for BPF programs. Stack // SkStorage - Specialized map for local storage at SK for BPF programs. SkStorage // DevMapHash - Hash-based indexing scheme for references to network devices. DevMapHash // StructOpsMap - This map holds a kernel struct with its function pointer implemented in a BPF // program. StructOpsMap // RingBuf - Similar to PerfEventArray, but shared across all CPUs. RingBuf // InodeStorage - Specialized local storage map for inodes. InodeStorage // TaskStorage - Specialized local storage map for task_struct. TaskStorage )
All the various map types that can be created
var StructOpts MapType = StructOpsMap
Deprecated: StructOpts was a typo, use StructOpsMap instead.
Declared as a variable to prevent stringer from picking it up as an enum value.
type MapUpdateFlags ¶
type MapUpdateFlags uint64
MapUpdateFlags controls the behaviour of the Map.Update call.
The exact semantics depend on the specific MapType.
const ( // UpdateAny creates a new element or update an existing one. UpdateAny MapUpdateFlags = iota // UpdateNoExist creates a new element. UpdateNoExist MapUpdateFlags = 1 << (iota - 1) // UpdateExist updates an existing element. UpdateExist )
type PinType ¶
type PinType int
PinType determines whether a map is pinned into a BPFFS.
Valid pin types.
Mirrors enum libbpf_pin_type.
type Program ¶
type Program struct { // Contains the output of the kernel verifier if enabled, // otherwise it is empty. VerifierLog string // contains filtered or unexported fields }
Program represents BPF program loaded into the kernel.
It is not safe to close a Program which is used by other goroutines.
Example (UnmarshalFromMap) ¶
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) }
Output:
func LoadPinnedProgram ¶
func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error)
LoadPinnedProgram loads a Program from a BPF file.
Requires at least Linux 4.11.
func NewProgram ¶
func NewProgram(spec *ProgramSpec) (*Program, error)
NewProgram creates a new Program.
Loading a program for the first time will perform feature detection by loading small, temporary programs.
func NewProgramFromFD ¶
NewProgramFromFD creates a program from a raw fd.
You should not use fd after calling this function.
Requires at least Linux 4.10.
func NewProgramFromID ¶
NewProgramFromID returns the program for a given id.
Returns ErrNotExist, if there is no eBPF program with the given id.
func NewProgramWithOptions ¶
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.
Example ¶
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: 2, LogSize: 1024, }) if err != nil { panic(err) } defer prog.Close() fmt.Println("The verifier output is:") fmt.Println(prog.VerifierLog)
Output:
func (*Program) Attach
deprecated
func (p *Program) Attach(fd int, typ AttachType, flags AttachFlags) error
Attach a Program.
Deprecated: use link.RawAttachProgram instead.
func (*Program) Benchmark ¶
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.
Note: profiling a call to this function will skew it's results, see https://github.com/cilium/ebpf/issues/24
This function requires at least Linux 4.12.
func (*Program) Clone ¶
Clone creates a duplicate of the Program.
Closing the duplicate does not affect the original, and vice versa.
Cloning a nil Program returns nil.
func (*Program) Detach
deprecated
func (p *Program) Detach(fd int, typ AttachType, flags AttachFlags) error
Detach a Program.
Deprecated: use link.RawDetachProgram instead.
func (*Program) FD ¶
FD gets the file descriptor of the Program.
It is invalid to call this function after Close has been called.
func (*Program) Info ¶ added in v0.3.0
func (p *Program) Info() (*ProgramInfo, error)
Info returns metadata about the program.
Requires at least 4.10.
func (*Program) IsPinned ¶ added in v0.4.0
IsPinned returns true if the Program has a non-empty pinned path.
func (*Program) Pin ¶
Pin persists the Program on the BPF virtual file system past the lifetime of the process that created it
Calling Pin on a previously pinned program will overwrite the path, except when the new path already exists. Re-pinning across filesystems is not supported.
This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
func (*Program) Test ¶
Test runs the Program in the kernel with the given input and returns the value returned by the eBPF program. outLen may be zero.
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 (*Program) Type ¶
func (p *Program) Type() ProgramType
Type returns the underlying type of the program.
type ProgramID ¶
type ProgramID uint32
ProgramID represents the unique ID of an eBPF program.
func ProgramGetNextID ¶
ProgramGetNextID returns the ID of the next eBPF program.
Returns ErrNotExist, if there is no next eBPF program.
type ProgramInfo ¶ added in v0.3.0
type ProgramInfo struct { Type ProgramType // Truncated hash of the BPF bytecode. Tag string // Name as supplied by user space at load time. Name string // contains filtered or unexported fields }
ProgramInfo describes a program.
func (*ProgramInfo) BTFID ¶ added in v0.7.0
func (pi *ProgramInfo) BTFID() (btf.ID, bool)
BTFID returns the BTF ID associated with the program.
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.)
func (*ProgramInfo) ID ¶ added in v0.4.0
func (pi *ProgramInfo) ID() (ProgramID, bool)
ID returns the program ID.
Available from 4.13.
The bool return value indicates whether this optional field is available.
func (*ProgramInfo) MapIDs ¶ added in v0.7.0
func (pi *ProgramInfo) MapIDs() ([]MapID, bool)
MapIDs returns the maps related to the program.
The bool return value indicates whether this optional field is available.
func (*ProgramInfo) RunCount ¶ added in v0.4.0
func (pi *ProgramInfo) RunCount() (uint64, bool)
RunCount returns the total number of times the program was called.
Can return 0 if the collection of statistics is not enabled. See EnableStats(). The bool return value indicates whether this optional field is available.
func (*ProgramInfo) Runtime ¶ added in v0.4.0
func (pi *ProgramInfo) Runtime() (time.Duration, bool)
Runtime returns the total accumulated runtime of the program.
Can return 0 if the collection of statistics is not enabled. See EnableStats(). The bool return value indicates whether this optional field is available.
type ProgramOptions ¶
type ProgramOptions struct { // Controls the detail emitted by the kernel verifier. Set to non-zero // to enable logging. LogLevel uint32 // Controls the output buffer size for the verifier. Defaults to // DefaultVerifierLogSize. LogSize int // An ELF containing the target BTF for this program. It is used both to // find the correct function to trace and to apply CO-RE relocations. // This is useful in environments where the kernel BTF is not available // (containers) or where it is in a non-standard location. Defaults to // use the kernel BTF from a well-known location. TargetBTF io.ReaderAt }
ProgramOptions control loading a program into the kernel.
type ProgramSpec ¶
type ProgramSpec struct { // Name is passed to the kernel as a debug aid. Must only contain // alpha numeric and '_' characters. Name string // Type determines at which hook in the kernel a program will run. Type ProgramType AttachType AttachType // Name of a kernel data structure or function to attach to. Its // interpretation depends on Type and AttachType. AttachTo string // The program to attach to. Must be provided manually. AttachTarget *Program Instructions asm.Instructions // Flags is passed to the kernel and specifies additional program // load attributes. Flags uint32 // License of the program. Some helpers are only available if // the license is deemed compatible with the GPL. // // See https://www.kernel.org/doc/html/latest/process/license-rules.html#id1 License string // Version used by Kprobe programs. // // Deprecated on kernels 5.0 and later. Leave empty to let the library // detect this value automatically. KernelVersion uint32 // The BTF associated with this program. Changing Instructions // will most likely invalidate the contained data, and may // result in errors when attempting to load it into the kernel. BTF *btf.Program // The byte order this program was compiled for, may be nil. ByteOrder binary.ByteOrder }
ProgramSpec defines a Program.
func (*ProgramSpec) Copy ¶
func (ps *ProgramSpec) Copy() *ProgramSpec
Copy returns a copy of the spec.
func (*ProgramSpec) Tag ¶ added in v0.4.0
func (ps *ProgramSpec) Tag() (string, error)
Tag calculates the kernel tag for a series of instructions.
Use asm.Instructions.Tag if you need to calculate for non-native endianness.
Example ¶
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) }
Output:
type ProgramType ¶
type ProgramType uint32
ProgramType of the eBPF program
const ( UnspecifiedProgram ProgramType = iota SocketFilter Kprobe SchedCLS SchedACT TracePoint XDP PerfEvent CGroupSKB CGroupSock LWTIn LWTOut LWTXmit SockOps SkSKB CGroupDevice SkMsg RawTracepoint CGroupSockAddr LWTSeg6Local LircMode2 SkReuseport FlowDissector CGroupSysctl RawTracepointWritable CGroupSockopt Tracing StructOps Extension LSM SkLookup )
eBPF program types
func (ProgramType) Max ¶ added in v0.7.0
func (_ ProgramType) Max() ProgramType
Max return the latest supported ProgramType.
func (ProgramType) String ¶
func (i ProgramType) String() string
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package asm is an assembler for eBPF bytecode.
|
Package asm is an assembler for eBPF bytecode. |
cmd
|
|
bpf2go
Program bpf2go embeds eBPF in Go.
|
Program bpf2go embeds eBPF in Go. |
examples
module
|
|
Package features allows probing for BPF features available to the calling process.
|
Package features allows probing for BPF features available to the calling process. |
btf
Package btf handles data encoded according to the BPF Type Format.
|
Package btf handles data encoded according to the BPF Type Format. |
Package link allows attaching eBPF programs to various kernel hooks.
|
Package link allows attaching eBPF programs to various kernel hooks. |
Package perf allows interacting with Linux perf_events.
|
Package perf allows interacting with Linux perf_events. |
Package ringbuf allows interacting with Linux BPF ring buffer.
|
Package ringbuf allows interacting with Linux BPF ring buffer. |
Package rlimit allows raising RLIMIT_MEMLOCK if necessary for the use of BPF.
|
Package rlimit allows raising RLIMIT_MEMLOCK if necessary for the use of BPF. |