ebpf

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2018 License: ISC Imports: 6 Imported by: 0

README

ebpf

import "acln.ro/ebpf"

eBPF package for Go. Currently under active development.

See documentation at https://godoc.org/acln.ro/ebpf.

license

Package ebpf is distributed under the ISC license. A copy of the license can be found in the LICENSE file.

TODO(acln): leave a note about the samples, figure out what the right license is there, since they're based on GPL samples from the Linux source tree.

Documentation

Index

Constants

View Source
const (
	// K specifies the 32 bit immediate as the source operand.
	K = iota << 3

	// X specifies the source register as the source operand.
	X
)

Source operands.

View Source
const MaxInstructions = 4096

MaxInstructions is the maximum number of instructions in a BPF or eBPF program.

Variables

This section is empty.

Functions

func IsExist

func IsExist(err error) bool

IsExist returns a boolean indicating whether err reports that an object (e.g. an entry in a map) already exists.

func IsNotExist

func IsNotExist(err error) bool

IsNotExist returns a boolean indicating whether err is reports that an object (e.g. an entry in a map) does not exist.

func IsTooBig

func IsTooBig(err error) bool

IsTooBig returns a boolean indicating whether err is known to report that a map has reached its size limit.

Types

type ALUOp

type ALUOp uint8

ALUOp specifies an ALU operation.

const (
	ADD ALUOp = iota << 4
	SUB
	MUL
	DIV
	OR
	AND
	LSH
	RSH
	NEG
	MOD
	XOR
	MOV  // eBPF only
	ARSH // eBPF only
	END  // eBPF only
)

Valid ALU operations.

type AddressMode

type AddressMode uint8

AddressMode is the addres mode of a load or store instruction.

const (
	IMM AddressMode = iota << 5
	ABS
	IND
	MEM
	LEN
	MSH
	XADD // eBPF only
)

Valid address modes.

type Assembler

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

An Assembler assembles eBPF instructions.

func (*Assembler) ALU32Imm

func (a *Assembler) ALU32Imm(op ALUOp, dst Register, imm int32)

ALU32Imm emits a 32 bit ALU instruction on a register and a 32 bit immediate. Schematically:

dst = int32(dst) <op> imm

After the operation, dst is zero-extended into 64-bit.

func (*Assembler) ALU32Reg

func (a *Assembler) ALU32Reg(op ALUOp, dst, src Register)

ALU32Reg emits a 32 bit ALU instruction on registers. Schematically:

dst = int32(dst) <op> int32(src)

After the operation, dst is zero-extended into 64-bit.

func (*Assembler) ALU64Imm

func (a *Assembler) ALU64Imm(op ALUOp, dst Register, imm int32)

ALU64Imm emits a 64 bit ALU instruction on a register and a 32 bit immediate. Schematically:

dst = dst <op> int64(imm)

func (*Assembler) ALU64Reg

func (a *Assembler) ALU64Reg(op ALUOp, dst, src Register)

ALU64Reg emits a 64 bit ALU instruction on registers.

dst = dst <op> src

func (*Assembler) Assemble

func (a *Assembler) Assemble() []RawInstruction

Assemble assembles the code and returns the raw instructions.

func (*Assembler) AtomicAdd32

func (a *Assembler) AtomicAdd32(dst, src Register, offset int16)

AtomicAdd32 emits a 32-bit atomic add to a memory location. Schematically:

*(uint32 *)(dst + offset) += uint32(src)

func (*Assembler) AtomicAdd64

func (a *Assembler) AtomicAdd64(dst, src Register, offset int16)

AtomicAdd64 emits a 64-bit atomic add to a memory location. Schematically:

*(uint64 *)(dst + offset) += src

func (*Assembler) Call

func (a *Assembler) Call(fn KernelFunction)

Call emits a function call instruction. Schematically:

func (*Assembler) Exit

func (a *Assembler) Exit()

Exit emits a program exit instruction.

func (*Assembler) JumpImm

func (a *Assembler) JumpImm(cond JumpCondition, dst Register, imm int32, offset int16)

JumpImm emits a conditional jump against an immediate. Schematically:

if dst <op> imm { goto pc + offset }

func (*Assembler) JumpReg

func (a *Assembler) JumpReg(cond JumpCondition, dst, src Register, offset int16)

JumpReg emits a conditional jump against registers. Schematically:

if dst <op> src { goto pc + offset }

func (*Assembler) LoadAbs

func (a *Assembler) LoadAbs(w InstructionWidth, imm int32)

LoadAbs emits the special 'direct packet access' instruction. Schematically:

R0 = *(uintw *)(skb->data + imm)

func (*Assembler) LoadImm64

func (a *Assembler) LoadImm64(dst Register, imm uint64)

LoadImm64 emits the special 'load 64 bit immediate' instruction, which loads a 64 bit immediate into dst.

func (*Assembler) LoadMapFD

func (a *Assembler) LoadMapFD(dst Register, fd uint32)

LoadMapFD loads a map file descriptor into dst.

func (*Assembler) MemLoad

func (a *Assembler) MemLoad(w InstructionWidth, dst, src Register, offset int16)

MemLoad emits a memory load. Schematically:

dst = *(uintw *)(src + offset)

func (*Assembler) MemStoreImm

func (a *Assembler) MemStoreImm(w InstructionWidth, dst Register, offset int16, imm int32)

MemStoreImm emits a memory store from an immediate. Schematically:

*(uintw *)(dst + offset) = imm

func (*Assembler) MemStoreReg

func (a *Assembler) MemStoreReg(w InstructionWidth, dst, src Register, offset int16)

MemStoreReg emits a memory store from a register. Schematically:

*(uintw *)(dst + offset) = src

func (*Assembler) Mov32Imm

func (a *Assembler) Mov32Imm(dst Register, imm int32)

Mov32Imm emits a move of a 32 bit immediate into a register. Schematically:

dst = imm

After the operation, dst is zero-extended into 64-bit.

func (*Assembler) Mov32Reg

func (a *Assembler) Mov32Reg(dst, src Register)

Mov32Reg emits a move on 32-bit subregisters. Schematically:

dst = int32(src)

After the operation, dst is zero-extended into 64-bit.

func (*Assembler) Mov64Imm

func (a *Assembler) Mov64Imm(dst Register, imm int32)

Mov64Imm emits a 64 bit move of a 32 bit immediate into a register. Schematically:

dst = imm

func (*Assembler) Mov64Reg

func (a *Assembler) Mov64Reg(dst, src Register)

Mov64Reg emits a move on 64-bit registers. Schematically:

dst = src

func (*Assembler) Raw

func (a *Assembler) Raw(ins Instruction)

Raw emits a raw instruction to the stream.

type AttachType

type AttachType uint32

AttachType describes the attach type of an eBPF program.

const (
	AttachTypeCGroupInetIngress AttachType = iota
	AttachTypeCGroupInetEgress
	AttachTypeCGroupInetSockCreate
	AttachTypeCGroupSockOps
	AttachTypeSKSKBStreamParser
	AttachTypeSKSKBStreamVerdict
	AttachTypeCGroupDevice
	AttachTypeSKMsgVerdict
	AttachTypeCGroupInet4Bind
	AttachTypeCGroupInet6Bind
	AttachTypeCGroupInet4Connect
	AttachTypeCGroupInet6Connect
	AttachTypeCGroupInet4PostBind
	AttachTypeCGroupInet6PostBind
	AttachTypeCGroupUDP4SendMsg
	AttachTypeCGroupUDP6SendMsg
	AttachTypeLIRCMode2
)

Valid program attach types.

type CGroupAttachFlag added in v0.3.0

type CGroupAttachFlag uint32

CGroupAttachFlag is a flag for an AttachCGroup operation.

const (
	// CGroupAttachAllowNone allows no further bpf programs in the target
	// cgroup sub-tree.
	CGroupAttachAllowNone CGroupAttachFlag = 0

	// CGroupAttachAllowOverride arranges for the program in this cgroup
	// to yield to programs installed by sub-cgroups.
	CGroupAttachAllowOverride CGroupAttachFlag = 1 << 0

	// CGroupAttachAllowMulti arranges for the program in this cgroup
	// to run in addition to programs installed by sub-cgroups.
	CGroupAttachAllowMulti CGroupAttachFlag = 1 << 1
)

cgroup attach flags.

type Instruction

type Instruction struct {
	// Code is the operation to execute.
	Code uint8

	// Dst and Src specify the destination and source registers
	// respectively.
	Dst, Src Register

	// Off specifies the signed 16 bit offset.
	Off int16

	// Imm specifies the signed 32 bit immediate. The interpretation of
	// the immediate varies from instruction to instruction.
	Imm int32
}

Instruction specifies a raw eBPF instruction.

Note that Instruction does not pack the destination and source registers into a single 8 bit field. Therefore, it is not suitable for passing into the Linux kernel or an eBPF virtual machine directly.

func (Instruction) Pack

func (i Instruction) Pack() RawInstruction

Pack packs the Dst and Src fields into 4 bits each, and performs the final assembly of the instruction, producing a RawInstruction.

type InstructionClass

type InstructionClass uint8

InstructionClass is an eBPF instruction class.

const (
	LD InstructionClass = iota
	LDX
	ST
	STX
	ALU
	JMP

	ALU64
)

Instruction classes.

type InstructionWidth

type InstructionWidth uint8

InstructionWidth is the width of a load or store instruction.

const (
	W  InstructionWidth = iota << 3 // 32 bit
	H                               // 16 bit
	B                               // 8 bit
	DW                              // 64 bit
)

Instruction widths.

type JumpCondition

type JumpCondition uint8

JumpCondition specifies a jump condition.

const (
	JA JumpCondition = iota << 4
	JEQ
	JGT
	JGE
	JSET
	JNE  // eBPF only
	JSGT // eBPF only
	JSGE // eBPF only
	CALL // eBPF only
	EXIT // eBPF only
	JLT  // eBPF only
	JLE  // eBPF only
	JSLT // eBPF only
	JSLE // eBPF only
)

Valid jump conditions.

type KernelFunction

type KernelFunction int32

KernelFunction is a function callable by eBPF programs from inside the kernel.

const (
	KernelFunctionUnspec KernelFunction = iota // bpf_unspec

	MapLookupElem     // bpf_map_lookup_elem
	MapUpdateElem     // bpf_map_update_elem
	MapDeleteElem     // bpf_map_delete_elem
	ProbeRead         // bpf_probe_read
	KTimeGetNS        // bpf_ktime_get_ns
	TracePrintk       // bpf_trace_printk
	GetPrandomU32     // bpf_get_prandom_u32
	GetSMPProcessorID // bpf_get_smp_processor_id
	SKBStoreBytes     // bpf_skb_store_bytes
	L3CSumReplace     // bpf_l3_csum_replace
	L4CSumReplace     // bpf_l4_csum_replace
	TailCall          // bpf_tail_call
	CloneRedirect     // bpf_clone_redirect

)

Kernel functions.

type Map added in v0.5.0

type Map struct {
	Type           MapType
	KeySize        uint32
	ValueSize      uint32
	MaxEntries     uint32
	Flags          uint32 // TODO(acln): investigate these
	InnerMap       *Map   // TODO(acln): is this right?
	NUMANode       uint32
	ObjectName     string
	InterfaceIndex uint32 // TODO(acln): document this
	// contains filtered or unexported fields
}

Map configures an eBPF map.

Before use, a Map must be initialized using the Init method. KeySize, and MaxEntries must be non-zero. For arrays, KeySize must be 4.

TODO(acln): investigate if ValueSize can be zero.

ObjectName names the map. Names must not contain the NULL character. Names longer than 15 bytes are truncated.

A Map must not be copied after initialization. After initialization, it is safe (in the data race sense) to call methods on the Map from multiple goroutines concurrently. However, it may not always be safe to do so from the perspective of the actual eBPF map semantics. For example, writes to hash maps are atomic, while writes to arrays are not. Consult the bpf documentation for more details.

TODO(acln): eitehr expand on where to find said documentation, or document the semantics more precisely.

func (*Map) Close added in v0.5.0

func (m *Map) Close() error

Close destroys the map and releases the associated file descriptor. After a call to Close, future method calls on the Map will return errors.

func (*Map) Create added in v0.5.0

func (m *Map) Create(k, v []byte) error

Create creates a new entry for k in the map, and sets the value to v. If an entry for k exists in the map, Create returns an error such that IsExist(err) == true.

func (*Map) Delete added in v0.5.0

func (m *Map) Delete(k []byte) error

Delete deletes the entry for k. If an entry for k does not exist in the map, Delete returns an error such that IsNotExist(err) == true.

func (*Map) Init added in v0.5.0

func (m *Map) Init() error

Init initializes the map.

func (*Map) Iterate added in v0.5.0

func (m *Map) Iterate(fn func(k, v []byte) (stop bool), startHint []byte) error

Iterate iterates over all keys in the map and calls fn for each key-value pair. If fn returns true or the final element of the map is reached, iteration stops. fn must not retain the arguments it is called with.

startHint optionally specifies a key that does *not* exist in the map, such that Iterate can begin iteration from the first key that does. Due to the nature of BPF map iterators, on Linux kernels older than 4.12, Iterate requires a non-nil startHint. On Linux >= 4.12, startHint may be nil, but it is recommended to pass a valid one nevertheless.

func (*Map) Lookup added in v0.5.0

func (m *Map) Lookup(k, v []byte) error

Lookup looks up the value for k and stores it in v. If k is not found in the map, Lookup returns an error such that IsNotExist(err) == true.

func (*Map) Set added in v0.5.0

func (m *Map) Set(k, v []byte) error

Set sets the value for k to v. If an entry for k exists in the map, it will be overwritten.

func (*Map) Sysfd added in v0.5.0

func (m *Map) Sysfd() int

Sysfd is a horrible kludge that exists only temporarily. A better interface should exist instead.

TODO(acln): delete this as soon as possible.

func (*Map) Update added in v0.5.0

func (m *Map) Update(k, v []byte) error

Update updates the entry for k to v. If an entry for k does not exist in the map, Update returns an error such that IsNotExist(err) == true.

type MapOpError

type MapOpError struct {
	Op  string
	Err error
}

MapOpError records an error caused by a map operation.

Op is the high level operation performed.

In some cases, Err is of type SyscallError.

func (*MapOpError) Cause

func (e *MapOpError) Cause() error

Cause returns e.Err's cause, if any, or e.Err itself otherwise.

func (*MapOpError) Error

func (e *MapOpError) Error() string

type MapType added in v0.5.0

type MapType uint32

MapType is the type of an eBPF map.

const (
	MapUnspec MapType = iota

	MapHash
	MapArray
	MapProgArray
	MapPerfEventArray
	MapPerCPUHash
	MapPerCPUArray
	MapStackTrace
	MapCGroupArray
	MapLRUHash
	MapLRUPerCPUHash
	MapLPMTrie
	MapArrayOfMaps
	MapHashOfMaps
	MapDevmap
	MapSockmap
	MapCPUmap
	MapXSKMap
	MapSockhash
	MapCGroupStorage
	MapReuseportSockarray
)

Supported map types.

type Prog

type Prog struct {
	Type               ProgType
	Instructions       []RawInstruction
	License            string
	KernelVersion      uint32
	StrictAlignment    bool
	ObjectName         string
	IfIndex            uint32
	ExpectedAttachType AttachType
	// contains filtered or unexported fields
}

Prog configures an eBPF program.

func (*Prog) AttachCGroup added in v0.3.0

func (p *Prog) AttachCGroup(fd int, typ AttachType, flag CGroupAttachFlag) error

AttachCGroup attaches the program to a control group.

TODO(acln): implement this

func (*Prog) AttachSocket added in v0.3.0

func (p *Prog) AttachSocket(sock syscall.RawConn) error

AttachSocket attaches the program to a socket.

func (*Prog) AttachSocketFD added in v0.3.0

func (p *Prog) AttachSocketFD(sockFD int) error

AttachSocketFD attaches the program to a raw file descriptor, which must refer to a socket.

func (*Prog) Detach added in v0.3.0

func (p *Prog) Detach() error

Detach detaches the program from the associated file descriptor. Most programs don't need to call Detach explicitly, since it is called by Unload.

func (*Prog) Load

func (p *Prog) Load() (log string, err error)

Load loads the program into the kernel.

If loading the program produces output from the eBPF kernel verifier, the output is returned in the log string.

func (*Prog) RunTest added in v0.3.0

func (p *Prog) RunTest(t Test) error

RunTest tests the program, as specified by t.

func (*Prog) Unload

func (p *Prog) Unload() error

Unload unloads the program from the kernel and releases the associated file descriptor.

type ProgType

type ProgType uint32

ProgType is the type of an eBPF program.

const (
	ProgTypeUnspec ProgType = iota
	ProgTypeSocketFilter
	ProgTypeKProbe
	ProgTypeSchedCLS
	ProgTypeSchedACT
	ProgTypeTracepoint
	ProgTypeXDP
	ProgTypePerfEvent
	ProgTypeCGroupSKB
	ProgTypeCGroupSock
	ProgTypeLWTIn
	ProgTypeLWTOut
	ProgTypeLWTXMit
	ProgTypeSockOps
	ProgTypeSKSKB
	ProgTypeCGroupDevice
	ProgTypeSKMsg
	ProgTypeRawTracepoint
	ProgTypeCGroupSockAddr
	ProgTypeLWTSeg6Local
	ProgTypeLIRCMode2
	ProgTypeSKReusePort
)

Valid eBPF program types.

type RawInstruction

type RawInstruction struct {
	Code uint8
	Regs uint8
	Off  int16
	Imm  int32
}

RawInstruction is an assembled eBPF instruction.

type Register

type Register uint8

Register is an eBPF register.

const (
	R0 Register = iota
	R1
	R2
	R3
	R4
	R5
	R6
	R7
	R8
	R9
	R10
	FP = R10

	// PseudoMapFD is used to specify a map file descriptor
	// for loading, in a 64-bit immediate load instruction.
	PseudoMapFD Register = 1

	// PseudoCall is used to specify a kernel function to call,
	// in a call instruction.
	PseudoCall Register = 1
)

Valid eBPF registers.

When calling kernel functions, R0 holds the return value, R1 - R5 are destroyed and set to unreadable, and R6 - R9 are preserved (callee-saved). R10 or FP is the read-only frame pointer.

type SyscallError

type SyscallError struct {
	Cmd string
	Err error
}

SyscallError records an error from a bpf(2) system call.

Cmd is a string describing the bpf command executed, e.g. "BPF_CREATE_MAP".

Err is the underlying error, of type syscall.Errno.

func (*SyscallError) Cause

func (e *SyscallError) Cause() error

Cause returns the cause of the error: e.Err.

func (*SyscallError) Error

func (e *SyscallError) Error() string

type Test added in v0.3.0

type Test struct {
	Retval   uint32 // TODO(acln): what is this for?
	Input    []byte
	Output   []byte
	Repeat   uint32
	Duration uint32 // TODO(acln): what is this? ms? us? ns?
}

Test specifies a test run for an eBPF program.

Notes

Bugs

  • all of this is very poorly documented

Jump to

Keyboard shortcuts

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