bpf

package
v0.0.0-...-e4c45ee Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2024 License: Apache-2.0, MIT Imports: 8 Imported by: 0

Documentation

Overview

Package bpf provides tools for working with Berkeley Packet Filter (BPF) programs. More information on BPF can be found at https://www.freebsd.org/cgi/man.cgi?bpf(4)

Index

Constants

View Source
const (
	// MaxInstructions is the maximum number of instructions in a BPF program,
	// and is equal to Linux's BPF_MAXINSNS.
	MaxInstructions = 4096

	// ScratchMemRegisters is the number of M registers in a BPF virtual machine,
	// and is equal to Linux's BPF_MEMWORDS.
	ScratchMemRegisters = 16
)
View Source
const (
	// Instruction class, stored in bits 0-2.
	Ld   = 0x00 // load into A
	Ldx  = 0x01 // load into X
	St   = 0x02 // store from A
	Stx  = 0x03 // store from X
	Alu  = 0x04 // arithmetic
	Jmp  = 0x05 // jump
	Ret  = 0x06 // return
	Misc = 0x07

	// Size of a load, stored in bits 3-4.
	W = 0x00 // 32 bits
	H = 0x08 // 16 bits
	B = 0x10 // 8 bits

	// Source operand for a load, stored in bits 5-7.
	// Address mode numbers in the comments come from Linux's
	// Documentation/networking/filter.txt.
	Imm = 0x00 // immediate value K (mode 4)
	Abs = 0x20 // data in input at byte offset K (mode 1)
	Ind = 0x40 // data in input at byte offset X+K (mode 2)
	Mem = 0x60 // M[K] (mode 3)
	Len = 0x80 // length of the input in bytes ("BPF extension len")
	Msh = 0xa0 // 4 * lower nibble of input at byte offset K (mode 5)

	// Source operands for arithmetic, jump, and return instructions.
	// Arithmetic and jump instructions can use K or X as source operands.
	// Return instructions can use K or A as source operands.
	K = 0x00 // still mode 4
	X = 0x08 // mode 0
	A = 0x10 // mode 9

	// Arithmetic instructions, stored in bits 4-7.
	Add = 0x00
	Sub = 0x10 // A - src
	Mul = 0x20
	Div = 0x30 // A / src
	Or  = 0x40
	And = 0x50
	Lsh = 0x60 // A << src
	Rsh = 0x70 // A >> src
	Neg = 0x80 // -A (src ignored)
	Mod = 0x90 // A % src
	Xor = 0xa0

	// Jump instructions, stored in bits 4-7.
	Ja   = 0x00 // unconditional (uses K for jump offset)
	Jeq  = 0x10 // if A == src
	Jgt  = 0x20 // if A > src
	Jge  = 0x30 // if A >= src
	Jset = 0x40 // if (A & src) != 0

	// Miscellaneous instructions, stored in bits 3-7.
	Tax = 0x00 // A = X
	Txa = 0x80 // X = A

)

Parts of a linux.BPFInstruction.OpCode. Compare to the Linux kernel's include/uapi/linux/filter.h.

In the comments below:

  • A, X, and M[] are BPF virtual machine registers.

  • K refers to the instruction field linux.BPFInstruction.K.

  • Bits are counted from the LSB position.

View Source
const (
	// DivisionByZero indicates that a program contains, or executed, a
	// division or modulo by zero.
	DivisionByZero = iota

	// InvalidEndOfProgram indicates that the last instruction of a program is
	// not a return.
	InvalidEndOfProgram

	// InvalidInstructionCount indicates that a program has zero instructions
	// or more than MaxInstructions instructions.
	InvalidInstructionCount

	// InvalidJumpTarget indicates that a program contains a jump whose target
	// is outside of the program's bounds.
	InvalidJumpTarget

	// InvalidLoad indicates that a program executed an invalid load of input
	// data.
	InvalidLoad

	// InvalidOpcode indicates that a program contains an instruction with an
	// invalid opcode.
	InvalidOpcode

	// InvalidRegister indicates that a program contains a load from, or store
	// to, a non-existent M register (index >= ScratchMemRegisters).
	InvalidRegister
)

Possible values for ProgramError.Code.

Variables

This section is empty.

Functions

func Decode

func Decode(ins Instruction) (string, error)

Decode translates a single BPF instruction into text format.

func DecodeInstructions

func DecodeInstructions(instns []Instruction) (string, error)

DecodeInstructions translates an array of BPF instructions into text format.

func DecodeProgram

func DecodeProgram(p Program) (string, error)

DecodeProgram translates a compiled BPF program into text format.

func Exec

func Exec(p Program, in Input) (uint32, error)

Exec executes a BPF program over the given input and returns its return value.

Types

type Error

type Error struct {
	// Code indicates the kind of error that occurred.
	Code int

	// PC is the program counter (index into the list of instructions) at which
	// the error occurred.
	PC int
}

Error is an error encountered while compiling or executing a BPF program.

func (Error) Error

func (e Error) Error() string

Error implements error.Error.

type FragmentOutcomes

type FragmentOutcomes struct {
	// MayFallThrough is true if executing the fragment may cause it to start
	// executing the program instruction that comes right after the last
	// instruction in this fragment (i.e. at `Fragment.toPC`).
	MayFallThrough bool

	// MayJumpToKnownOffsetBeyondFragment is true if executing the fragment may
	// jump to a fixed offset (or resolved label) that is not within the range
	// of the fragment itself, nor does it point to the instruction that would
	// come right after this fragment.
	// If the fragment jumps to an unresolved label, this will instead be
	// indicated in `MayJumpToUnresolvedLabels`.
	MayJumpToKnownOffsetBeyondFragment bool

	// MayJumpToUnresolvedLabels is the set of named labels that have not yet
	// been added to the program (the labels are not resolvable) but that the
	// fragment may jump to.
	MayJumpToUnresolvedLabels map[string]struct{}

	// MayReturn is true if executing the fragment may cause a return statement
	// to be executed.
	MayReturn bool
}

FragmentOutcomes represents the set of outcomes that a ProgramFragment execution may result into.

func (FragmentOutcomes) String

func (o FragmentOutcomes) String() string

String returns a list of possible human-readable outcomes.

type Input

type Input interface {
	// Load32 reads 32 bits from the input starting at the given byte offset.
	Load32(off uint32) (uint32, bool)

	// Load16 reads 16 bits from the input starting at the given byte offset.
	Load16(off uint32) (uint16, bool)

	// Load8 reads 8 bits from the input starting at the given byte offset.
	Load8(off uint32) (uint8, bool)

	// Length returns the length of the input in bytes.
	Length() uint32
}

Input represents a source of input data for a BPF program. (BPF documentation sometimes refers to the input data as the "packet" due to its origins as a packet processing DSL.)

For all of Input's Load methods:

  • The second (bool) return value is true if the load succeeded and false otherwise.

  • Inputs should not assume that the loaded range falls within the input data's length. Inputs should return false if the load falls outside of the input data.

  • Inputs should not assume that the offset is correctly aligned. Inputs may choose to service or reject loads to unaligned addresses.

type InputBytes

type InputBytes struct {
	// Data is the data accessed through the Input interface.
	Data []byte

	// Order is the byte order the data is accessed with.
	Order binary.ByteOrder
}

InputBytes implements the Input interface by providing access to a byte slice. Unaligned loads are supported.

func (InputBytes) Length

func (i InputBytes) Length() uint32

Length implements Input.Length.

func (InputBytes) Load16

func (i InputBytes) Load16(off uint32) (uint16, bool)

Load16 implements Input.Load16.

func (InputBytes) Load32

func (i InputBytes) Load32(off uint32) (uint32, bool)

Load32 implements Input.Load32.

func (InputBytes) Load8

func (i InputBytes) Load8(off uint32) (uint8, bool)

Load8 implements Input.Load8.

type Instruction

type Instruction linux.BPFInstruction

Instruction is a type alias for linux.BPFInstruction. It adds a human-readable stringification and other helper functions.

+marshal slice:InstructionSlice +stateify savable +stateify identtype

func Jump

func Jump(code uint16, k uint32, jt, jf uint8) Instruction

Jump returns an Instruction representing a BPF jump instruction.

func Optimize

func Optimize(insns []Instruction) []Instruction

Optimize losslessly optimizes a BPF program. The BPF instructions are assumed to have been checked for validity and consistency. The instructions in `insns` may be modified in-place.

func Stmt

func Stmt(code uint16, k uint32) Instruction

Stmt returns an Instruction representing a BPF non-jump instruction.

func (Instruction) IsConditionalJump

func (ins Instruction) IsConditionalJump() bool

IsConditionalJump returns true if `ins` is a conditional jump instruction.

func (Instruction) IsJump

func (ins Instruction) IsJump() bool

IsJump returns true if `ins` is a jump instruction.

func (Instruction) IsUnconditionalJump

func (ins Instruction) IsUnconditionalJump() bool

IsUnconditionalJump returns true if `ins` is a conditional jump instruction.

func (Instruction) JumpOffsets

func (ins Instruction) JumpOffsets() []JumpOffset

JumpOffsets returns the set of instruction offsets that this instruction may jump to. Returns a nil slice if this is not a jump instruction.

func (*Instruction) StateFields

func (ins *Instruction) StateFields() []string

func (*Instruction) StateLoad

func (ins *Instruction) StateLoad(stateSourceObject state.Source)

+checklocksignore

func (*Instruction) StateSave

func (ins *Instruction) StateSave(stateSinkObject state.Sink)

+checklocksignore

func (*Instruction) StateTypeName

func (ins *Instruction) StateTypeName() string

func (*Instruction) String

func (ins *Instruction) String() string

String returns a human-readable version of the instruction.

type JumpOffset

type JumpOffset struct {
	// Type is the type of jump that an instruction may execute.
	Type JumpType

	// Offset is the number of instructions that the jump skips over.
	Offset uint32
}

JumpOffset is a possible jump offset that an instruction may jump to.

type JumpType

type JumpType int

JumpType is the type of jump target that an instruction may use.

const (
	JumpDirect JumpType = iota
	JumpTrue
	JumpFalse
)

Types of jump that an instruction may use.

type Program

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

Program is a BPF program that has been validated for consistency.

+stateify savable

func Compile

func Compile(insns []Instruction) (Program, error)

Compile performs validation and optimization on a sequence of BPF instructions before wrapping them in a Program.

func (Program) Length

func (p Program) Length() int

Length returns the number of instructions in the program.

func (*Program) StateFields

func (p *Program) StateFields() []string

func (*Program) StateLoad

func (p *Program) StateLoad(stateSourceObject state.Source)

+checklocksignore

func (*Program) StateSave

func (p *Program) StateSave(stateSinkObject state.Sink)

+checklocksignore

func (*Program) StateTypeName

func (p *Program) StateTypeName() string

type ProgramBuilder

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

ProgramBuilder assists with building a BPF program with jump labels that are resolved to their proper offsets.

func NewProgramBuilder

func NewProgramBuilder() *ProgramBuilder

NewProgramBuilder creates a new ProgramBuilder instance.

func (*ProgramBuilder) AddDirectJumpLabel

func (b *ProgramBuilder) AddDirectJumpLabel(labelName string)

AddDirectJumpLabel adds a new jump to the program where is labelled.

func (*ProgramBuilder) AddJump

func (b *ProgramBuilder) AddJump(code uint16, k uint32, jt, jf uint8)

AddJump adds a new jump to the program.

func (*ProgramBuilder) AddJumpFalseLabel

func (b *ProgramBuilder) AddJumpFalseLabel(code uint16, k uint32, jt uint8, jfLabel string)

AddJumpFalseLabel adds a new jump to the program where 'jump if false' is a label.

func (*ProgramBuilder) AddJumpLabels

func (b *ProgramBuilder) AddJumpLabels(code uint16, k uint32, jtLabel, jfLabel string)

AddJumpLabels adds a new jump to the program where both jump targets are labels.

func (*ProgramBuilder) AddJumpTrueLabel

func (b *ProgramBuilder) AddJumpTrueLabel(code uint16, k uint32, jtLabel string, jf uint8)

AddJumpTrueLabel adds a new jump to the program where 'jump if true' is a label.

func (*ProgramBuilder) AddLabel

func (b *ProgramBuilder) AddLabel(name string) error

AddLabel sets the given label name at the current location. The next instruction is executed when the any code jumps to this label. More than one label can be added to the same location.

func (*ProgramBuilder) AddStmt

func (b *ProgramBuilder) AddStmt(code uint16, k uint32)

AddStmt adds a new statement to the program.

func (*ProgramBuilder) Instructions

func (b *ProgramBuilder) Instructions() ([]Instruction, error)

Instructions returns an array of BPF instructions representing the program with all labels resolved. Return error in case label resolution failed due to an invalid program.

N.B. Partial results will be returned in the error case, which is useful for debugging.

func (*ProgramBuilder) Record

func (b *ProgramBuilder) Record() func() ProgramFragment

Record starts recording the instructions being added to the ProgramBuilder until the returned function is called. The returned function returns a ProgramFragment which represents the recorded instructions. It may be called repeatedly.

type ProgramFragment

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

ProgramFragment is a set of not-compiled instructions that were added to a ProgramBuilder from the moment the `Record` function was called on it.

func (ProgramFragment) Outcomes

func (f ProgramFragment) Outcomes() FragmentOutcomes

Outcomes returns the set of possible outcomes that executing this fragment may result into.

func (ProgramFragment) String

func (f ProgramFragment) String() string

String returns a string version of the fragment.

Jump to

Keyboard shortcuts

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