Documentation ¶
Index ¶
- Constants
- func GetNativeEndianness() binary.ByteOrder
- func RegisterContextUnmarshaller(ctxType string, fn ContextUnmarshaller)
- type CapturedContext
- type CapturedContextHelperCall
- type CapturedContextRegisterData
- type Context
- type ContextUnmarshaller
- type Emulator
- type FlowKeys
- type GenericContext
- type GenericContextInt
- type GenericContextMemory
- type GenericContextMemoryBlock
- type GenericContextPointer
- type GenericContextRegisters
- type GenericContextStruct
- type GenericContextStructField
- type HelperFunction
- type LinuxArrayMap
- func (m *LinuxArrayMap) GetSpec() ebpf.MapSpec
- func (m *LinuxArrayMap) Indices() int
- func (m *LinuxArrayMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxArrayMap) Keys(cpuid int) []byte
- func (m *LinuxArrayMap) Load(offset uint32, size asm.Size) (uint64, error)
- func (m *LinuxArrayMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxArrayMap) Read(offset uint32, b []byte) error
- func (m *LinuxArrayMap) Store(offset uint32, value uint64, size asm.Size) error
- func (m *LinuxArrayMap) Update(key []byte, value []byte, flags uint32, cpuid int) error
- func (m *LinuxArrayMap) UpdateObject(key []byte, value LinuxMap, flags uint32) error
- func (m *LinuxArrayMap) Write(offset uint32, b []byte) error
- type LinuxContextSKBuff
- type LinuxContextXDP
- type LinuxEmuProcValKey
- type LinuxEmulator
- func (le *LinuxEmulator) AddMap(name string, m LinuxMap) error
- func (le *LinuxEmulator) CallHelperFunction(helperNr int32, p *Process) error
- func (le *LinuxEmulator) CustomInstruction(inst asm.Instruction, process *Process) error
- func (le *LinuxEmulator) RewriteProgram(program *ebpf.ProgramSpec) error
- func (le *LinuxEmulator) SetVM(vm *VM)
- type LinuxEmulatorOpts
- type LinuxEmulatorSettings
- type LinuxHashMap
- func (m *LinuxHashMap) Delete(key []byte) error
- func (m *LinuxHashMap) GetSpec() ebpf.MapSpec
- func (m *LinuxHashMap) Indices() int
- func (m *LinuxHashMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxHashMap) Keys(cpuid int) []byte
- func (m *LinuxHashMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxHashMap) Update(key []byte, value []byte, flags uint32, cpuid int) error
- func (m *LinuxHashMap) UpdateObject(key []byte, value LinuxMap, flags uint32) error
- type LinuxLRUHashMap
- func (m *LinuxLRUHashMap) Delete(key []byte) error
- func (m *LinuxLRUHashMap) GetSpec() ebpf.MapSpec
- func (m *LinuxLRUHashMap) Indices() int
- func (m *LinuxLRUHashMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxLRUHashMap) Keys(cpuid int) []byte
- func (m *LinuxLRUHashMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxLRUHashMap) Update(key []byte, value []byte, flags uint32, cpuid int) error
- type LinuxMap
- type LinuxMapDeleter
- type LinuxMapPopper
- type LinuxMapPusher
- type LinuxMapUpdater
- type LinuxPerCPUArrayMap
- func (m *LinuxPerCPUArrayMap) GetSpec() ebpf.MapSpec
- func (m *LinuxPerCPUArrayMap) Indices() int
- func (m *LinuxPerCPUArrayMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxPerCPUArrayMap) Keys(cpuid int) []byte
- func (m *LinuxPerCPUArrayMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxPerCPUArrayMap) Update(key []byte, value []byte, flags uint32, cpuid int) error
- type LinuxPerCPUHashMap
- func (m *LinuxPerCPUHashMap) Delete(key []byte) error
- func (m *LinuxPerCPUHashMap) GetSpec() ebpf.MapSpec
- func (m *LinuxPerCPUHashMap) Indices() int
- func (m *LinuxPerCPUHashMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxPerCPUHashMap) Keys(cpuid int) []byte
- func (m *LinuxPerCPUHashMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxPerCPUHashMap) Update(key []byte, value []byte, flags uint32, cpuid int) error
- func (m *LinuxPerCPUHashMap) UpdateObject(key []byte, value LinuxMap, flags uint32) error
- type LinuxPerfEventArrayMap
- func (m *LinuxPerfEventArrayMap) GetSpec() ebpf.MapSpec
- func (m *LinuxPerfEventArrayMap) Indices() int
- func (m *LinuxPerfEventArrayMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxPerfEventArrayMap) Keys(cpuid int) []byte
- func (m *LinuxPerfEventArrayMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxPerfEventArrayMap) Pop(cpuid int) ([]byte, error)
- func (m *LinuxPerfEventArrayMap) Push(value []byte, cpuid int) error
- type LinuxQueueMap
- func (m *LinuxQueueMap) GetSpec() ebpf.MapSpec
- func (m *LinuxQueueMap) Indices() int
- func (m *LinuxQueueMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxQueueMap) Keys(cpuid int) []byte
- func (m *LinuxQueueMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxQueueMap) Pop(cpuid int) (uint32, error)
- func (m *LinuxQueueMap) Push(value []byte, cpuid int) error
- type LinuxStackMap
- func (m *LinuxStackMap) GetSpec() ebpf.MapSpec
- func (m *LinuxStackMap) Indices() int
- func (m *LinuxStackMap) Init(emulator *LinuxEmulator) error
- func (m *LinuxStackMap) Keys(cpuid int) []byte
- func (m *LinuxStackMap) Lookup(key []byte, cpuid int) (uint32, error)
- func (m *LinuxStackMap) Pop(cpuid int) (uint32, error)
- func (m *LinuxStackMap) Push(value []byte, cpuid int) error
- type MemoryController
- func (mc *MemoryController) AddEntry(obj interface{}, size uint32, name string) (MemoryEntry, error)
- func (mc *MemoryController) DelEntryByAddr(addr uint32) error
- func (mc *MemoryController) DelEntryByObj(obj interface{}) error
- func (mc *MemoryController) GetAllEntries() []MemoryEntry
- func (mc *MemoryController) GetEntry(addr uint32) (MemoryEntry, uint32, bool)
- func (mc *MemoryController) GetEntryByObject(obj interface{}) (MemoryEntry, bool)
- func (mc *MemoryController) String() string
- type MemoryEntry
- type NetDev
- type PlainMemory
- type Process
- type ProcessPool
- type ProcessPoolJob
- type Registers
- type RingMemory
- type SK
- func (sk *SK) Load(offset uint32, size asm.Size) (uint64, error)
- func (sk *SK) Read(offset uint32, b []byte) error
- func (sk *SK) Size() int
- func (sk *SK) Store(offset uint32, value uint64, size asm.Size) error
- func (sk *SK) UnmarshalJSON(b []byte) error
- func (sk *SK) Write(offset uint32, b []byte) error
- type SKBuff
- type VM
- type VMMem
- type VMOpt
- type VMSettings
Constants ¶
const ( AF_UNSPEC = 0x0 BPF_TCP_CLOSE = 0x7 AF_INET = 0x2 AF_INET6 = 0xa )
Define unix constants here, since we can't import sys/unix on windows
Variables ¶
This section is empty.
Functions ¶
func GetNativeEndianness ¶
GetNativeEndianness returns the binary.ByteOrder matching the endianess of the current machine
func RegisterContextUnmarshaller ¶
func RegisterContextUnmarshaller(ctxType string, fn ContextUnmarshaller)
RegisterContextUnmarshaller is used to register custom context type unmarshallers which will be invoked by UnmarshalContextJSON if any context is passed in with "type" set to `ctxType`.
Types ¶
type CapturedContext ¶ added in v0.0.6
type CapturedContext struct { Sub Context `json:"-"` RawSub json.RawMessage `json:"subContext"` HelperCalls map[string][]CapturedContextHelperCall `json:"helperCalls"` }
CapturedContext wraps another context and adds captured helper call data to it which the LinuxEmulator can use to replay helper calls instead of actually emulating them, or doing both in some cases.
func (*CapturedContext) Cleanup ¶ added in v0.0.6
func (cc *CapturedContext) Cleanup(process *Process) error
Cleanup cleans up the allocated memory of the sub-context
func (*CapturedContext) GetName ¶ added in v0.0.6
func (cc *CapturedContext) GetName() string
GetName returns the name of the context
func (*CapturedContext) Load ¶ added in v0.0.6
func (cc *CapturedContext) Load(process *Process) error
Load loads the sub-context into memory
func (*CapturedContext) MarshalJSON ¶ added in v0.0.6
func (cc *CapturedContext) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*CapturedContext) SetName ¶ added in v0.0.6
func (cc *CapturedContext) SetName(name string)
SetName sets the name of the context
type CapturedContextHelperCall ¶ added in v0.0.6
type CapturedContextHelperCall struct { HelperFn asm.BuiltinFunc `json:"helperFn"` Params []CapturedContextRegisterData `json:"params"` Result []CapturedContextRegisterData `json:"results"` }
CapturedContextHelperCall describes a single call to a helper function
type CapturedContextRegisterData ¶ added in v0.0.6
type CapturedContextRegisterData struct { Reg asm.Register `json:"reg"` Value json.RawMessage `json:"value"` Scalar uint64 `json:"-"` Data []byte `json:"-"` }
CapturedContextRegisterData describes the contexts of a register
func (*CapturedContextRegisterData) MarshalJSON ¶ added in v0.0.6
func (crd *CapturedContextRegisterData) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*CapturedContextRegisterData) UnmarshalJSON ¶ added in v0.0.6
func (crd *CapturedContextRegisterData) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
type Context ¶
type Context interface { SetName(string) GetName() string // Load is called when a new process is started, the context is expected to construct a memory object to be passed // to the program, register it in the memory controller and set initial argument registers(R1-R5) Load(process *Process) error // Cleanup is called when a process exists, the Context is expected to delete all its memory from the memory // controller. Cleanup(process *Process) error }
Context describes a object which provides all information needed to emulate a specific eBPF environment. A context contains both the initial arguments(R1-R5) of a eBPF program as well as data which can be used by the emulator in helper functions.
func UnmarshalContextJSON ¶
UnmarshalContextJSON attempts to unmarshal json into a Context. This function expects the top level element to be a object with "name" and "type" string fields where "type" is a unique name of the context type. The "ctx" field should contain the context type specific object.
Custom context types can also be decoded, additional unmarshallers can be added with the RegisterContextUnmarshaller function.
type ContextUnmarshaller ¶
type ContextUnmarshaller func(name string, ctx json.RawMessage) (Context, error)
ContextUnmarshaller unmarshals JSON into a specific context
type Emulator ¶
type Emulator interface { // SetVM is called when an emulator is linked to a VM, this allows the emulator to save a reference // so it can access information about the VM like the memory controller. SetVM(vm *VM) // CallHelperFunction is called when a process executes a call to a helper function. The emulator must make sure // that this call is thread-safe in go-land, meaning that we should not allow raceconditions in the vm/emulator. // However, eBPF programs are themselves responsible for race-conditions in VM memory. // // If this function returns an error, a un-graceful error is assumed which will abort further execution of the // program and forwards the error to the process callee. Helper functions can also define graceful errors, which // can be returned to the calling program by setting the R0 register for example. CallHelperFunction(helperNr int32, p *Process) error // CustomInstruction is called when a process encounters an instruction that is not implemented by the VM. This // allows the emulator to implement custom eBPF CPU instructions as long as the opcode is not already in use. CustomInstruction(inst asm.Instruction, process *Process) error // RewriteProgram is called when a program is loaded into the VM. At this point the emulator may rewrite parts // of the program with emulator specific references, map addresses for example. If an error is returned the program // loading is halted. RewriteProgram(program *ebpf.ProgramSpec) error }
Emulator describes a struct which implements eBPF features which are specific to a certain environment.
type FlowKeys ¶ added in v0.0.5
type FlowKeys struct { Nhoff uint16 `json:"nhoff"` Thoff uint16 `json:"thoff"` // ETH_P_* of valid addrs AddrProto uint16 `json:"addrProto"` IsFrag uint8 `json:"isFrag"` IsFirstFrag uint8 `json:"isFirstFrag"` IsEncap uint8 `json:"isEncap"` IPProto uint8 `json:"ipProto"` NProto uint16 `json:"nProto"` Sport uint16 `json:"sport"` Dport uint16 `json:"dport"` SrcIPv6orIPv4 net.IP `json:"ip"` Flags uint32 `json:"flags"` FlowLabel uint32 `json:"flowLabel"` }
FlowKeys describe the flow information of a sk_buff
func (*FlowKeys) Load ¶ added in v0.0.5
Load reads a single integer value of 1, 2, 4 or 8 bytes at a specific offset
func (*FlowKeys) Read ¶ added in v0.0.5
Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size
type GenericContext ¶
type GenericContext struct { Name string `json:"-"` Registers GenericContextRegisters `json:"registers"` Memory []GenericContextMemory `json:"memory"` EmulatorRaw map[string]json.RawMessage `json:"emulator"` Emulator map[string]interface{} `json:"-"` // contains filtered or unexported fields }
GenericContext implements mimic.Context. The goal of GenericContext and its GenericContext... struct types is to provide a method to construct any type of eBPF context. Being generic also means we have to be very verbose which is not always desirable, it is recommended to use specific contexts whenever possible, but this type can always be used as a fallback in situations where no specific context type exists.
func (*GenericContext) Cleanup ¶
func (c *GenericContext) Cleanup(process *Process) error
Cleanup cleans up the context, the process call this function the Process.Cleanup is called, users should not have to manually call this function. Cleaning up the context will remove the associated memory from the processes memory controller and make the context ready to be re-used/re-loaded.
func (*GenericContext) GetName ¶
func (c *GenericContext) GetName() string
GetName returns the name of the context
func (*GenericContext) Load ¶
func (c *GenericContext) Load(process *Process) error
Load loads the context into a process. Load is called by the VM when creating a new process, users don't have to call this function manually. Loading a context into a process will register memory for the context at the memory controller of the VM.
func (*GenericContext) MarshalJSON ¶
func (c *GenericContext) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*GenericContext) SetName ¶ added in v0.0.6
func (c *GenericContext) SetName(name string)
SetName sets the name of the context
type GenericContextInt ¶
GenericContextInt is a memory object describing a interger value of a specific bit size(8, 16, 32, or 64).
func (*GenericContextInt) GetValue ¶
func (i *GenericContextInt) GetValue() ([]byte, error)
GetValue returns the bytes for the given integer in the native byte order.
type GenericContextMemory ¶
type GenericContextMemory struct { Name string `json:"name"` Type string `json:"type"` RawValue json.RawMessage `json:"value"` Block *GenericContextMemoryBlock `json:"-"` Pointer *GenericContextPointer `json:"-"` Struct *GenericContextStruct `json:"-"` Int *GenericContextInt `json:"-"` }
GenericContextMemory represents a named memory object in the generic context, which can be one of multiple actual different memory types. The name for each type within a generic context should be unique.
func (*GenericContextMemory) MarshalJSON ¶
func (m *GenericContextMemory) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*GenericContextMemory) UnmarshalJSON ¶
func (m *GenericContextMemory) UnmarshalJSON(b []byte) error
UnmarshalJSON implements json.Unmarshaler
type GenericContextMemoryBlock ¶
type GenericContextMemoryBlock struct { Value []byte ByteOrder binary.ByteOrder // contains filtered or unexported fields }
GenericContextMemoryBlock is a block of memory, the `Value` will be loaded into the memory controller as a PlainMemory object.
func (*GenericContextMemoryBlock) Cleanup ¶
func (m *GenericContextMemoryBlock) Cleanup(p *Process) error
Cleanup will remove the memory block from the memory controller of the given process.
func (*GenericContextMemoryBlock) GetAddr ¶
func (m *GenericContextMemoryBlock) GetAddr(p *Process, g *GenericContextMemory) (uint32, error)
GetAddr returns the virtual address of block of memory within the process. If the block is not yet loaded, calling this function will cause the load. If the block was already loaded, the existing memory address is returned.
func (*GenericContextMemoryBlock) MarshalJSON ¶
func (m *GenericContextMemoryBlock) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*GenericContextMemoryBlock) UnmarshalJSON ¶
func (m *GenericContextMemoryBlock) UnmarshalJSON(b []byte) error
UnmarshalJSON implements json.Unmarshaler
type GenericContextPointer ¶
type GenericContextPointer struct { Memory string `json:"memory"` Offset int `json:"offset"` Size int `json:"size"` }
GenericContextPointer is a pointer to other memory defined in GenericContext.Memory. Offset is the offset from the start of the memory block in bytes and Size is the size of the pointer in bits(32 or 64). Pointers can only point to "block" and "struct" memory objects.
func (*GenericContextPointer) GetValue ¶
func (ptr *GenericContextPointer) GetValue(p *Process, g *GenericContext) (uint32, error)
GetValue returns the value of the pointer(the address of the memory we point to plus the allocation)
type GenericContextRegisters ¶
type GenericContextRegisters struct { R1 string `json:"r1,omitempty"` R2 string `json:"r2,omitempty"` R3 string `json:"r3,omitempty"` R4 string `json:"r4,omitempty"` R5 string `json:"r5,omitempty"` }
GenericContextRegisters are registers which the generic context can set when loading
type GenericContextStruct ¶
type GenericContextStruct struct { Fields []GenericContextStructField // contains filtered or unexported fields }
GenericContextStruct is a memory object which describes a memory structure which can be translated into a PlainMemory object and loaded into the memory controller of a process.
func (*GenericContextStruct) Cleanup ¶
func (s *GenericContextStruct) Cleanup(p *Process) error
Cleanup removes the structure from the processes memory controller
func (*GenericContextStruct) GetAddr ¶
func (s *GenericContextStruct) GetAddr(p *Process, g *GenericContext, m *GenericContextMemory) (uint32, error)
GetAddr returns the virtual address of the structure. The call to this function will cause the struct to be registered with the memory controller of the process, subsequent calls will return the same address.
func (*GenericContextStruct) MarshalJSON ¶
func (s *GenericContextStruct) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*GenericContextStruct) UnmarshalJSON ¶
func (s *GenericContextStruct) UnmarshalJSON(b []byte) error
UnmarshalJSON implements json.Unmarshaler
type GenericContextStructField ¶
GenericContextStructField describes a field of GenericContextStruct
type HelperFunction ¶
HelperFunction is a function defined in Go which can be invoked by the eBPF VM via the Call instruction. The emulator has a lookup map which maps a particular number to a helper function. Helper functions are used as a interface between the sandboxed eBPF VM and the Emulator/Host/Outside world. Helper functions are responsible for security checks and should implement policies or other forms of limitations to guarantee that eBPF code can't be used for malicious purposes.
Helper functions are called with eBPF calling convention, meaning R1-R5 are arguments, and R0 is the return value. Errors returned by the helper are considered fatal for the process, are passed to the process and will result in it aborting. Recoverable errors/graceful errors should be returned to the VM via the R0 register and a helper func specific contract.
type LinuxArrayMap ¶
LinuxArrayMap is the emulated version of ebpf.Array / BPF_MAP_TYPE_ARRAY. Array maps have 4 byte integer keys from 0 to Spec.MaxEntries with arbitrary values
func (*LinuxArrayMap) GetSpec ¶
func (m *LinuxArrayMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxArrayMap) Indices ¶ added in v0.0.3
func (m *LinuxArrayMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxArrayMap) Init ¶
func (m *LinuxArrayMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxArrayMap) Keys ¶
func (m *LinuxArrayMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
func (*LinuxArrayMap) Load ¶ added in v0.0.10
Load reads a single integer value of 1, 2, 4 or 8 bytes at a specific offset
func (*LinuxArrayMap) Lookup ¶
func (m *LinuxArrayMap) Lookup(key []byte, cpuid int) (uint32, error)
Lookup returns the virtual memory offset to the map value or 0 if no value can be found for the given key.
func (*LinuxArrayMap) Read ¶ added in v0.0.10
func (m *LinuxArrayMap) Read(offset uint32, b []byte) error
Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size
func (*LinuxArrayMap) Store ¶ added in v0.0.10
Store write a single interger value of 1, 2, 4 or 8 bytes to a specific offset
func (*LinuxArrayMap) Update ¶
Update updates an existing value in the map, or add a new value if it didn't exist before.
func (*LinuxArrayMap) UpdateObject ¶ added in v0.0.3
func (m *LinuxArrayMap) UpdateObject(key []byte, value LinuxMap, flags uint32) error
UpdateObject is similar to Update, accept it take a arbitrary go interface{} as value. The virtual address of the object will be stored in the map. The map must have a value size of 4 bytes and the object must already be registered with the VMs memory controller.
type LinuxContextSKBuff ¶ added in v0.0.5
type LinuxContextSKBuff struct { Name string `json:"-"` Packet []byte `json:"packet"` SK *SK `json:"sock"` Dev *NetDev `json:"dev"` FlowKeys *FlowKeys `json:"flowKeys"` // contains filtered or unexported fields }
LinuxContextSKBuff is a context for skb programs
func (*LinuxContextSKBuff) Cleanup ¶ added in v0.0.5
func (c *LinuxContextSKBuff) Cleanup(process *Process) error
Cleanup removes the context from the processes memory and makes the context ready to be re-used/re-loaded.
func (*LinuxContextSKBuff) GetName ¶ added in v0.0.5
func (c *LinuxContextSKBuff) GetName() string
GetName return the context name
func (*LinuxContextSKBuff) Load ¶ added in v0.0.5
func (c *LinuxContextSKBuff) Load(process *Process) error
Load load the context into the memory of the process
func (*LinuxContextSKBuff) SetName ¶ added in v0.0.6
func (c *LinuxContextSKBuff) SetName(name string)
SetName sets the name of the context
type LinuxContextXDP ¶
type LinuxContextXDP struct { Name string `json:"-"` Headroom int `json:"headroom"` Tailroom int `json:"tailroom"` Packet []byte `json:"packet"` IngessIfIndex int32 `json:"ingress_ifidx"` RxQueueIndex int32 `json:"rx_queue_idx"` EgressIfIndex int32 `json:"egress_ifidx"` // contains filtered or unexported fields }
LinuxContextXDP is a specialized context type for XDP programs.
func (*LinuxContextXDP) Cleanup ¶
func (c *LinuxContextXDP) Cleanup(process *Process) error
Cleanup removes the context from the processes memory and makes the context ready to be re-used/re-loaded.
func (*LinuxContextXDP) GetName ¶
func (c *LinuxContextXDP) GetName() string
GetName return the context name
func (*LinuxContextXDP) Load ¶
func (c *LinuxContextXDP) Load(process *Process) error
Load load the context into the memory of the process
func (*LinuxContextXDP) SetName ¶ added in v0.0.6
func (c *LinuxContextXDP) SetName(name string)
SetName set the name of the context
type LinuxEmuProcValKey ¶ added in v0.0.2
type LinuxEmuProcValKey int
LinuxEmuProcValKey is a enum values which is used as the key to the Process.EmulatorValues maps when a LinuxEmulator is used.
const ( // LinuxEmuProcValKeyTailcalls tracks the amount of tailcalls which a process has made. LinuxEmuProcValKeyTailcalls LinuxEmuProcValKey = iota )
func (LinuxEmuProcValKey) String ¶ added in v0.0.2
func (v LinuxEmuProcValKey) String() string
type LinuxEmulator ¶
LinuxEmulator implements Emulator, and attempts to emulate all Linux specific eBPF features.
func NewLinuxEmulator ¶ added in v0.0.2
func NewLinuxEmulator(opts ...LinuxEmulatorOpts) *LinuxEmulator
NewLinuxEmulator create a new LinuxEmulator from the given options.
func (*LinuxEmulator) AddMap ¶
func (le *LinuxEmulator) AddMap(name string, m LinuxMap) error
AddMap adds a map to the emulator.
func (*LinuxEmulator) CallHelperFunction ¶
func (le *LinuxEmulator) CallHelperFunction(helperNr int32, p *Process) error
CallHelperFunction is called by the VM when it wants to execute a helper function.
func (*LinuxEmulator) CustomInstruction ¶ added in v0.0.5
func (le *LinuxEmulator) CustomInstruction(inst asm.Instruction, process *Process) error
CustomInstruction is called by the VM when it encounters a unimplemented CPU instruction, giving the emulator a chance to provide an implementation.
func (*LinuxEmulator) RewriteProgram ¶
func (le *LinuxEmulator) RewriteProgram(program *ebpf.ProgramSpec) error
RewriteProgram is called by the VM when adding a program to it. It allows us to rewrite program instructions. In this case we rewrite map load instructions to have the virtual addresess of the map to which the refer.
func (*LinuxEmulator) SetVM ¶
func (le *LinuxEmulator) SetVM(vm *VM)
SetVM is called by VM when attaching the emulator to the VM, it allows the emulator to store a reference to the VM to which is is attached.
type LinuxEmulatorOpts ¶ added in v0.0.2
type LinuxEmulatorOpts func(*LinuxEmulatorSettings)
LinuxEmulatorOpts are options which can be passed to NewLinuxEmulator to modify the default settings.
func OptMaxTailCalls ¶ added in v0.0.2
func OptMaxTailCalls(max int) LinuxEmulatorOpts
OptMaxTailCalls is a option to change the max amount of tailcalls a process is allowed to make
func OptRngSeed ¶ added in v0.0.3
func OptRngSeed(seed int64) LinuxEmulatorOpts
OptRngSeed sets the seed for the random number generator used for bpf_get_prandom_u32.
type LinuxEmulatorSettings ¶ added in v0.0.2
type LinuxEmulatorSettings struct { // The maximum amount of tailcalls a process can make, a security feature in the Linux kernel to avoid // infinite tailcall loops. MaxTailCalls int // The seed used by the pseudo random number generator for the bpf_get_prandom_u32 function. // Is set to the current nanoseconds since system boot, but can be set to a custom value to make the the emulator // predictable. RandomSeed int64 // The boot time of the emulator, is the boot time of the host by default, can be set so behavior is predictable. // Value is used to calculate time since boot for bpf_ktime_get_ns helper function. TimeOfBoot time.Time // The size of the perf event ring buffer per cpu. When allocating memory for a MAP_TYPE_PERF_EVENT_ARRAY, this // is the number of bytes per cpu reserved. This value is always rounded up to the nearest multiple of the // systems page size. PerfEventBufferSize int }
LinuxEmulatorSettings are settings used by LinuxEmulator, which can be updated by
type LinuxHashMap ¶
type LinuxHashMap struct { Spec *ebpf.MapSpec KeyToIndex map[[sha256.Size]byte]int // contains filtered or unexported fields }
LinuxHashMap is the emulated version of ebpf.Hash / BPF_MAP_TYPE_HASH. Hash maps have arbitrary keys and values.
func (*LinuxHashMap) Delete ¶
func (m *LinuxHashMap) Delete(key []byte) error
Delete deletes a values from the map
func (*LinuxHashMap) GetSpec ¶
func (m *LinuxHashMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxHashMap) Indices ¶ added in v0.0.3
func (m *LinuxHashMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxHashMap) Init ¶
func (m *LinuxHashMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxHashMap) Keys ¶
func (m *LinuxHashMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
func (*LinuxHashMap) Lookup ¶
func (m *LinuxHashMap) Lookup(key []byte, cpuid int) (uint32, error)
Lookup returns the virtual memory offset to the map value or 0 if no value can be found for the given key.
func (*LinuxHashMap) Update ¶
Update updates an existing value in the map, or add a new value if it didn't exist before.
func (*LinuxHashMap) UpdateObject ¶ added in v0.0.3
func (m *LinuxHashMap) UpdateObject(key []byte, value LinuxMap, flags uint32) error
UpdateObject is similar to Update, accept it take a arbitrary go interface{} as value. The virtual address of the object will be stored in the map. The map must have a value size of 4 bytes and the object must already be registered with the VMs memory controller.
type LinuxLRUHashMap ¶
LinuxLRUHashMap is the emulated version of ebpf.LRUHash / BPF_MAP_TYPE_LRU_HASH. This map type is a normal hash map which also records which map values are the Least Recently Used. If the map is full and a new value is added, this map type will discard the Least Recently Used value from the map to make room for the new value instread of returning a "out of memory" error.
func (*LinuxLRUHashMap) Delete ¶
func (m *LinuxLRUHashMap) Delete(key []byte) error
Delete deletes a key from the map.
func (*LinuxLRUHashMap) GetSpec ¶
func (m *LinuxLRUHashMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxLRUHashMap) Indices ¶ added in v0.0.3
func (m *LinuxLRUHashMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxLRUHashMap) Init ¶
func (m *LinuxLRUHashMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxLRUHashMap) Keys ¶
func (m *LinuxLRUHashMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
type LinuxMap ¶
type LinuxMap interface { Init(emulator *LinuxEmulator) error GetSpec() ebpf.MapSpec // Indices returns the amount of per-cpu indexes. Indices() int // Keys returns a byte slice containing all key values in their byte representation. The size is always a multiple // of the about of entries in the map and the key size. Keys(cpuid int) []byte // Lookup returns a pointer to a value matching the key, or NULL if no matching value can be found. // `key` must be the same length as defined in the map spec Lookup(key []byte, cpuid int) (uint32, error) }
LinuxMap is an interface which describes the common functions each map for the LinuxEmulator has. LinuxMaps are initialized by the LinuxEmulator upon being added to the emulator and are expected to be ready to store data after that. Every map type is expected to be able to return a list of valid keys and for these keys to be retrieved via Lookup, this is so the Host can always inspect the map contents. Other "actions" like modifying the maps are optional and have their own interfaces.
type LinuxMapDeleter ¶
type LinuxMapDeleter interface { // Delete takes a key, and removes it from the map Delete(key []byte) error }
LinuxMapDeleter describes a LinuxMap which can delete any value as long as the key is known.
type LinuxMapPopper ¶ added in v0.0.3
type LinuxMapPopper interface { // Pops a key-less value from a map Pop(cpuid int) (uint32, error) }
LinuxMapPopper describes a LinuxMap from which you can pop values without a key, deleting them from the map.
type LinuxMapPusher ¶ added in v0.0.3
type LinuxMapPusher interface { // Pushes a key-less value into a map Push(value []byte, cpuid int) error }
LinuxMapPusher describes a LinuxMap into which you can push values without a key.
type LinuxMapUpdater ¶
type LinuxMapUpdater interface { // Updates takes a key, value and flags, key and value slices must match the length of the key and value as defined // in the map spec. If successful nil is returned, graceful errors are of type syscall.Errno and can be forwarded // to the eBPF VM. Other error types are fatal. Update(key []byte, value []byte, flags uint32, cpuid int) error }
LinuxMapUpdater describes a LinuxMap which can update any value as long as the key is known.
type LinuxPerCPUArrayMap ¶ added in v0.0.3
LinuxPerCPUArrayMap is the emulated version of ebpf.PerCPUArray / BPF_MAP_TYPE_PERCPU_ARRAY. Array maps have 4 byte integer keys from 0 to Spec.MaxEntries, it value is the address of a map.
func (*LinuxPerCPUArrayMap) GetSpec ¶ added in v0.0.3
func (m *LinuxPerCPUArrayMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxPerCPUArrayMap) Indices ¶ added in v0.0.3
func (m *LinuxPerCPUArrayMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxPerCPUArrayMap) Init ¶ added in v0.0.3
func (m *LinuxPerCPUArrayMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxPerCPUArrayMap) Keys ¶ added in v0.0.3
func (m *LinuxPerCPUArrayMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
type LinuxPerCPUHashMap ¶ added in v0.0.3
type LinuxPerCPUHashMap struct { Spec *ebpf.MapSpec KeyToIndex map[[sha256.Size]byte]int // contains filtered or unexported fields }
LinuxPerCPUHashMap is the emulated version of ebpf.PerCPUHash / BPF_MAP_TYPE_PERCPU_HASH. Hash maps have arbitrary keys and values.
func (*LinuxPerCPUHashMap) Delete ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) Delete(key []byte) error
Delete deletes a values from the map
func (*LinuxPerCPUHashMap) GetSpec ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxPerCPUHashMap) Indices ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxPerCPUHashMap) Init ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxPerCPUHashMap) Keys ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
func (*LinuxPerCPUHashMap) Lookup ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) Lookup(key []byte, cpuid int) (uint32, error)
Lookup returns the virtual memory offset to the map value or 0 if no value can be found for the given key.
func (*LinuxPerCPUHashMap) Update ¶ added in v0.0.3
Update updates an existing value in the map, or add a new value if it didn't exist before.
func (*LinuxPerCPUHashMap) UpdateObject ¶ added in v0.0.3
func (m *LinuxPerCPUHashMap) UpdateObject(key []byte, value LinuxMap, flags uint32) error
UpdateObject is similar to Update, accept it take a arbitrary go interface{} as value. The virtual address of the object will be stored in the map. The map must have a value size of 4 bytes and the object must already be registered with the VMs memory controller.
type LinuxPerfEventArrayMap ¶ added in v0.0.3
LinuxPerfEventArrayMap is the emulated version of ebpf.PerfEventArray / BPF_MAP_TYPE_PERF_EVENT_ARRAY. This map type has no keys, the map has no set value size, each element can be of a different size.
func (*LinuxPerfEventArrayMap) GetSpec ¶ added in v0.0.3
func (m *LinuxPerfEventArrayMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxPerfEventArrayMap) Indices ¶ added in v0.0.3
func (m *LinuxPerfEventArrayMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxPerfEventArrayMap) Init ¶ added in v0.0.3
func (m *LinuxPerfEventArrayMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxPerfEventArrayMap) Keys ¶ added in v0.0.3
func (m *LinuxPerfEventArrayMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
func (*LinuxPerfEventArrayMap) Lookup ¶ added in v0.0.3
func (m *LinuxPerfEventArrayMap) Lookup(key []byte, cpuid int) (uint32, error)
Lookup returns the virtual memory offset to the map value or 0 if no value can be found for the given key.
type LinuxQueueMap ¶ added in v0.0.4
LinuxQueueMap is the emulated version of ebpf.Queue / BPF_MAP_TYPE_QUEUE. This map type has no keys, value sizes are fixed, but is configurable. This map type is a FIFO queue.
func (*LinuxQueueMap) GetSpec ¶ added in v0.0.4
func (m *LinuxQueueMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxQueueMap) Indices ¶ added in v0.0.4
func (m *LinuxQueueMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxQueueMap) Init ¶ added in v0.0.4
func (m *LinuxQueueMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxQueueMap) Keys ¶ added in v0.0.4
func (m *LinuxQueueMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
func (*LinuxQueueMap) Lookup ¶ added in v0.0.4
func (m *LinuxQueueMap) Lookup(key []byte, cpuid int) (uint32, error)
Lookup returns the virtual memory offset to the map value or 0 if no value can be found for the given key.
type LinuxStackMap ¶ added in v0.0.4
LinuxStackMap is the emulated version of ebpf.PerfEventArray / BPF_MAP_TYPE_PERF_EVENT_ARRAY. Array maps have 4 byte integer keys from 0 to Spec.MaxEntries with arbitrary values
func (*LinuxStackMap) GetSpec ¶ added in v0.0.4
func (m *LinuxStackMap) GetSpec() ebpf.MapSpec
GetSpec returns the specification of the map, part of the LinuxMap implementation
func (*LinuxStackMap) Indices ¶ added in v0.0.4
func (m *LinuxStackMap) Indices() int
Indices returns the amount of per-cpu indexes.
func (*LinuxStackMap) Init ¶ added in v0.0.4
func (m *LinuxStackMap) Init(emulator *LinuxEmulator) error
Init initializes the map, part of the LinuxMap implementation
func (*LinuxStackMap) Keys ¶ added in v0.0.4
func (m *LinuxStackMap) Keys(cpuid int) []byte
Keys returns a byte slice which contains all keys in the map, keys are packed, the user is expected to calculate the proper window into the slice based on the size of m.Spec.KeySize.
func (*LinuxStackMap) Lookup ¶ added in v0.0.4
func (m *LinuxStackMap) Lookup(key []byte, cpuid int) (uint32, error)
Lookup returns the virtual memory offset to the map value or 0 if no value can be found for the given key.
type MemoryController ¶
type MemoryController struct {
// contains filtered or unexported fields
}
MemoryController is used to link virtual addresses(uint64 values) to Go objects.
func (*MemoryController) AddEntry ¶
func (mc *MemoryController) AddEntry(obj interface{}, size uint32, name string) (MemoryEntry, error)
AddEntry adds a new memory entry to the controller.
func (*MemoryController) DelEntryByAddr ¶
func (mc *MemoryController) DelEntryByAddr(addr uint32) error
DelEntryByAddr deletes a memory entry by virtual address `addr`, which might be any value between the entries Addr and Addr+Size.
func (*MemoryController) DelEntryByObj ¶
func (mc *MemoryController) DelEntryByObj(obj interface{}) error
DelEntryByObj deletes the entry from the memory controller which resolves to the given object.
func (*MemoryController) GetAllEntries ¶
func (mc *MemoryController) GetAllEntries() []MemoryEntry
GetAllEntries returns all memory entries, the returned slice are copies of the actual entries so they can't be used to modify internal state.
func (*MemoryController) GetEntry ¶
func (mc *MemoryController) GetEntry(addr uint32) (MemoryEntry, uint32, bool)
GetEntry returns the memory entry matching the given virtual address. This method also returns the offset into the entry. An `addr` of 0x14 might for example resolve to an entry at 0x10 of size 8 and an offset of 0x04 into that entry. The last return value is a boolean which is true if an entry was found, and false if no entry was found.
func (*MemoryController) GetEntryByObject ¶
func (mc *MemoryController) GetEntryByObject(obj interface{}) (MemoryEntry, bool)
GetEntryByObject return the memory entry which points to the given object. The boolean indicates if a entry was found.
func (*MemoryController) String ¶
func (mc *MemoryController) String() string
String implements fmt.Stringer
type MemoryEntry ¶
MemoryEntry is returned by the MemoryController, each entry has a name `Which“ is used for debugging purposes. Virtual address `Addr`, allocation size `Size` and a `Object` which is what the `Addr` resolves to. Any virtual address between `Addr` and `Addr`+`Size` resolves to this entry.
func (MemoryEntry) Copy ¶
func (me MemoryEntry) Copy() MemoryEntry
Copy makes a value copy of the MemoryEntry, the new entry will still point to the same Object
type NetDev ¶ added in v0.0.5
type NetDev struct {
IFIndex uint32 `json:"ifIndex"`
}
NetDev represents a network device to which a socket / socket_buffer is connected
type PlainMemory ¶
PlainMemory is the simplest implementation of VMMem possible, it is just a []byte with no additional information about its contents. The ByteOrder is used when Load'in or Store'ing scalar values. If ByteOrder is not set the native endianness will be used.
func (*PlainMemory) Load ¶
Load loads a scalar value of the given `size` and `offset` from the memory.
func (*PlainMemory) Read ¶
func (pm *PlainMemory) Read(offset uint32, b []byte) error
Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size
type Process ¶
type Process struct { // The VM in which the process runs VM *VM // The current Program Program *ebpf.ProgramSpec // Stack of this process Stack PlainMemory // Context of the process Context Context // The registers of this process Registers Registers // A values which the the emulator can use to track process specific values EmulatorValues map[interface{}]interface{} // contains filtered or unexported fields }
Process describes an instance of a program executing, each process has its own registers and stack
func (*Process) Run ¶
Run runs the program until it exits, encounters a fatal error or the context is canceled/deadline expires
func (*Process) Step ¶
Step "steps" through one program instruction. If this function returns `exited` == true, it means that the program has stop execution, subsequent calls to Step will be ineffective. If `err` != nil, it means that a fatal error was encountered and that the process can't continue execution subsequent calls to Step will be ineffective.
type ProcessPool ¶ added in v0.0.3
type ProcessPool interface { Enqueue(job ProcessPoolJob, noblock bool) error Start(backlog int) error Stop() }
ProcessPool is a worker pool for processes. Once Start'ed processes can be submitted which will be ran on the workers each worker has its own virtual CPU ID, thus emulating an actual CPU. The processPool guarantees that no two processes will run with the same CPU ID, making programs which rely on that property to guard against race-conditions save to run. Starting the worker pool with the exact amount of logical CPUs on the host (runtime.NumCPU()) is also the most performant way to run eBPF programs which are non-blocking.
type ProcessPoolJob ¶ added in v0.0.3
type ProcessPoolJob struct { // The process to be executed Process *Process // The context with which the process is to be ran. Which can be used to cancel a particular process or to set // a deadline to limit its resource usage. Optional, if nil context.Background() is used. Context context.Context // When the process exits or errors, instread of cleaning it up, it will be handed off to this callback which will // be started in its own goroutine. This can be used to process the results, but is also responsible for the process // cleanup. Optional, if nil, the process is cleaned up by the pool. Handoff func(p *Process, err error) }
ProcessPoolJob is a job which can be scheduled with the process pool to be executed.
type Registers ¶
type Registers struct { // PC is the program counter, it keeps track of the next instruction to be executed by the current program. It is // a offset within the instruction slice. PC int // R0 is used as return values from helper functions, BPF-to-BPF calls and eBPF programs R0 uint64 // R1-R5 are used as arguments to a functions. R1 uint64 R2 uint64 R3 uint64 R4 uint64 R5 uint64 // R6-R9 are callee saved registers, when calling a helper or BPF-to-BPF function the callee will save the current // values of these registers and upon returning will restore them. R6 uint64 R7 uint64 R8 uint64 R9 uint64 // R10 contains a pointer to the end of the current stack frame, it is read-only, programs are not allowed to write // to this register, only copy its value and modify its copy. The frame pointer will be changed when calling into // a BPF-to-BPF function. Callees can pass the current frame pointer to the next function to allow that function // to access the frame pointer of the callee. R10 uint64 }
Registers describe the CPU registers of the VM
type RingMemory ¶ added in v0.0.3
RingMemory is very similar to PlainMemory, except RingMemory will wrap around to the start when reading or writing out of bounds.
func (*RingMemory) Load ¶ added in v0.0.3
Load loads a scalar value of the given `size` and `offset` from the memory.
func (*RingMemory) Read ¶ added in v0.0.3
func (pm *RingMemory) Read(offset uint32, b []byte) error
Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size
type SK ¶ added in v0.0.5
type SK struct { BoundDevIF uint32 `json:"boundDevIF"` Family uint32 `json:"family"` SockType uint32 `json:"sockType"` Protocol uint32 `json:"protocol"` Mark uint32 `json:"mark"` Priority uint32 `json:"priority"` SrcIP4 string `json:"srcIP4"` SrcIP6 string `json:"srcIP6"` SrcPort uint32 `json:"srcPort"` /* host byte order */ DstPort uint32 `json:"dstPort"` /* network byte order */ DstIP4 string `json:"dstIP4"` DstIP6 string `json:"dstIP6"` State uint32 `json:"state"` RXQueueMapping int32 `json:"rxQueueMapping"` // contains filtered or unexported fields }
SK https://elixir.bootlin.com/linux/v5.16.10/source/include/uapi/linux/bpf.h#L5406
func (*SK) Load ¶ added in v0.0.5
Load reads a single integer value of 1, 2, 4 or 8 bytes at a specific offset
func (*SK) Read ¶ added in v0.0.5
Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size
func (*SK) Size ¶ added in v0.0.5
Size returns the size of the bpf_sk (not the actual sk, but its virtual address proxy range)
func (*SK) Store ¶ added in v0.0.5
Store write a single interger value of 1, 2, 4 or 8 bytes to a specific offset
func (*SK) UnmarshalJSON ¶ added in v0.0.5
UnmarshalJSON implements json.Unmarshaler
type SKBuff ¶ added in v0.0.5
type SKBuff struct {
// contains filtered or unexported fields
}
SKBuff is an emulated version of the Linux socket buffer. A datastructure which Linux uses to keep track of packets received on a socket. A SKBuff is a metadata wrapper around the actual packet data, usually part of a linked list of other SKBuff objects. It contains a lot of pre-processes data which programs and pointers to the different network layers of the packet. https://elixir.bootlin.com/linux/v5.16.10/source/include/linux/skbuff.h#L731
eBPF programs can't directly access the sk_buff struct, rather the __sk_buff proxy is used. https://elixir.bootlin.com/linux/v5.16.10/source/include/uapi/linux/bpf.h#L5315 This object never actually exists it memory, just defined to provide the correct offset. When programs are loaded into the Linux kernel they are re-written to access the actual sk_buff, this provides API stability. https://elixir.bootlin.com/linux/v5.16.10/source/net/core/filter.c#L8548
This emulated version is not a perfect replica of the sk_buff, just aims to provide features required for eBPF emulation. Instread of re-writing the eBPF program, the SKBuff implements the VMMem interface, which internally will do the same conversion as the kernel does.
func SKBuffFromBytes ¶ added in v0.0.5
SKBuffFromBytes parses the packet and constructs a SKBuff from it.
Basically do the same as https://elixir.bootlin.com/linux/v5.16.10/source/net/bpf/test_run.c#L565
func (*SKBuff) Load ¶ added in v0.0.5
Load reads a single integer value of 1, 2, 4 or 8 bytes at a specific offset
func (*SKBuff) Read ¶ added in v0.0.5
Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size
func (*SKBuff) Size ¶ added in v0.0.5
Size returns the size of the __sk_buff (not the actual SKBuff, but its virtual address proxy range)
type VM ¶
type VM struct { MemoryController MemoryController // contains filtered or unexported fields }
VM is the eBPF virtual machine
func (*VM) AddProgram ¶
func (vm *VM) AddProgram(prog *ebpf.ProgramSpec) (int, error)
AddProgram adds a program to the VM. Doing so will cause the VM to rewrite the program to make it ready for execution. On success a unique identifier for the program is returned, which can be used in calls to NewProcess to specify the entrypoint program.
func (*VM) GetProcessPool ¶ added in v0.0.3
func (vm *VM) GetProcessPool() ProcessPool
GetProcessPool returns the process pool of the VM
func (*VM) GetPrograms ¶
func (vm *VM) GetPrograms() []*ebpf.ProgramSpec
GetPrograms returns the loaded program specs
type VMMem ¶
type VMMem interface { // Load reads a single integer value of 1, 2, 4 or 8 bytes at a specific offset Load(offset uint32, size asm.Size) (uint64, error) // Store write a single interger value of 1, 2, 4 or 8 bytes to a specific offset Store(offset uint32, value uint64, size asm.Size) error // Read reads a byte slice of arbitrary size, the length of 'b' is used to determine the requested size Read(offset uint32, b []byte) error // Write write a byte slice of arbitrary size to the memory Write(offset uint32, b []byte) error }
VMMem is memory which which the VM can access(read and write)
type VMOpt ¶
type VMOpt func(*VMSettings)
VMOpt is a option which can be used during the creation of a VM with the NewVM function
func VMOptEmulator ¶
VMOptEmulator is used to assign an Emulator to a VM
func VMOptSetvCPUs ¶ added in v0.0.3
VMOptSetvCPUs explicitly sets the amount of virtual CPUs of the VM
type VMSettings ¶
type VMSettings struct { Emulator Emulator // Size of the stack in bytes StackFrameSize int // Number of stack frames (max call depth of BPF-to-BPF calls) StackFrameCount int // Number of vCPU's, processes can't have a CPUID higher or equal to this number VirtualCPUs int }
VMSettings are the actual settings of the VM, VMOpt's can change an instance of these settings.
Source Files ¶
- context.go
- context_captured.go
- context_generic.go
- context_sk_buff.go
- context_xdp_md.go
- emulator.go
- emulator_linux_.go
- emulator_linux_helpers.go
- emulator_linux_map.go
- emulator_linux_map_array.go
- emulator_linux_map_hash.go
- emulator_linux_map_perf_event_array.go
- emulator_linux_map_stack_queue.go
- emulator_linux_sk_buff.go
- inst.go
- inst_gen.go
- memory_controller.go
- memory_plain.go
- memory_ring.go
- ring_buffer.go
- util_linux.go
- vm.go
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
inst_gen
This binary generates the source code for the CPU instructions of the eBPF machine go run cmd/inst_gen/main.go | gofmt > inst_gen.go
|
This binary generates the source code for the CPU instructions of the eBPF machine go run cmd/inst_gen/main.go | gofmt > inst_gen.go |