Documentation

Overview

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},
})

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ALUOp

type ALUOp uint16

    An ALUOp is an arithmetic or logic operation.

    const (
    	ALUOpAdd ALUOp = iota << 4
    	ALUOpSub
    	ALUOpMul
    	ALUOpDiv
    	ALUOpOr
    	ALUOpAnd
    	ALUOpShiftLeft
    	ALUOpShiftRight
    
    	ALUOpMod
    	ALUOpXor
    )

      ALU binary operation types.

      type ALUOpConstant

      type ALUOpConstant struct {
      	Op  ALUOp
      	Val uint32
      }

        ALUOpConstant executes A = A <Op> Val.

        func (ALUOpConstant) Assemble

        func (a ALUOpConstant) Assemble() (RawInstruction, error)

          Assemble implements the Instruction Assemble method.

          func (ALUOpConstant) String

          func (a ALUOpConstant) String() string

            String returns the instruction in assembler notation.

            type ALUOpX

            type ALUOpX struct {
            	Op ALUOp
            }

              ALUOpX executes A = A <Op> X

              func (ALUOpX) Assemble

              func (a ALUOpX) Assemble() (RawInstruction, error)

                Assemble implements the Instruction Assemble method.

                func (ALUOpX) String

                func (a ALUOpX) String() string

                  String returns the instruction in assembler notation.

                  type Extension

                  type Extension int

                    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 (
                    
                    	// ExtLen returns the length of the packet.
                    	ExtLen Extension = 1
                    	// ExtProto returns the packet's L3 protocol type.
                    	ExtProto Extension = 0
                    	// 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?
                    	ExtType Extension = 4
                    	// ExtPayloadOffset returns the offset of the packet payload, or
                    	// the first protocol header that the kernel does not know how to
                    	// parse.
                    	ExtPayloadOffset Extension = 52
                    	// ExtInterfaceIndex returns the index of the interface on which
                    	// the packet was received.
                    	ExtInterfaceIndex Extension = 8
                    	// ExtNetlinkAttr returns the netlink attribute of type X at
                    	// offset A.
                    	ExtNetlinkAttr Extension = 12
                    	// ExtNetlinkAttrNested returns the nested netlink attribute of
                    	// type X at offset A.
                    	ExtNetlinkAttrNested Extension = 16
                    	// ExtMark returns the packet's mark value.
                    	ExtMark Extension = 20
                    	// ExtQueue returns the packet's assigned hardware queue.
                    	ExtQueue Extension = 24
                    	// ExtLinkLayerType returns the packet's hardware address type
                    	// (e.g. Ethernet, Infiniband).
                    	ExtLinkLayerType Extension = 28
                    	// ExtRXHash returns the packets receive hash.
                    	//
                    	// TODO: figure out what this rxhash actually is.
                    	ExtRXHash Extension = 32
                    	// ExtCPUID returns the ID of the CPU processing the current
                    	// packet.
                    	ExtCPUID Extension = 36
                    	// ExtVLANTag returns the packet's VLAN tag.
                    	ExtVLANTag Extension = 44
                    	// 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.
                    	ExtVLANTagPresent Extension = 48
                    	// 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.
                    	ExtVLANProto Extension = 60
                    	// ExtRand returns a uniformly random uint32.
                    	ExtRand Extension = 56
                    )

                      Extension functions available in the Linux kernel.

                      type Instruction

                      type Instruction interface {
                      	// Assemble assembles the Instruction into a RawInstruction.
                      	Assemble() (RawInstruction, error)
                      }

                        An Instruction is one instruction executed by the BPF virtual machine.

                        func Disassemble

                        func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool)

                          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.

                          type Jump

                          type Jump struct {
                          	Skip uint32
                          }

                            Jump skips the following Skip instructions in the program.

                            func (Jump) Assemble

                            func (a Jump) Assemble() (RawInstruction, error)

                              Assemble implements the Instruction Assemble method.

                              func (Jump) String

                              func (a Jump) String() string

                                String returns the instruction in assembler notation.

                                type JumpIf

                                type JumpIf struct {
                                	Cond      JumpTest
                                	Val       uint32
                                	SkipTrue  uint8
                                	SkipFalse uint8
                                }

                                  JumpIf skips the following Skip instructions in the program if A <Cond> Val is true.

                                  func (JumpIf) Assemble

                                  func (a JumpIf) Assemble() (RawInstruction, error)

                                    Assemble implements the Instruction Assemble method.

                                    func (JumpIf) String

                                    func (a JumpIf) String() string

                                      String returns the instruction in assembler notation.

                                      type JumpIfX

                                      type JumpIfX struct {
                                      	Cond      JumpTest
                                      	SkipTrue  uint8
                                      	SkipFalse uint8
                                      }

                                        JumpIfX skips the following Skip instructions in the program if A <Cond> X is true.

                                        func (JumpIfX) Assemble

                                        func (a JumpIfX) Assemble() (RawInstruction, error)

                                          Assemble implements the Instruction Assemble method.

                                          func (JumpIfX) String

                                          func (a JumpIfX) String() string

                                            String returns the instruction in assembler notation.

                                            type JumpTest

                                            type JumpTest uint16

                                              A JumpTest is a comparison operator used in conditional jumps.

                                              const (
                                              	// K == A
                                              	JumpEqual JumpTest = iota
                                              	// K != A
                                              	JumpNotEqual
                                              	// K > A
                                              	JumpGreaterThan
                                              	// K < A
                                              	JumpLessThan
                                              	// K >= A
                                              	JumpGreaterOrEqual
                                              	// K <= A
                                              	JumpLessOrEqual
                                              	// K & A != 0
                                              	JumpBitsSet
                                              	// K & A == 0
                                              	JumpBitsNotSet
                                              )

                                                Supported operators for conditional jumps. K can be RegX for JumpIfX

                                                type LoadAbsolute

                                                type LoadAbsolute struct {
                                                	Off  uint32
                                                	Size int // 1, 2 or 4
                                                }

                                                  LoadAbsolute loads packet[Off:Off+Size] as an integer value into register A.

                                                  func (LoadAbsolute) Assemble

                                                  func (a LoadAbsolute) Assemble() (RawInstruction, error)

                                                    Assemble implements the Instruction Assemble method.

                                                    func (LoadAbsolute) String

                                                    func (a LoadAbsolute) String() string

                                                      String returns the instruction in assembler notation.

                                                      type LoadConstant

                                                      type LoadConstant struct {
                                                      	Dst Register
                                                      	Val uint32
                                                      }

                                                        LoadConstant loads Val into register Dst.

                                                        func (LoadConstant) Assemble

                                                        func (a LoadConstant) Assemble() (RawInstruction, error)

                                                          Assemble implements the Instruction Assemble method.

                                                          func (LoadConstant) String

                                                          func (a LoadConstant) String() string

                                                            String returns the instruction in assembler notation.

                                                            type LoadExtension

                                                            type LoadExtension struct {
                                                            	Num Extension
                                                            }

                                                              LoadExtension invokes a linux-specific extension and stores the result in register A.

                                                              func (LoadExtension) Assemble

                                                              func (a LoadExtension) Assemble() (RawInstruction, error)

                                                                Assemble implements the Instruction Assemble method.

                                                                func (LoadExtension) String

                                                                func (a LoadExtension) String() string

                                                                  String returns the instruction in assembler notation.

                                                                  type LoadIndirect

                                                                  type LoadIndirect struct {
                                                                  	Off  uint32
                                                                  	Size int // 1, 2 or 4
                                                                  }

                                                                    LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value into register A.

                                                                    func (LoadIndirect) Assemble

                                                                    func (a LoadIndirect) Assemble() (RawInstruction, error)

                                                                      Assemble implements the Instruction Assemble method.

                                                                      func (LoadIndirect) String

                                                                      func (a LoadIndirect) String() string

                                                                        String returns the instruction in assembler notation.

                                                                        type LoadMemShift

                                                                        type LoadMemShift struct {
                                                                        	Off uint32
                                                                        }

                                                                          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.

                                                                          func (LoadMemShift) Assemble

                                                                          func (a LoadMemShift) Assemble() (RawInstruction, error)

                                                                            Assemble implements the Instruction Assemble method.

                                                                            func (LoadMemShift) String

                                                                            func (a LoadMemShift) String() string

                                                                              String returns the instruction in assembler notation.

                                                                              type LoadScratch

                                                                              type LoadScratch struct {
                                                                              	Dst Register
                                                                              	N   int // 0-15
                                                                              }

                                                                                LoadScratch loads scratch[N] into register Dst.

                                                                                func (LoadScratch) Assemble

                                                                                func (a LoadScratch) Assemble() (RawInstruction, error)

                                                                                  Assemble implements the Instruction Assemble method.

                                                                                  func (LoadScratch) String

                                                                                  func (a LoadScratch) String() string

                                                                                    String returns the instruction in assembler notation.

                                                                                    type NegateA

                                                                                    type NegateA struct{}

                                                                                      NegateA executes A = -A.

                                                                                      func (NegateA) Assemble

                                                                                      func (a NegateA) Assemble() (RawInstruction, error)

                                                                                        Assemble implements the Instruction Assemble method.

                                                                                        func (NegateA) String

                                                                                        func (a NegateA) String() string

                                                                                          String returns the instruction in assembler notation.

                                                                                          type RawInstruction

                                                                                          type RawInstruction struct {
                                                                                          	// Operation to execute.
                                                                                          	Op uint16
                                                                                          	// For conditional jump instructions, the number of instructions
                                                                                          	// to skip if the condition is true/false.
                                                                                          	Jt uint8
                                                                                          	Jf uint8
                                                                                          	// Constant parameter. The meaning depends on the Op.
                                                                                          	K uint32
                                                                                          }

                                                                                            A RawInstruction is a raw BPF virtual machine instruction.

                                                                                            func Assemble

                                                                                            func Assemble(insts []Instruction) ([]RawInstruction, error)

                                                                                              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.

                                                                                              func (RawInstruction) Assemble

                                                                                              func (ri RawInstruction) Assemble() (RawInstruction, error)

                                                                                                Assemble implements the Instruction Assemble method.

                                                                                                func (RawInstruction) Disassemble

                                                                                                func (ri RawInstruction) Disassemble() Instruction

                                                                                                  Disassemble parses ri into an Instruction and returns it. If ri is not recognized by this package, ri itself is returned.

                                                                                                  type Register

                                                                                                  type Register uint16

                                                                                                    A Register is a register of the BPF virtual machine.

                                                                                                    const (
                                                                                                    	// RegA is the accumulator register. RegA is always the
                                                                                                    	// destination register of ALU operations.
                                                                                                    	RegA Register = iota
                                                                                                    	// RegX is the indirection register, used by LoadIndirect
                                                                                                    	// operations.
                                                                                                    	RegX
                                                                                                    )

                                                                                                    type RetA

                                                                                                    type RetA struct{}

                                                                                                      RetA exits the BPF program, returning the value of register A.

                                                                                                      func (RetA) Assemble

                                                                                                      func (a RetA) Assemble() (RawInstruction, error)

                                                                                                        Assemble implements the Instruction Assemble method.

                                                                                                        func (RetA) String

                                                                                                        func (a RetA) String() string

                                                                                                          String returns the instruction in assembler notation.

                                                                                                          type RetConstant

                                                                                                          type RetConstant struct {
                                                                                                          	Val uint32
                                                                                                          }

                                                                                                            RetConstant exits the BPF program, returning a constant value.

                                                                                                            func (RetConstant) Assemble

                                                                                                            func (a RetConstant) Assemble() (RawInstruction, error)

                                                                                                              Assemble implements the Instruction Assemble method.

                                                                                                              func (RetConstant) String

                                                                                                              func (a RetConstant) String() string

                                                                                                                String returns the instruction in assembler notation.

                                                                                                                type Setter

                                                                                                                type Setter interface {
                                                                                                                	SetBPF(filter []RawInstruction) error
                                                                                                                }

                                                                                                                  A Setter is a type which can attach a compiled BPF filter to itself.

                                                                                                                  type StoreScratch

                                                                                                                  type StoreScratch struct {
                                                                                                                  	Src Register
                                                                                                                  	N   int // 0-15
                                                                                                                  }

                                                                                                                    StoreScratch stores register Src into scratch[N].

                                                                                                                    func (StoreScratch) Assemble

                                                                                                                    func (a StoreScratch) Assemble() (RawInstruction, error)

                                                                                                                      Assemble implements the Instruction Assemble method.

                                                                                                                      func (StoreScratch) String

                                                                                                                      func (a StoreScratch) String() string

                                                                                                                        String returns the instruction in assembler notation.

                                                                                                                        type TAX

                                                                                                                        type TAX struct{}

                                                                                                                          TAX copies the value of register A to register X.

                                                                                                                          func (TAX) Assemble

                                                                                                                          func (a TAX) Assemble() (RawInstruction, error)

                                                                                                                            Assemble implements the Instruction Assemble method.

                                                                                                                            func (TAX) String

                                                                                                                            func (a TAX) String() string

                                                                                                                              String returns the instruction in assembler notation.

                                                                                                                              type TXA

                                                                                                                              type TXA struct{}

                                                                                                                                TXA copies the value of register X to register A.

                                                                                                                                func (TXA) Assemble

                                                                                                                                func (a TXA) Assemble() (RawInstruction, error)

                                                                                                                                  Assemble implements the Instruction Assemble method.

                                                                                                                                  func (TXA) String

                                                                                                                                  func (a TXA) String() string

                                                                                                                                    String returns the instruction in assembler notation.

                                                                                                                                    type VM

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

                                                                                                                                      A VM is an emulated BPF virtual machine.

                                                                                                                                      func NewVM

                                                                                                                                      func NewVM(filter []Instruction) (*VM, error)

                                                                                                                                        NewVM returns a new VM using the input BPF program.

                                                                                                                                        Example

                                                                                                                                          ExampleNewVM demonstrates usage of a VM, using an Ethernet frame as input and checking its EtherType to determine if it should be accepted.

                                                                                                                                          Output:
                                                                                                                                          
                                                                                                                                          out: 14 bytes
                                                                                                                                          

                                                                                                                                          func (*VM) Run

                                                                                                                                          func (v *VM) Run(in []byte) (int, error)

                                                                                                                                            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.