package bpf
Import Path
golang.org/x/net/bpf (on go.dev)
Dependency Relation
imports 3 packages, and imported by 2 packages
Involved Source Files
asm.go
constants.go
Package bpf implements marshaling and unmarshaling of programs for the
Berkeley Packet Filter virtual machine, and provides a Go implementation
of the virtual machine.
BPF's main use is to specify a packet filter for network taps, so that
the kernel doesn't have to expensively copy every packet it sees to
userspace. However, it's been repurposed to other areas where running
user code in-kernel is needed. For example, Linux's seccomp uses BPF
to apply security policies to system calls. For simplicity, this
documentation refers only to packets, but other uses of BPF have their
own data payloads.
BPF programs run in a restricted virtual machine. It has almost no
access to kernel functions, and while conditional branches are
allowed, they can only jump forwards, to guarantee that there are no
infinite loops.
# The virtual machine
The BPF VM is an accumulator machine. Its main register, called
register A, is an implicit source and destination in all arithmetic
and logic operations. The machine also has 16 scratch registers for
temporary storage, and an indirection register (register X) for
indirect memory access. All registers are 32 bits wide.
Each run of a BPF program is given one packet, which is placed in the
VM's read-only "main memory". LoadAbsolute and LoadIndirect
instructions can fetch up to 32 bits at a time into register A for
examination.
The goal of a BPF program is to produce and return a verdict (uint32),
which tells the kernel what to do with the packet. In the context of
packet filtering, the returned value is the number of bytes of the
packet to forward to userspace, or 0 to ignore the packet. Other
contexts like seccomp define their own return values.
In order to simplify programs, attempts to read past the end of the
packet terminate the program execution with a verdict of 0 (ignore
packet). This means that the vast majority of BPF programs don't need
to do any explicit bounds checking.
In addition to the bytes of the packet, some BPF programs have access
to extensions, which are essentially calls to kernel utility
functions. Currently, the only extensions supported by this package
are the Linux packet filter extensions.
# Examples
This packet filter selects all ARP packets.
bpf.Assemble([]bpf.Instruction{
// Load "EtherType" field from the ethernet header.
bpf.LoadAbsolute{Off: 12, Size: 2},
// Skip over the next instruction if EtherType is not ARP.
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},
// Verdict is "send up to 4k of the packet to userspace."
bpf.RetConstant{Val: 4096},
// Verdict is "ignore packet."
bpf.RetConstant{Val: 0},
})
This packet filter captures a random 1% sample of traffic.
bpf.Assemble([]bpf.Instruction{
// Get a 32-bit random number from the Linux kernel.
bpf.LoadExtension{Num: bpf.ExtRand},
// 1% dice roll?
bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},
// Capture.
bpf.RetConstant{Val: 4096},
// Ignore.
bpf.RetConstant{Val: 0},
})
instructions.go
setter.go
vm.go
vm_instructions.go
Package-Level Type Names (total 25)
An ALUOp is an arithmetic or logic operation.
const ALUOpAdd
const ALUOpAnd
const ALUOpDiv
const ALUOpMod
const ALUOpMul
const ALUOpOr
const ALUOpShiftLeft
const ALUOpShiftRight
const ALUOpSub
const ALUOpXor
ALUOpConstant executes A = A <Op> Val.
Op ALUOp
Val uint32
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
ALUOpConstant : Instruction
ALUOpConstant : expvar.Var
ALUOpConstant : fmt.Stringer
ALUOpX executes A = A <Op> X
Op ALUOp
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
ALUOpX : Instruction
ALUOpX : expvar.Var
ALUOpX : fmt.Stringer
An Extension is a function call provided by the kernel that
performs advanced operations that are expensive or impossible
within the BPF virtual machine.
Extensions are only implemented by the Linux kernel.
TODO: should we prune this list? Some of these extensions seem
either broken or near-impossible to use correctly, whereas other
(len, random, ifindex) are quite useful.
const ExtCPUID
const ExtInterfaceIndex
const ExtLen
const ExtLinkLayerType
const ExtMark
const ExtNetlinkAttr
const ExtNetlinkAttrNested
const ExtPayloadOffset
const ExtProto
const ExtQueue
const ExtRand
const ExtRXHash
const ExtType
const ExtVLANProto
const ExtVLANTag
const ExtVLANTagPresent
An Instruction is one instruction executed by the BPF virtual
machine.
Assemble assembles the Instruction into a RawInstruction.
ALUOpConstant
ALUOpX
Jump
JumpIf
JumpIfX
LoadAbsolute
LoadConstant
LoadExtension
LoadIndirect
LoadMemShift
LoadScratch
NegateA
RawInstruction
RetA
RetConstant
StoreScratch
TAX
TXA
func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool)
func RawInstruction.Disassemble() Instruction
func Assemble(insts []Instruction) ([]RawInstruction, error)
func NewVM(filter []Instruction) (*VM, error)
Jump skips the following Skip instructions in the program.
Skip uint32
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
Jump : Instruction
Jump : expvar.Var
Jump : fmt.Stringer
JumpIf skips the following Skip instructions in the program if A
<Cond> Val is true.
Cond JumpTest
SkipFalse uint8
SkipTrue uint8
Val uint32
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
JumpIf : Instruction
JumpIf : expvar.Var
JumpIf : fmt.Stringer
JumpIfX skips the following Skip instructions in the program if A
<Cond> X is true.
Cond JumpTest
SkipFalse uint8
SkipTrue uint8
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
JumpIfX : Instruction
JumpIfX : expvar.Var
JumpIfX : fmt.Stringer
A JumpTest is a comparison operator used in conditional jumps.
const JumpBitsNotSet
const JumpBitsSet
const JumpEqual
const JumpGreaterOrEqual
const JumpGreaterThan
const JumpLessOrEqual
const JumpLessThan
const JumpNotEqual
LoadAbsolute loads packet[Off:Off+Size] as an integer value into
register A.
Off uint32
// 1, 2 or 4
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
LoadAbsolute : Instruction
LoadAbsolute : expvar.Var
LoadAbsolute : fmt.Stringer
LoadConstant loads Val into register Dst.
Dst Register
Val uint32
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
LoadConstant : Instruction
LoadConstant : expvar.Var
LoadConstant : fmt.Stringer
LoadExtension invokes a linux-specific extension and stores the
result in register A.
Num Extension
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
LoadExtension : Instruction
LoadExtension : expvar.Var
LoadExtension : fmt.Stringer
LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value
into register A.
Off uint32
// 1, 2 or 4
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
LoadIndirect : Instruction
LoadIndirect : expvar.Var
LoadIndirect : fmt.Stringer
LoadMemShift multiplies the first 4 bits of the byte at packet[Off]
by 4 and stores the result in register X.
This instruction is mainly useful to load into X the length of an
IPv4 packet header in a single instruction, rather than have to do
the arithmetic on the header's first byte by hand.
Off uint32
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
LoadMemShift : Instruction
LoadMemShift : expvar.Var
LoadMemShift : fmt.Stringer
LoadScratch loads scratch[N] into register Dst.
Dst Register
// 0-15
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
LoadScratch : Instruction
LoadScratch : expvar.Var
LoadScratch : fmt.Stringer
NegateA executes A = -A.
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
NegateA : Instruction
NegateA : expvar.Var
NegateA : fmt.Stringer
A RawInstruction is a raw BPF virtual machine instruction.
Jf uint8
For conditional jump instructions, the number of instructions
to skip if the condition is true/false.
Constant parameter. The meaning depends on the Op.
Operation to execute.
Assemble implements the Instruction Assemble method.
Disassemble parses ri into an Instruction and returns it. If ri is
not recognized by this package, ri itself is returned.
RawInstruction : Instruction
func Assemble(insts []Instruction) ([]RawInstruction, error)
func ALUOpConstant.Assemble() (RawInstruction, error)
func ALUOpX.Assemble() (RawInstruction, error)
func Instruction.Assemble() (RawInstruction, error)
func Jump.Assemble() (RawInstruction, error)
func JumpIf.Assemble() (RawInstruction, error)
func JumpIfX.Assemble() (RawInstruction, error)
func LoadAbsolute.Assemble() (RawInstruction, error)
func LoadConstant.Assemble() (RawInstruction, error)
func LoadExtension.Assemble() (RawInstruction, error)
func LoadIndirect.Assemble() (RawInstruction, error)
func LoadMemShift.Assemble() (RawInstruction, error)
func LoadScratch.Assemble() (RawInstruction, error)
func NegateA.Assemble() (RawInstruction, error)
func RawInstruction.Assemble() (RawInstruction, error)
func RetA.Assemble() (RawInstruction, error)
func RetConstant.Assemble() (RawInstruction, error)
func StoreScratch.Assemble() (RawInstruction, error)
func TAX.Assemble() (RawInstruction, error)
func TXA.Assemble() (RawInstruction, error)
func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool)
func Setter.SetBPF(filter []RawInstruction) error
RetA exits the BPF program, returning the value of register A.
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
RetA : Instruction
RetA : expvar.Var
RetA : fmt.Stringer
RetConstant exits the BPF program, returning a constant value.
Val uint32
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
RetConstant : Instruction
RetConstant : expvar.Var
RetConstant : fmt.Stringer
A Setter is a type which can attach a compiled BPF filter to itself.
( Setter) SetBPF(filter []RawInstruction) error
*golang.org/x/net/ipv4.PacketConn
*golang.org/x/net/ipv4.RawConn
*golang.org/x/net/ipv6.PacketConn
StoreScratch stores register Src into scratch[N].
// 0-15
Src Register
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
StoreScratch : Instruction
StoreScratch : expvar.Var
StoreScratch : fmt.Stringer
TAX copies the value of register A to register X.
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
TAX : Instruction
TAX : expvar.Var
TAX : fmt.Stringer
TXA copies the value of register X to register A.
Assemble implements the Instruction Assemble method.
String returns the instruction in assembler notation.
TXA : Instruction
TXA : expvar.Var
TXA : fmt.Stringer
A VM is an emulated BPF virtual machine.
Run runs the VM's BPF program against the input bytes.
Run returns the number of bytes accepted by the BPF program, and any errors
which occurred while processing the program.
func NewVM(filter []Instruction) (*VM, error)
Package-Level Functions (total 3)
Assemble converts insts into raw instructions suitable for loading
into a BPF virtual machine.
Currently, no optimization is attempted, the assembled program flow
is exactly as provided.
Disassemble attempts to parse raw back into
Instructions. Unrecognized RawInstructions are assumed to be an
extension not implemented by this package, and are passed through
unchanged to the output. The allDecoded value reports whether insts
contains no RawInstructions.
NewVM returns a new VM using the input BPF program.
Package-Level Constants (total 36)
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ALU binary operation types.
ExtCPUID returns the ID of the CPU processing the current
packet.
ExtInterfaceIndex returns the index of the interface on which
the packet was received.
ExtLen returns the length of the packet.
ExtLinkLayerType returns the packet's hardware address type
(e.g. Ethernet, Infiniband).
ExtMark returns the packet's mark value.
ExtNetlinkAttr returns the netlink attribute of type X at
offset A.
ExtNetlinkAttrNested returns the nested netlink attribute of
type X at offset A.
ExtPayloadOffset returns the offset of the packet payload, or
the first protocol header that the kernel does not know how to
parse.
ExtProto returns the packet's L3 protocol type.
ExtQueue returns the packet's assigned hardware queue.
ExtRand returns a uniformly random uint32.
ExtRXHash returns the packets receive hash.
TODO: figure out what this rxhash actually is.
ExtType returns the packet's type (skb->pkt_type in the kernel)
TODO: better documentation. How nice an API do we want to
provide for these esoteric extensions?
ExtVLANProto returns 0x8100 if the frame has a VLAN header,
0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some
other value if no VLAN information is present.
ExtVLANTag returns the packet's VLAN tag.
ExtVLANTagPresent returns non-zero if the packet has a VLAN
tag.
TODO: I think this might be a lie: it reads bit 0x1000 of the
VLAN header, which changed meaning in recent revisions of the
spec - this extension may now return meaningless information.
K & A == 0
K & A != 0
K == A
K >= A
K > A
K <= A
K < A
K != A
RegA is the accumulator register. RegA is always the
destination register of ALU operations.
RegX is the indirection register, used by LoadIndirect
operations.
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |