Idiomatic Clojure DSL for BPF programming
Idiomatic Clojure DSL for BPF programming
(add dst imm)Add immediate to register (64-bit).
Example: (add :r0 10) ; r0 += 10
Add immediate to register (64-bit). Example: (add :r0 10) ; r0 += 10
(add-reg dst src)Add register to register (64-bit).
Example: (add-reg :r0 :r1) ; r0 += r1
Add register to register (64-bit). Example: (add-reg :r0 :r1) ; r0 += r1
(alu-imm op dst imm)ALU operation with immediate operand (64-bit).
Example: (alu-imm :add :r0 10) ; r0 += 10
ALU operation with immediate operand (64-bit). Example: (alu-imm :add :r0 10) ; r0 += 10
ALU operation codes (bits 4-7 of opcode)
ALU operation codes (bits 4-7 of opcode)
(alu-reg op dst src)ALU operation with register operand (64-bit).
Example: (alu-reg :add :r0 :r1) ; r0 += r1
ALU operation with register operand (64-bit). Example: (alu-reg :add :r0 :r1) ; r0 += r1
(alu32-imm op dst imm)ALU operation with immediate operand (32-bit).
Example: (alu32-imm :add :r0 10) ; r0 = (u32)(r0 + 10)
ALU operation with immediate operand (32-bit). Example: (alu32-imm :add :r0 10) ; r0 = (u32)(r0 + 10)
(alu32-reg op dst src)ALU operation with register operand (32-bit).
Example: (alu32-reg :add :r0 :r1) ; r0 = (u32)(r0 + r1)
ALU operation with register operand (32-bit). Example: (alu32-reg :add :r0 :r1) ; r0 = (u32)(r0 + r1)
(and dst src-or-imm)Bitwise AND operation (tutorial-compatible). Handles both immediate and register sources.
Example: (and :r0 0xFF) ; r0 &= 0xFF (immediate) (and :r0 :r1) ; r0 &= r1 (register)
Bitwise AND operation (tutorial-compatible). Handles both immediate and register sources. Example: (and :r0 0xFF) ; r0 &= 0xFF (immediate) (and :r0 :r1) ; r0 &= r1 (register)
(and-op dst imm)Bitwise AND with immediate (64-bit).
Example: (and-op :r0 0xFF) ; r0 &= 0xFF
Bitwise AND with immediate (64-bit). Example: (and-op :r0 0xFF) ; r0 &= 0xFF
(and-reg dst src)Bitwise AND with register (64-bit).
Example: (and-reg :r0 :r1) ; r0 &= r1
Bitwise AND with register (64-bit). Example: (and-reg :r0 :r1) ; r0 &= r1
(arsh dst imm)Arithmetic right shift by immediate (64-bit).
Example: (arsh :r0 8) ; r0 = (s64)r0 >> 8
Arithmetic right shift by immediate (64-bit). Example: (arsh :r0 8) ; r0 = (s64)r0 >> 8
(assemble instructions)Assemble a sequence of instructions into BPF bytecode.
Parameters:
Returns combined byte array.
Example: (assemble [(mov :r0 0) (exit-insn)])
Assemble a sequence of instructions into BPF bytecode.
Parameters:
- instructions: Sequence of instruction byte arrays
Returns combined byte array.
Example:
(assemble [(mov :r0 0)
(exit-insn)])(atomic-add size dst src)(atomic-add size dst src offset)Atomic add to memory location.
Performs: *dst[offset] += src
Parameters:
Example: (atomic-add :dw :r1 :r2 0) ; (u64)(r1+0) += r2
Atomic add to memory location. Performs: *dst[offset] += src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to add - offset: Memory offset (default 0) Example: (atomic-add :dw :r1 :r2 0) ; *(u64*)(r1+0) += r2
(atomic-and size dst src)(atomic-and size dst src offset)Atomic AND to memory location.
Performs: *dst[offset] &= src
Parameters:
Example: (atomic-and :dw :r1 :r2 0) ; (u64)(r1+0) &= r2
Atomic AND to memory location. Performs: *dst[offset] &= src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to AND - offset: Memory offset (default 0) Example: (atomic-and :dw :r1 :r2 0) ; *(u64*)(r1+0) &= r2
(atomic-clear-bit addr-reg bit)(atomic-clear-bit addr-reg bit offset)Generate code to atomically clear a bit.
Uses atomic-and with inverted bit mask.
Parameters:
Returns instruction sequence.
Example: (atomic-clear-bit :r1 5 0) ; Clear bit 5 in *r1
Generate code to atomically clear a bit. Uses atomic-and with inverted bit mask. Parameters: - addr-reg: Register containing memory address - bit: Bit number to clear (0-63) - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-clear-bit :r1 5 0) ; Clear bit 5 in *r1
(atomic-cmpxchg size dst src)(atomic-cmpxchg size dst src offset)Atomic compare-and-exchange (CAS).
Performs:
Note: r0 is implicitly used as the comparison value.
Parameters:
Example: ;; Compare-and-swap pattern: (mov :r0 expected-value) (mov :r2 new-value) (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now contains original value ;; Memory updated only if original == expected-value
Atomic compare-and-exchange (CAS). Performs: - If *dst[offset] == r0, then *dst[offset] = src - r0 receives the original value of *dst[offset] Note: r0 is implicitly used as the comparison value. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing new value to write if comparison succeeds - offset: Memory offset (default 0) Example: ;; Compare-and-swap pattern: (mov :r0 expected-value) (mov :r2 new-value) (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now contains original value ;; Memory updated only if original == expected-value
(atomic-decrement addr-reg)(atomic-decrement addr-reg offset)Generate code to atomically decrement a counter.
Uses atomic-add with value -1.
Parameters:
Returns instruction sequence.
Example: (atomic-decrement :r1 0) ; (*r1)-- atomically
Generate code to atomically decrement a counter. Uses atomic-add with value -1. Parameters: - addr-reg: Register containing counter address - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-decrement :r1 0) ; (*r1)-- atomically
(atomic-fetch-add size dst src)(atomic-fetch-add size dst src offset)Atomic fetch-and-add: returns old value, then adds.
Performs: src = *dst[offset]; *dst[offset] += src (Note: src receives the OLD value, not the new value)
Parameters:
Example: (atomic-fetch-add :dw :r1 :r2 0) ; r2 = *(r1+0); *(r1+0) += old_r2
Atomic fetch-and-add: returns old value, then adds. Performs: src = *dst[offset]; *dst[offset] += src (Note: src receives the OLD value, not the new value) Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to add (receives old value) - offset: Memory offset (default 0) Example: (atomic-fetch-add :dw :r1 :r2 0) ; r2 = *(r1+0); *(r1+0) += old_r2
(atomic-fetch-and size dst src)(atomic-fetch-and size dst src offset)Atomic fetch-and-AND: returns old value, then ANDs.
Parameters:
Atomic fetch-and-AND: returns old value, then ANDs. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to AND (receives old value) - offset: Memory offset (default 0)
(atomic-fetch-or size dst src)(atomic-fetch-or size dst src offset)Atomic fetch-and-OR: returns old value, then ORs.
Parameters:
Atomic fetch-and-OR: returns old value, then ORs. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to OR (receives old value) - offset: Memory offset (default 0)
(atomic-fetch-xor size dst src)(atomic-fetch-xor size dst src offset)Atomic fetch-and-XOR: returns old value, then XORs.
Parameters:
Atomic fetch-and-XOR: returns old value, then XORs. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to XOR (receives old value) - offset: Memory offset (default 0)
(atomic-increment addr-reg)(atomic-increment addr-reg offset)Generate code to atomically increment a counter.
Uses atomic-fetch-add with value 1.
Parameters:
Returns instruction sequence.
Example: (atomic-increment :r1 0) ; (*r1)++ atomically
Generate code to atomically increment a counter. Uses atomic-fetch-add with value 1. Parameters: - addr-reg: Register containing counter address - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-increment :r1 0) ; (*r1)++ atomically
(atomic-or size dst src)(atomic-or size dst src offset)Atomic OR to memory location.
Performs: *dst[offset] |= src
Parameters:
Example: (atomic-or :dw :r1 :r2 0) ; (u64)(r1+0) |= r2
Atomic OR to memory location. Performs: *dst[offset] |= src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to OR - offset: Memory offset (default 0) Example: (atomic-or :dw :r1 :r2 0) ; *(u64*)(r1+0) |= r2
(atomic-set-bit addr-reg bit)(atomic-set-bit addr-reg bit offset)Generate code to atomically set a bit.
Uses atomic-or to set the specified bit.
Parameters:
Returns instruction sequence.
Example: (atomic-set-bit :r1 5 0) ; Set bit 5 in *r1
Generate code to atomically set a bit. Uses atomic-or to set the specified bit. Parameters: - addr-reg: Register containing memory address - bit: Bit number to set (0-63) - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-set-bit :r1 5 0) ; Set bit 5 in *r1
(atomic-toggle-bit addr-reg bit)(atomic-toggle-bit addr-reg bit offset)Generate code to atomically toggle (flip) a bit.
Uses atomic-xor with the bit mask.
Parameters:
Returns instruction sequence.
Example: (atomic-toggle-bit :r1 5 0) ; Toggle bit 5 in *r1
Generate code to atomically toggle (flip) a bit. Uses atomic-xor with the bit mask. Parameters: - addr-reg: Register containing memory address - bit: Bit number to toggle (0-63) - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-toggle-bit :r1 5 0) ; Toggle bit 5 in *r1
(atomic-xchg size dst src)(atomic-xchg size dst src offset)Atomic exchange: swap register value with memory value.
Performs: src = xchg(*dst[offset], src) The old memory value is placed in src, and src's old value is written to memory.
Parameters:
Example: (atomic-xchg :dw :r1 :r2 0) ; r2 <=> *(r1+0)
Atomic exchange: swap register value with memory value. Performs: src = xchg(*dst[offset], src) The old memory value is placed in src, and src's old value is written to memory. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register to exchange with memory - offset: Memory offset (default 0) Example: (atomic-xchg :dw :r1 :r2 0) ; r2 <=> *(r1+0)
(atomic-xor size dst src)(atomic-xor size dst src offset)Atomic XOR to memory location.
Performs: *dst[offset] ^= src
Parameters:
Example: (atomic-xor :dw :r1 :r2 0) ; (u64)(r1+0) ^= r2
Atomic XOR to memory location. Performs: *dst[offset] ^= src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to XOR - offset: Memory offset (default 0) Example: (atomic-xor :dw :r1 :r2 0) ; *(u64*)(r1+0) ^= r2
(bounded-loop iterations callback-fn-reg)(bounded-loop iterations callback-fn-reg callback-ctx-reg)Generate code for a bounded loop using bpf_loop helper.
Executes callback function up to N times.
Parameters:
Returns instruction sequence.
Example: (bounded-loop 10 :r1 :r2) ;; Calls function at r1 up to 10 times with ctx r2
Generate code for a bounded loop using bpf_loop helper. Executes callback function up to N times. Parameters: - iterations: Number of iterations (immediate or register) - callback-fn-reg: Register containing callback function pointer - callback-ctx-reg: Register containing callback context (optional) Returns instruction sequence. Example: (bounded-loop 10 :r1 :r2) ;; Calls function at r1 up to 10 times with ctx r2
(call helper-id)Call BPF helper function.
Example: (call (:map-lookup-elem bpf-helpers)) ; call helper
Call BPF helper function. Example: (call (:map-lookup-elem bpf-helpers)) ; call helper
(cas-loop addr-reg expected-reg new-reg retry-offset)(cas-loop addr-reg expected-reg new-reg retry-offset offset)Generate a compare-and-swap loop pattern.
Attempts to atomically update a value from old to new. Retries if another CPU modified the value.
Parameters:
Returns instruction sequence.
Note: This is a template - actual implementation may need adjustment based on specific use case.
Example: ;; Load current value into r6 (ldx :dw :r6 :r1 0) ;; Prepare expected and new values (mov-reg :r0 :r6) ; r0 = expected (add-reg :r2 :r6) ; r2 = r6 + delta = new value ;; CAS (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now has original, compare with expected (jmp-reg :jne :r0 :r6 retry-offset) ; retry if changed
Generate a compare-and-swap loop pattern. Attempts to atomically update a value from old to new. Retries if another CPU modified the value. Parameters: - addr-reg: Register containing memory address - expected-reg: Register containing expected old value - new-reg: Register containing new value to write - retry-offset: Jump offset to retry location (negative) - offset: Memory offset (default 0) Returns instruction sequence. Note: This is a template - actual implementation may need adjustment based on specific use case. Example: ;; Load current value into r6 (ldx :dw :r6 :r1 0) ;; Prepare expected and new values (mov-reg :r0 :r6) ; r0 = expected (add-reg :r2 :r6) ; r2 = r6 + delta = new value ;; CAS (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now has original, compare with expected (jmp-reg :jne :r0 :r6 retry-offset) ; retry if changed
(compile-program & instructions)Compile DSL instructions into BPF bytecode at runtime.
Parameters:
Returns byte array.
Example: (compile-program (mov :r0 2) (exit-insn))
Compile DSL instructions into BPF bytecode at runtime.
Parameters:
- instructions: List of DSL instruction forms
Returns byte array.
Example:
(compile-program
(mov :r0 2)
(exit-insn))(core-enum-value dst enum-name value-name)Generate placeholder instruction for CO-RE enum value relocation.
Returns the integer value of an enum constant.
Parameters:
Returns instruction byte array.
Example: ;; Get value of TASK_RUNNING from task state enum (core-enum-value :r0 "task_state" "TASK_RUNNING")
Generate placeholder instruction for CO-RE enum value relocation. Returns the integer value of an enum constant. Parameters: - dst: Destination register - enum-name: Enum type name - value-name: Enum value name Returns instruction byte array. Example: ;; Get value of TASK_RUNNING from task state enum (core-enum-value :r0 "task_state" "TASK_RUNNING")
(core-field-exists dst struct-name field-name)Generate placeholder instruction for CO-RE field existence check.
Returns 1 if field exists in target kernel, 0 if not.
Parameters:
Returns instruction byte array.
Example: ;; Check if task_struct has 'pids' field (core-field-exists :r0 "task_struct" "pids")
Generate placeholder instruction for CO-RE field existence check. Returns 1 if field exists in target kernel, 0 if not. Parameters: - dst: Destination register - struct-name: Structure name - field-name: Field name Returns instruction byte array. Example: ;; Check if task_struct has 'pids' field (core-field-exists :r0 "task_struct" "pids")
(core-field-offset dst struct-name field-name)Generate placeholder instruction for CO-RE field offset relocation.
This generates a MOV instruction with a placeholder immediate value (0) that will be relocated at load time using BTF information to the correct field offset.
Note: Actual CO-RE relocation requires BTF data and relocation records that are typically handled by the ELF loader or program loader.
Parameters:
Returns instruction byte array with placeholder offset.
Example: ;; Load offset of task_struct->pid into r1 (core-field-offset :r1 "task_struct" "pid")
The placeholder value (0) would be replaced with the actual offset during program loading when CO-RE relocations are processed.
Generate placeholder instruction for CO-RE field offset relocation. This generates a MOV instruction with a placeholder immediate value (0) that will be relocated at load time using BTF information to the correct field offset. Note: Actual CO-RE relocation requires BTF data and relocation records that are typically handled by the ELF loader or program loader. Parameters: - dst: Destination register - struct-name: Structure name (for documentation/debugging) - field-name: Field name (for documentation/debugging) Returns instruction byte array with placeholder offset. Example: ;; Load offset of task_struct->pid into r1 (core-field-offset :r1 "task_struct" "pid") The placeholder value (0) would be replaced with the actual offset during program loading when CO-RE relocations are processed.
(core-field-size dst struct-name field-name)Generate placeholder instruction for CO-RE field size relocation.
Returns size of field in bytes.
Parameters:
Returns instruction byte array.
Example: ;; Get size of task_struct->comm field (core-field-size :r1 "task_struct" "comm")
Generate placeholder instruction for CO-RE field size relocation. Returns size of field in bytes. Parameters: - dst: Destination register - struct-name: Structure name - field-name: Field name Returns instruction byte array. Example: ;; Get size of task_struct->comm field (core-field-size :r1 "task_struct" "comm")
(core-read btf-data dst-reg src-reg struct-name field-path)Generate CO-RE relocatable field read instructions.
Reads a field from a kernel structure using BTF information for CO-RE (Compile Once - Run Everywhere) compatibility. The field offset is determined at load time based on the target kernel's BTF.
Parameters:
Returns instruction sequence for reading the field value. Uses bpf_probe_read_kernel for safe kernel memory access.
Example: ;; Read sk->__sk_common.skc_daddr into r6 (core-read btf :r6 :r7 "sock" [:__sk_common :skc_daddr])
Note: This generates a compile-time resolved offset. For true CO-RE relocation at load time, use the relocate namespace functions.
Generate CO-RE relocatable field read instructions. Reads a field from a kernel structure using BTF information for CO-RE (Compile Once - Run Everywhere) compatibility. The field offset is determined at load time based on the target kernel's BTF. Parameters: - btf-data: BTF data from btf/load-btf-file - dst-reg: Destination register for the read value - src-reg: Source register containing struct pointer - struct-name: Name of the kernel struct (string) - field-path: Vector of field names to traverse, e.g., [:__sk_common :skc_daddr] Returns instruction sequence for reading the field value. Uses bpf_probe_read_kernel for safe kernel memory access. Example: ;; Read sk->__sk_common.skc_daddr into r6 (core-read btf :r6 :r7 "sock" [:__sk_common :skc_daddr]) Note: This generates a compile-time resolved offset. For true CO-RE relocation at load time, use the relocate namespace functions.
(core-read-safe btf-data dst-reg src-reg struct-name field-path stack-offset)Generate CO-RE field read using bpf_probe_read_kernel for safety.
Like core-read but uses bpf_probe_read_kernel helper instead of direct memory load. This is safer for potentially invalid pointers.
The result is stored on the stack at the given offset, then loaded into the destination register.
Parameters:
Returns instruction sequence.
Example: ;; Safely read sk->__sk_common.skc_daddr (core-read-safe btf :r6 :r7 "sock" [:__sk_common :skc_daddr] -8)
Generate CO-RE field read using bpf_probe_read_kernel for safety. Like core-read but uses bpf_probe_read_kernel helper instead of direct memory load. This is safer for potentially invalid pointers. The result is stored on the stack at the given offset, then loaded into the destination register. Parameters: - btf-data: BTF data from btf/load-btf-file - dst-reg: Destination register for the read value - src-reg: Source register containing struct pointer - struct-name: Name of the kernel struct (string) - field-path: Vector of field names to traverse - stack-offset: Stack offset for temporary storage (negative, e.g., -8) Returns instruction sequence. Example: ;; Safely read sk->__sk_common.skc_daddr (core-read-safe btf :r6 :r7 "sock" [:__sk_common :skc_daddr] -8)
(core-type-exists dst type-name)Generate placeholder instruction for CO-RE type existence check.
Returns 1 if type exists in target kernel, 0 if not.
Parameters:
Returns instruction byte array.
Example: ;; Check if 'struct bpf_map' exists (core-type-exists :r0 "struct bpf_map")
Generate placeholder instruction for CO-RE type existence check. Returns 1 if type exists in target kernel, 0 if not. Parameters: - dst: Destination register - type-name: Type name to check Returns instruction byte array. Example: ;; Check if 'struct bpf_map' exists (core-type-exists :r0 "struct bpf_map")
(core-type-size dst type-name)Generate placeholder instruction for CO-RE type size relocation.
Returns size of type in bytes.
Parameters:
Returns instruction byte array.
Example: ;; Get size of task_struct (core-type-size :r1 "task_struct")
Generate placeholder instruction for CO-RE type size relocation. Returns size of type in bytes. Parameters: - dst: Destination register - type-name: Type name Returns instruction byte array. Example: ;; Get size of task_struct (core-type-size :r1 "task_struct")
(defbpf name & body)Define a BPF program using DSL.
Example: (defbpf my-program (mov :r0 0) (exit-insn))
Define a BPF program using DSL.
Example:
(defbpf my-program
(mov :r0 0)
(exit-insn))(div dst imm)Divide register by immediate (64-bit).
Example: (div :r0 2) ; r0 /= 2
Divide register by immediate (64-bit). Example: (div :r0 2) ; r0 /= 2
(div-reg dst src)Divide register by register (64-bit).
Example: (div-reg :r0 :r1) ; r0 /= r1
Divide register by register (64-bit). Example: (div-reg :r0 :r1) ; r0 /= r1
(end-to-be dst size)Convert register from host byte order to big-endian (network byte order).
size: Bit size - 16, 32, or 64
Example: (end-to-be :r0 16) ; r0 = htobe16(r0) (end-to-be :r1 32) ; r1 = htobe32(r1)
Convert register from host byte order to big-endian (network byte order). size: Bit size - 16, 32, or 64 Example: (end-to-be :r0 16) ; r0 = htobe16(r0) (end-to-be :r1 32) ; r1 = htobe32(r1)
(end-to-le dst size)Convert register from host byte order to little-endian.
size: Bit size - 16, 32, or 64
Note: On x86/x86_64 (little-endian), this is essentially a no-op. The instruction is provided for portability.
Example: (end-to-le :r0 16) ; r0 = htole16(r0) (end-to-le :r1 32) ; r1 = htole32(r1)
Convert register from host byte order to little-endian. size: Bit size - 16, 32, or 64 Note: On x86/x86_64 (little-endian), this is essentially a no-op. The instruction is provided for portability. Example: (end-to-le :r0 16) ; r0 = htole16(r0) (end-to-le :r1 32) ; r1 = htole32(r1)
(endian-be size dst)Convert to big-endian (tutorial-compatible alias for end-to-be).
Example: (endian-be :h :r5) ; Convert r5 to big-endian 16-bit
Convert to big-endian (tutorial-compatible alias for end-to-be). Example: (endian-be :h :r5) ; Convert r5 to big-endian 16-bit
(endian-le size dst)Convert to little-endian (tutorial-compatible alias for end-to-le).
Example: (endian-le :w :r5) ; Convert r5 to little-endian 32-bit
Convert to little-endian (tutorial-compatible alias for end-to-le). Example: (endian-le :w :r5) ; Convert r5 to little-endian 32-bit
(exit)Exit program (tutorial-compatible alias for exit-insn).
Exit program (tutorial-compatible alias for exit-insn).
(exit-insn)Exit BPF program.
Example: (exit-insn) ; return
Exit BPF program. Example: (exit-insn) ; return
(extract-gid uid-gid-reg gid-reg)Extract GID from combined UID/GID value.
Parameters:
Returns instruction sequence.
Example: (extract-gid :r0 :r1) ;; r1 = r0 >> 32
Extract GID from combined UID/GID value. Parameters: - uid-gid-reg: Register containing combined value - gid-reg: Register to receive GID Returns instruction sequence. Example: (extract-gid :r0 :r1) ;; r1 = r0 >> 32
(extract-pid pid-tgid-reg pid-reg)Extract PID from combined PID/TGID value.
Parameters:
Returns instruction sequence.
Example: (extract-pid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
Extract PID from combined PID/TGID value. Parameters: - pid-tgid-reg: Register containing combined value - pid-reg: Register to receive PID Returns instruction sequence. Example: (extract-pid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
(extract-tgid pid-tgid-reg tgid-reg)Extract TGID from combined PID/TGID value.
Parameters:
Returns instruction sequence.
Example: (extract-tgid :r0 :r1) ;; r1 = r0 >> 32
Extract TGID from combined PID/TGID value. Parameters: - pid-tgid-reg: Register containing combined value - tgid-reg: Register to receive TGID Returns instruction sequence. Example: (extract-tgid :r0 :r1) ;; r1 = r0 >> 32
(extract-uid uid-gid-reg uid-reg)Extract UID from combined UID/GID value.
Parameters:
Returns instruction sequence.
Example: (extract-uid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
Extract UID from combined UID/GID value. Parameters: - uid-gid-reg: Register containing combined value - uid-reg: Register to receive UID Returns instruction sequence. Example: (extract-uid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
(filter-by-pid target-pid skip-jump-offset)Generate code to filter by process ID.
Only continues if PID matches, otherwise jumps to offset.
Parameters:
Returns instruction sequence.
Example: (filter-by-pid 1234 20) ;; Jumps forward 20 instructions if current PID != 1234
Generate code to filter by process ID. Only continues if PID matches, otherwise jumps to offset. Parameters: - target-pid: PID to match (immediate value) - skip-jump-offset: Jump offset if PID doesn't match Returns instruction sequence. Example: (filter-by-pid 1234 20) ;; Jumps forward 20 instructions if current PID != 1234
(filter-by-uid target-uid skip-jump-offset)Generate code to filter by user ID.
Only continues if UID matches, otherwise jumps to offset.
Parameters:
Returns instruction sequence.
Example: (filter-by-uid 1000 20) ;; Jumps forward 20 instructions if current UID != 1000
Generate code to filter by user ID. Only continues if UID matches, otherwise jumps to offset. Parameters: - target-uid: UID to match (immediate value) - skip-jump-offset: Jump offset if UID doesn't match Returns instruction sequence. Example: (filter-by-uid 1000 20) ;; Jumps forward 20 instructions if current UID != 1000
(generate-core-read dst src field-spec)Generate BPF CO-RE read sequence for nested field access.
This generates a sequence of instructions to safely read a field from a structure with CO-RE relocations, including NULL pointer checks.
Pattern similar to BPF_CORE_READ macro in C.
Parameters:
Returns sequence of instruction byte arrays.
Example: ;; Read current->pid (generate-core-read :r0 :r1 {:struct-name "task_struct" :field-name "pid"})
Generate BPF CO-RE read sequence for nested field access.
This generates a sequence of instructions to safely read a field from
a structure with CO-RE relocations, including NULL pointer checks.
Pattern similar to BPF_CORE_READ macro in C.
Parameters:
- dst: Destination register for the result
- src: Source register containing pointer to structure
- field-spec: Map with :struct-name and :field-name
Returns sequence of instruction byte arrays.
Example:
;; Read current->pid
(generate-core-read :r0 :r1
{:struct-name "task_struct"
:field-name "pid"})(get-process-info pid-tgid-reg uid-gid-reg)(get-process-info pid-tgid-reg uid-gid-reg comm-buf-reg)(get-process-info pid-tgid-reg uid-gid-reg comm-buf-reg comm-size)Generate code to collect full process information.
Collects PID, TGID, UID, GID, and command name.
Parameters:
Returns instruction sequence.
Example: (get-process-info :r6 :r7 :r8) ;; r6 = (tgid << 32) | pid ;; r7 = (gid << 32) | uid ;; buffer at r8 = comm
Generate code to collect full process information. Collects PID, TGID, UID, GID, and command name. Parameters: - pid-tgid-reg: Register to store combined PID/TGID (default :r6) - uid-gid-reg: Register to store combined UID/GID (default :r7) - comm-buf-reg: Register containing comm buffer pointer (optional) - comm-size: Size of comm buffer (default 16) Returns instruction sequence. Example: (get-process-info :r6 :r7 :r8) ;; r6 = (tgid << 32) | pid ;; r7 = (gid << 32) | uid ;; buffer at r8 = comm
(helper-get-current-ancestor-cgroup-id ancestor-level-reg)Call bpf_get_current_ancestor_cgroup_id helper.
Get ancestor cgroup ID at specified level.
Parameters:
Returns ancestor cgroup ID in r0.
Example: (helper-get-current-ancestor-cgroup-id :r1)
Call bpf_get_current_ancestor_cgroup_id helper. Get ancestor cgroup ID at specified level. Parameters: - ancestor-level-reg: Register containing ancestor level Returns ancestor cgroup ID in r0. Example: (helper-get-current-ancestor-cgroup-id :r1)
(helper-get-current-cgroup-id)Call bpf_get_current_cgroup_id helper.
Get current cgroup ID.
Returns cgroup ID in r0.
Example: (helper-get-current-cgroup-id) ;; r0 = current cgroup ID
Call bpf_get_current_cgroup_id helper. Get current cgroup ID. Returns cgroup ID in r0. Example: (helper-get-current-cgroup-id) ;; r0 = current cgroup ID
(helper-get-current-comm buf-reg size-reg)Call bpf_get_current_comm helper.
Get current process command name.
Parameters:
Returns 0 on success, negative on error.
Example: (helper-get-current-comm :r1 :r2) ;; Fills buffer at r1 with command name
Call bpf_get_current_comm helper. Get current process command name. Parameters: - buf-reg: Register containing pointer to buffer (min 16 bytes) - size-reg: Register containing buffer size Returns 0 on success, negative on error. Example: (helper-get-current-comm :r1 :r2) ;; Fills buffer at r1 with command name
(helper-get-current-pid-tgid)Call bpf_get_current_pid_tgid helper.
Get current process PID and thread group ID.
Returns u64 in r0 where:
Example: (helper-get-current-pid-tgid) ;; r0 = (tgid << 32) | pid
Call bpf_get_current_pid_tgid helper. Get current process PID and thread group ID. Returns u64 in r0 where: - Upper 32 bits = TGID (process ID) - Lower 32 bits = PID (thread ID) Example: (helper-get-current-pid-tgid) ;; r0 = (tgid << 32) | pid
(helper-get-current-task)Call bpf_get_current_task helper.
Get pointer to current task_struct.
Returns pointer to task_struct in r0.
Example: (helper-get-current-task) ;; r0 = pointer to current task_struct
Call bpf_get_current_task helper. Get pointer to current task_struct. Returns pointer to task_struct in r0. Example: (helper-get-current-task) ;; r0 = pointer to current task_struct
(helper-get-current-task-btf)Call bpf_get_current_task_btf helper.
Get pointer to current task_struct with BTF type info.
Returns BTF pointer to task_struct in r0.
Call bpf_get_current_task_btf helper. Get pointer to current task_struct with BTF type info. Returns BTF pointer to task_struct in r0.
(helper-get-current-uid-gid)Call bpf_get_current_uid_gid helper.
Get current process UID and GID.
Returns u64 in r0 where:
Example: (helper-get-current-uid-gid) ;; r0 = (gid << 32) | uid
Call bpf_get_current_uid_gid helper. Get current process UID and GID. Returns u64 in r0 where: - Upper 32 bits = GID - Lower 32 bits = UID Example: (helper-get-current-uid-gid) ;; r0 = (gid << 32) | uid
(helper-get-numa-node-id)Call bpf_get_numa_node_id helper.
Get current NUMA node ID.
Returns NUMA node ID in r0.
Call bpf_get_numa_node_id helper. Get current NUMA node ID. Returns NUMA node ID in r0.
(helper-get-prandom-u32)Call bpf_get_prandom_u32 helper.
Get pseudo-random 32-bit number.
Returns random u32 in r0.
Example: (helper-get-prandom-u32) ;; r0 = random number
Call bpf_get_prandom_u32 helper. Get pseudo-random 32-bit number. Returns random u32 in r0. Example: (helper-get-prandom-u32) ;; r0 = random number
(helper-get-smp-processor-id)Call bpf_get_smp_processor_id helper.
Get current CPU number.
Returns CPU ID in r0.
Example: (helper-get-smp-processor-id) ;; r0 = current CPU number
Call bpf_get_smp_processor_id helper. Get current CPU number. Returns CPU ID in r0. Example: (helper-get-smp-processor-id) ;; r0 = current CPU number
(helper-get-stack ctx-reg buf-reg size-reg flags-reg)Call bpf_get_stack helper.
Get kernel or user stack trace.
Parameters:
Returns number of bytes written, or negative on error.
Example: (helper-get-stack :r1 :r2 :r3 :r4)
Call bpf_get_stack helper. Get kernel or user stack trace. Parameters: - ctx-reg: Register containing context pointer - buf-reg: Register containing buffer pointer - size-reg: Register containing buffer size - flags-reg: Register containing flags (kernel/user, skip frames, etc.) Returns number of bytes written, or negative on error. Example: (helper-get-stack :r1 :r2 :r3 :r4)
(helper-get-stackid ctx-reg map-reg flags-reg)Call bpf_get_stackid helper.
Get stack trace ID for current context.
Parameters:
Returns stack ID in r0 (>= 0), or negative on error.
Example: (helper-get-stackid :r1 :r2 :r3)
Call bpf_get_stackid helper. Get stack trace ID for current context. Parameters: - ctx-reg: Register containing context pointer - map-reg: Register containing stack trace map FD - flags-reg: Register containing flags Returns stack ID in r0 (>= 0), or negative on error. Example: (helper-get-stackid :r1 :r2 :r3)
(helper-get-task-stack task-reg buf-reg size-reg flags-reg)Call bpf_get_task_stack helper.
Get stack trace for a specific task.
Parameters:
Returns number of bytes written, or negative on error.
Call bpf_get_task_stack helper. Get stack trace for a specific task. Parameters: - task-reg: Register containing task_struct pointer - buf-reg: Register containing buffer pointer - size-reg: Register containing buffer size - flags-reg: Register containing flags Returns number of bytes written, or negative on error.
(helper-jiffies64)Call bpf_jiffies64 helper.
Get current jiffies64 value.
Returns jiffies64 value in r0.
Call bpf_jiffies64 helper. Get current jiffies64 value. Returns jiffies64 value in r0.
(helper-ktime-get-boot-ns)Call bpf_ktime_get_boot_ns helper.
Get monotonic time in nanoseconds including suspend time.
Returns nanosecond timestamp in r0.
Example: (helper-ktime-get-boot-ns) ;; r0 = timestamp including suspend
Call bpf_ktime_get_boot_ns helper. Get monotonic time in nanoseconds including suspend time. Returns nanosecond timestamp in r0. Example: (helper-ktime-get-boot-ns) ;; r0 = timestamp including suspend
(helper-ktime-get-coarse-ns)Call bpf_ktime_get_coarse_ns helper.
Get coarse-grained monotonic time (faster but less precise).
Returns nanosecond timestamp in r0.
Call bpf_ktime_get_coarse_ns helper. Get coarse-grained monotonic time (faster but less precise). Returns nanosecond timestamp in r0.
(helper-ktime-get-ns)Call bpf_ktime_get_ns helper.
Get monotonic time in nanoseconds since system boot.
Returns nanosecond timestamp in r0.
Example: (helper-ktime-get-ns) ;; r0 = timestamp in nanoseconds
Call bpf_ktime_get_ns helper. Get monotonic time in nanoseconds since system boot. Returns nanosecond timestamp in r0. Example: (helper-ktime-get-ns) ;; r0 = timestamp in nanoseconds
(helper-ktime-get-tai-ns)Call bpf_ktime_get_tai_ns helper.
Get TAI (International Atomic Time) in nanoseconds.
Returns TAI timestamp in r0.
Call bpf_ktime_get_tai_ns helper. Get TAI (International Atomic Time) in nanoseconds. Returns TAI timestamp in r0.
(helper-loop nr-loops-reg callback-fn-reg callback-ctx-reg flags-reg)Call bpf_loop helper.
Execute callback function in a bounded loop (up to nr-loops iterations).
Parameters:
Returns number of iterations completed.
Example: (helper-loop :r1 :r2 :r3 :r4)
Call bpf_loop helper. Execute callback function in a bounded loop (up to nr-loops iterations). Parameters: - nr-loops-reg: Register containing number of iterations - callback-fn-reg: Register containing callback function pointer - callback-ctx-reg: Register containing callback context pointer - flags-reg: Register containing flags Returns number of iterations completed. Example: (helper-loop :r1 :r2 :r3 :r4)
(helper-map-delete-elem map-reg key-reg)Call bpf_map_delete_elem helper.
Delete an element from a BPF map.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-map-delete-elem :r1 :r2) ;; r0 = 0 on success, < 0 on error
Call bpf_map_delete_elem helper. Delete an element from a BPF map. Parameters: - map-reg: Register containing map file descriptor - key-reg: Register containing pointer to key Returns 0 on success, negative error code on failure. Example: (helper-map-delete-elem :r1 :r2) ;; r0 = 0 on success, < 0 on error
(helper-map-lookup-elem map-reg key-reg)Call bpf_map_lookup_elem helper.
Look up an element in a BPF map by key.
Parameters:
Returns pointer to value in r0, or NULL if not found.
Example: (helper-map-lookup-elem :r1 :r2) ;; r0 will contain pointer to value or NULL
Call bpf_map_lookup_elem helper. Look up an element in a BPF map by key. Parameters: - map-reg: Register containing map file descriptor (or direct FD value) - key-reg: Register containing pointer to key Returns pointer to value in r0, or NULL if not found. Example: (helper-map-lookup-elem :r1 :r2) ;; r0 will contain pointer to value or NULL
(helper-map-update-elem map-reg key-reg value-reg flags-reg)Call bpf_map_update_elem helper.
Update or insert an element in a BPF map.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-map-update-elem :r1 :r2 :r3 :r4) ;; r0 = 0 on success, < 0 on error
Call bpf_map_update_elem helper. Update or insert an element in a BPF map. Parameters: - map-reg: Register containing map file descriptor - key-reg: Register containing pointer to key - value-reg: Register containing pointer to value - flags-reg: Register containing flags (BPF_ANY, BPF_NOEXIST, BPF_EXIST) Returns 0 on success, negative error code on failure. Example: (helper-map-update-elem :r1 :r2 :r3 :r4) ;; r0 = 0 on success, < 0 on error
(helper-perf-event-output ctx-reg map-reg flags-reg data-reg size-reg)Call bpf_perf_event_output helper.
Write data to perf event buffer.
Parameters:
Returns 0 on success, negative on error.
Example: (helper-perf-event-output :r1 :r2 :r3 :r4 :r5)
Call bpf_perf_event_output helper. Write data to perf event buffer. Parameters: - ctx-reg: Register containing context pointer - map-reg: Register containing perf event map FD - flags-reg: Register containing flags (usually CPU number) - data-reg: Register containing data pointer - size-reg: Register containing data size Returns 0 on success, negative on error. Example: (helper-perf-event-output :r1 :r2 :r3 :r4 :r5)
(helper-perf-event-read map-reg flags-reg)Call bpf_perf_event_read helper.
Read perf event counter value.
Parameters:
Returns counter value in r0.
Example: (helper-perf-event-read :r1 :r2)
Call bpf_perf_event_read helper. Read perf event counter value. Parameters: - map-reg: Register containing perf event array map FD - flags-reg: Register containing flags/index Returns counter value in r0. Example: (helper-perf-event-read :r1 :r2)
(helper-probe-read dst-reg size-reg src-reg)Call bpf_probe_read helper.
Read memory from an unsafe pointer (kernel or user).
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-probe-read :r1 :r2 :r3) ;; Reads r2 bytes from r3 to r1
Call bpf_probe_read helper. Read memory from an unsafe pointer (kernel or user). Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing size to read - src-reg: Register containing unsafe source pointer Returns 0 on success, negative error code on failure. Example: (helper-probe-read :r1 :r2 :r3) ;; Reads r2 bytes from r3 to r1
(helper-probe-read-kernel dst-reg size-reg src-reg)Call bpf_probe_read_kernel helper.
Read memory from kernel space pointer.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-probe-read-kernel :r1 :r2 :r3)
Call bpf_probe_read_kernel helper. Read memory from kernel space pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing size to read - src-reg: Register containing kernel pointer Returns 0 on success, negative error code on failure. Example: (helper-probe-read-kernel :r1 :r2 :r3)
(helper-probe-read-kernel-str dst-reg size-reg src-reg)Call bpf_probe_read_kernel_str helper.
Read null-terminated string from kernel pointer.
Parameters:
Returns length of string (including NULL) on success, negative on error.
Call bpf_probe_read_kernel_str helper. Read null-terminated string from kernel pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing max size to read - src-reg: Register containing kernel pointer Returns length of string (including NULL) on success, negative on error.
(helper-probe-read-str dst-reg size-reg src-reg)Call bpf_probe_read_str helper.
Read null-terminated string from unsafe pointer.
Parameters:
Returns length of string (including NULL) on success, negative on error.
Example: (helper-probe-read-str :r1 :r2 :r3)
Call bpf_probe_read_str helper. Read null-terminated string from unsafe pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing max size to read - src-reg: Register containing unsafe source pointer Returns length of string (including NULL) on success, negative on error. Example: (helper-probe-read-str :r1 :r2 :r3)
(helper-probe-read-user dst-reg size-reg src-reg)Call bpf_probe_read_user helper.
Read memory from user space pointer.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-probe-read-user :r1 :r2 :r3)
Call bpf_probe_read_user helper. Read memory from user space pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing size to read - src-reg: Register containing user pointer Returns 0 on success, negative error code on failure. Example: (helper-probe-read-user :r1 :r2 :r3)
(helper-probe-read-user-str dst-reg size-reg src-reg)Call bpf_probe_read_user_str helper.
Read null-terminated string from user pointer.
Parameters:
Returns length of string (including NULL) on success, negative on error.
Call bpf_probe_read_user_str helper. Read null-terminated string from user pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing max size to read - src-reg: Register containing user pointer Returns length of string (including NULL) on success, negative on error.
(helper-ringbuf-discard data-reg flags-reg)Call bpf_ringbuf_discard helper.
Discard reserved ring buffer space without submitting.
Parameters:
No return value (void).
Example: (helper-ringbuf-discard :r1 :r2)
Call bpf_ringbuf_discard helper. Discard reserved ring buffer space without submitting. Parameters: - data-reg: Register containing pointer from bpf_ringbuf_reserve - flags-reg: Register containing flags No return value (void). Example: (helper-ringbuf-discard :r1 :r2)
(helper-ringbuf-output ringbuf-reg data-reg size-reg flags-reg)Call bpf_ringbuf_output helper.
Write data to ring buffer (simplified interface).
Parameters:
Returns 0 on success, negative on error.
Example: (helper-ringbuf-output :r1 :r2 :r3 :r4)
Call bpf_ringbuf_output helper. Write data to ring buffer (simplified interface). Parameters: - ringbuf-reg: Register containing ring buffer map FD - data-reg: Register containing data pointer - size-reg: Register containing data size - flags-reg: Register containing flags Returns 0 on success, negative on error. Example: (helper-ringbuf-output :r1 :r2 :r3 :r4)
(helper-ringbuf-reserve ringbuf-reg size-reg flags-reg)Call bpf_ringbuf_reserve helper.
Reserve space in ring buffer for writing.
Parameters:
Returns pointer to reserved space in r0, or NULL on failure.
Example: (helper-ringbuf-reserve :r1 :r2 :r3) ;; r0 = pointer to reserved space or NULL
Call bpf_ringbuf_reserve helper. Reserve space in ring buffer for writing. Parameters: - ringbuf-reg: Register containing ring buffer map FD - size-reg: Register containing size to reserve - flags-reg: Register containing flags Returns pointer to reserved space in r0, or NULL on failure. Example: (helper-ringbuf-reserve :r1 :r2 :r3) ;; r0 = pointer to reserved space or NULL
(helper-ringbuf-submit data-reg flags-reg)Call bpf_ringbuf_submit helper.
Submit reserved ring buffer data.
Parameters:
No return value (void).
Example: (helper-ringbuf-submit :r1 :r2)
Call bpf_ringbuf_submit helper. Submit reserved ring buffer data. Parameters: - data-reg: Register containing pointer from bpf_ringbuf_reserve - flags-reg: Register containing flags No return value (void). Example: (helper-ringbuf-submit :r1 :r2)
(helper-snprintf str-reg str-size-reg fmt-reg data-reg data-len-reg)Call bpf_snprintf helper.
Format string to buffer (printf-style).
Parameters:
Returns number of bytes written (excluding null terminator).
Example: (helper-snprintf :r1 :r2 :r3 :r4 :r5)
Call bpf_snprintf helper. Format string to buffer (printf-style). Parameters: - str-reg: Register containing destination buffer pointer - str-size-reg: Register containing buffer size - fmt-reg: Register containing format string pointer - data-reg: Register containing data pointer - data-len-reg: Register containing data length Returns number of bytes written (excluding null terminator). Example: (helper-snprintf :r1 :r2 :r3 :r4 :r5)
(helper-spin-lock lock-reg)Call bpf_spin_lock helper.
Acquire a spinlock.
Parameters:
No return value (void).
Example: (helper-spin-lock :r1)
Call bpf_spin_lock helper. Acquire a spinlock. Parameters: - lock-reg: Register containing pointer to bpf_spin_lock No return value (void). Example: (helper-spin-lock :r1)
(helper-spin-unlock lock-reg)Call bpf_spin_unlock helper.
Release a spinlock.
Parameters:
No return value (void).
Example: (helper-spin-unlock :r1)
Call bpf_spin_unlock helper. Release a spinlock. Parameters: - lock-reg: Register containing pointer to bpf_spin_lock No return value (void). Example: (helper-spin-unlock :r1)
(helper-strncmp s1-reg s1-len-reg s2-reg)Call bpf_strncmp helper.
Compare two strings.
Parameters:
Returns 0 if equal, < 0 if s1 < s2, > 0 if s1 > s2.
Example: (helper-strncmp :r1 :r2 :r3)
Call bpf_strncmp helper. Compare two strings. Parameters: - s1-reg: Register containing first string pointer - s1-len-reg: Register containing first string length - s2-reg: Register containing second string pointer Returns 0 if equal, < 0 if s1 < s2, > 0 if s1 > s2. Example: (helper-strncmp :r1 :r2 :r3)
(helper-tail-call ctx-reg prog-array-reg index-reg)Call bpf_tail_call helper.
Tail call to another BPF program. Never returns on success.
Parameters:
Never returns on success. Falls through on failure.
Example: (helper-tail-call :r1 :r2 :r3) ;; Program continues here only if tail call failed
Call bpf_tail_call helper. Tail call to another BPF program. Never returns on success. Parameters: - ctx-reg: Register containing context pointer - prog-array-reg: Register containing program array map FD - index-reg: Register containing program index Never returns on success. Falls through on failure. Example: (helper-tail-call :r1 :r2 :r3) ;; Program continues here only if tail call failed
(helper-trace-printk fmt-reg fmt-size-reg)(helper-trace-printk fmt-reg fmt-size-reg arg1-reg)(helper-trace-printk fmt-reg fmt-size-reg arg1-reg arg2-reg)(helper-trace-printk fmt-reg fmt-size-reg arg1-reg arg2-reg arg3-reg)Call bpf_trace_printk helper.
Print debug message to trace pipe (/sys/kernel/debug/tracing/trace_pipe). WARNING: Use only for debugging! Has performance overhead.
Parameters:
Returns number of bytes written, or negative on error.
Example: (helper-trace-printk :r1 :r2 :r3 :r4 :r5)
Call bpf_trace_printk helper. Print debug message to trace pipe (/sys/kernel/debug/tracing/trace_pipe). WARNING: Use only for debugging! Has performance overhead. Parameters: - fmt-reg: Register containing format string pointer - fmt-size-reg: Register containing format string size - arg1-reg: Register containing first argument (optional) - arg2-reg: Register containing second argument (optional) - arg3-reg: Register containing third argument (optional) Returns number of bytes written, or negative on error. Example: (helper-trace-printk :r1 :r2 :r3 :r4 :r5)
BPF instruction classes (3 LSB bits of opcode)
BPF instruction classes (3 LSB bits of opcode)
(ja offset)Unconditional jump.
Example: (ja label-offset) ; goto +offset
Unconditional jump. Example: (ja label-offset) ; goto +offset
(jmp offset)Unconditional jump (tutorial-compatible alias for ja). Note: offset is in instructions, not bytes.
Example: (jmp 5) ; Jump forward 5 instructions
Unconditional jump (tutorial-compatible alias for ja). Note: offset is in instructions, not bytes. Example: (jmp 5) ; Jump forward 5 instructions
(jmp-imm op dst imm offset)Jump if condition with immediate operand.
Example: (jmp-imm :jeq :r0 0 label-offset) ; if r0 == 0 goto +offset
Jump if condition with immediate operand. Example: (jmp-imm :jeq :r0 0 label-offset) ; if r0 == 0 goto +offset
Jump operation codes (bits 4-7 of opcode)
Jump operation codes (bits 4-7 of opcode)
(jmp-reg op dst src offset)Jump if condition with register operand.
Example: (jmp-reg :jeq :r0 :r1 label-offset) ; if r0 == r1 goto +offset
Jump if condition with register operand. Example: (jmp-reg :jeq :r0 :r1 label-offset) ; if r0 == r1 goto +offset
(ld-map-fd dst map-fd)Load map file descriptor into register (tutorial-compatible). Uses lddw with BPF_PSEUDO_MAP_FD source register marker.
Example: (ld-map-fd :r1 map-fd) ; r1 = map_fd (for helper calls)
Load map file descriptor into register (tutorial-compatible). Uses lddw with BPF_PSEUDO_MAP_FD source register marker. Example: (ld-map-fd :r1 map-fd) ; r1 = map_fd (for helper calls)
(lddw dst imm64)Load 64-bit immediate (wide instruction).
Example: (lddw :r0 0x123456789ABCDEF) ; r0 = 0x123456789ABCDEF
Load 64-bit immediate (wide instruction). Example: (lddw :r0 0x123456789ABCDEF) ; r0 = 0x123456789ABCDEF
(ldx size dst src offset)Load from memory into register.
Example: (ldx :dw :r0 :r1 4) ; r0 = (u64)(r1 + 4)
Load from memory into register. Example: (ldx :dw :r0 :r1 4) ; r0 = *(u64*)(r1 + 4)
(load-ctx size dst offset)Load from context pointer (alias for ldx with r1 as source). Commonly used to read fields from BPF program context.
Example: (load-ctx :dw :r2 0) ; r2 = (u64)(ctx + 0)
Load from context pointer (alias for ldx with r1 as source). Commonly used to read fields from BPF program context. Example: (load-ctx :dw :r2 0) ; r2 = *(u64*)(ctx + 0)
(load-mem size dst src offset)Load from memory into register (tutorial-compatible alias for ldx).
Example: (load-mem :dw :r0 :r1 4) ; r0 = (u64)(r1 + 4)
Load from memory into register (tutorial-compatible alias for ldx). Example: (load-mem :dw :r0 :r1 4) ; r0 = *(u64*)(r1 + 4)
Load/store mode modifiers (bits 5-7 of opcode)
Load/store mode modifiers (bits 5-7 of opcode)
Load/store size modifiers (bits 3-4 of opcode)
Load/store size modifiers (bits 3-4 of opcode)
(lsh dst imm)Left shift by immediate (64-bit).
Example: (lsh :r0 8) ; r0 <<= 8
Left shift by immediate (64-bit). Example: (lsh :r0 8) ; r0 <<= 8
(lsh-reg dst src)Left shift by register (64-bit).
Example: (lsh-reg :r0 :r1) ; r0 <<= r1
Left shift by register (64-bit). Example: (lsh-reg :r0 :r1) ; r0 <<= r1
(map-ref map-or-fd)Reference to a map for use in instructions. Returns the map-fd for use with ld-map-fd.
Example: (ld-map-fd :r1 (map-ref my-map))
Reference to a map for use in instructions. Returns the map-fd for use with ld-map-fd. Example: (ld-map-fd :r1 (map-ref my-map))
(mod dst imm)Modulo register by immediate (64-bit).
Example: (mod :r0 10) ; r0 %= 10
Modulo register by immediate (64-bit). Example: (mod :r0 10) ; r0 %= 10
(mod-reg dst src)Modulo register by register (64-bit).
Example: (mod-reg :r0 :r1) ; r0 %= r1
Modulo register by register (64-bit). Example: (mod-reg :r0 :r1) ; r0 %= r1
(mov dst imm)Move immediate to register (64-bit).
Example: (mov :r0 42) ; r0 = 42
Move immediate to register (64-bit). Example: (mov :r0 42) ; r0 = 42
(mov-reg dst src)Move register to register (64-bit).
Example: (mov-reg :r0 :r1) ; r0 = r1
Move register to register (64-bit). Example: (mov-reg :r0 :r1) ; r0 = r1
(mul dst imm)Multiply register by immediate (64-bit).
Example: (mul :r0 2) ; r0 *= 2
Multiply register by immediate (64-bit). Example: (mul :r0 2) ; r0 *= 2
(mul-reg dst src)Multiply register by register (64-bit).
Example: (mul-reg :r0 :r1) ; r0 *= r1
Multiply register by register (64-bit). Example: (mul-reg :r0 :r1) ; r0 *= r1
(neg-reg dst)Negate register (64-bit).
Example: (neg-reg :r0) ; r0 = -r0
Negate register (64-bit). Example: (neg-reg :r0) ; r0 = -r0
(or-op dst imm)Bitwise OR with immediate (64-bit).
Example: (or-op :r0 0x10) ; r0 |= 0x10
Bitwise OR with immediate (64-bit). Example: (or-op :r0 0x10) ; r0 |= 0x10
(or-reg dst src)Bitwise OR with register (64-bit).
Example: (or-reg :r0 :r1) ; r0 |= r1
Bitwise OR with register (64-bit). Example: (or-reg :r0 :r1) ; r0 |= r1
(read-kprobe-arg ctx-reg arg-index dst-reg)Read a kprobe function argument from the pt_regs context.
In kprobe programs, r1 contains a pointer to the pt_regs structure which holds the CPU registers at the time of the probe. This function generates instructions to read argument N from pt_regs into a destination register.
The pt_regs offsets are architecture-specific and are automatically determined based on the current runtime architecture.
Parameters:
Returns a single ldx instruction.
Example: ;; At kprobe entry, r1 = pt_regs* (read-kprobe-arg :r1 0 :r6) ; r6 = first function argument (sk pointer) (read-kprobe-arg :r1 1 :r7) ; r7 = second function argument
Architecture support:
Read a kprobe function argument from the pt_regs context. In kprobe programs, r1 contains a pointer to the pt_regs structure which holds the CPU registers at the time of the probe. This function generates instructions to read argument N from pt_regs into a destination register. The pt_regs offsets are architecture-specific and are automatically determined based on the current runtime architecture. Parameters: - ctx-reg: Register containing pt_regs pointer (typically :r1 at kprobe entry) - arg-index: Argument index (0 = first argument, 1 = second, etc.) - dst-reg: Destination register to store the argument value Returns a single ldx instruction. Example: ;; At kprobe entry, r1 = pt_regs* (read-kprobe-arg :r1 0 :r6) ; r6 = first function argument (sk pointer) (read-kprobe-arg :r1 1 :r7) ; r7 = second function argument Architecture support: - x86_64: Arguments in rdi, rsi, rdx, rcx, r8, r9 - arm64: Arguments in x0-x7 - s390x: Arguments in r2-r6 - ppc64le: Arguments in r3-r10 - riscv64: Arguments in a0-a7
(ringbuf-discard data-reg)Discard reserved ring buffer data without submitting.
Discards data that was previously reserved with ringbuf-reserve. Use this instead of submit if you decide not to send the event. After calling this, the reserved pointer is no longer valid.
Parameters:
Returns instruction sequence.
Example: (ringbuf-discard :r6) ;; Discards reserved space at r6
Discard reserved ring buffer data without submitting. Discards data that was previously reserved with ringbuf-reserve. Use this instead of submit if you decide not to send the event. After calling this, the reserved pointer is no longer valid. Parameters: - data-reg: Register containing pointer from ringbuf-reserve Returns instruction sequence. Example: (ringbuf-discard :r6) ;; Discards reserved space at r6
(ringbuf-output-event ringbuf-map-reg event-ptr-reg event-size)(ringbuf-output-event ringbuf-map-reg
event-ptr-reg
event-size
error-jump-offset)Generate code to output an event to ring buffer with error handling.
Combines helper call with error checking.
Parameters:
Returns instruction sequence.
Example: (ringbuf-output-event :r1 :r2 64 10) ;; Output 64 bytes from r2 to ringbuf r1 ;; Jump forward 10 instructions on error
Generate code to output an event to ring buffer with error handling. Combines helper call with error checking. Parameters: - ringbuf-map-reg: Register with ring buffer map FD - event-ptr-reg: Register with event data pointer - event-size: Size of event data (immediate or register) - error-jump-offset: Jump offset on error (optional) Returns instruction sequence. Example: (ringbuf-output-event :r1 :r2 64 10) ;; Output 64 bytes from r2 to ringbuf r1 ;; Jump forward 10 instructions on error
(ringbuf-reserve dst-reg map-fd size)Reserve space in ring buffer, returning pointer in dst-reg.
Higher-level function that loads the map FD and calls bpf_ringbuf_reserve. The reserved pointer is returned in dst-reg (moved from r0).
Parameters:
Returns instruction sequence. After execution:
Example: (ringbuf-reserve :r6 ringbuf-map-fd 48) ;; r6 = reserved pointer (check for NULL before use!)
Typical pattern: (concat (ringbuf-reserve :r6 map-fd 48) ;; Check for NULL [(jmp-imm :jeq :r6 0 error-offset)] ;; Write to r6 + offset [(stx :dw :r6 :r7 0)] ; store data (ringbuf-submit :r6))
Reserve space in ring buffer, returning pointer in dst-reg.
Higher-level function that loads the map FD and calls bpf_ringbuf_reserve.
The reserved pointer is returned in dst-reg (moved from r0).
Parameters:
- dst-reg: Destination register for reserved pointer
- map-fd: Ring buffer map file descriptor (integer)
- size: Size to reserve (integer, must be 8-byte aligned)
Returns instruction sequence. After execution:
- dst-reg = pointer to reserved space, or NULL on failure
Example:
(ringbuf-reserve :r6 ringbuf-map-fd 48)
;; r6 = reserved pointer (check for NULL before use!)
Typical pattern:
(concat
(ringbuf-reserve :r6 map-fd 48)
;; Check for NULL
[(jmp-imm :jeq :r6 0 error-offset)]
;; Write to r6 + offset
[(stx :dw :r6 :r7 0)] ; store data
(ringbuf-submit :r6))(ringbuf-submit data-reg)Submit reserved ring buffer data.
Submits data that was previously reserved with ringbuf-reserve. After calling this, the reserved pointer is no longer valid.
Parameters:
Returns instruction sequence.
Example: (ringbuf-submit :r6) ;; Submits data at r6 to consumers
Submit reserved ring buffer data. Submits data that was previously reserved with ringbuf-reserve. After calling this, the reserved pointer is no longer valid. Parameters: - data-reg: Register containing pointer from ringbuf-reserve Returns instruction sequence. Example: (ringbuf-submit :r6) ;; Submits data at r6 to consumers
(rsh dst imm)Right shift (logical) by immediate (64-bit).
Example: (rsh :r0 8) ; r0 >>= 8
Right shift (logical) by immediate (64-bit). Example: (rsh :r0 8) ; r0 >>= 8
(rsh-reg dst src)Right shift (logical) by register (64-bit).
Example: (rsh-reg :r0 :r1) ; r0 >>= r1
Right shift (logical) by register (64-bit). Example: (rsh-reg :r0 :r1) ; r0 >>= r1
(safe-probe-read dst-reg size src-reg error-jump-offset)Generate safe probe read with error checking.
Reads from unsafe pointer and checks for errors.
Parameters:
Returns instruction sequence.
Example: (safe-probe-read :r1 4 :r2 10) ;; Reads 4 bytes from r2 to r1 ;; Jumps forward 10 instructions on error
Generate safe probe read with error checking. Reads from unsafe pointer and checks for errors. Parameters: - dst-reg: Destination buffer register - size: Size to read (immediate value) - src-reg: Source pointer register - error-jump-offset: Jump offset on error Returns instruction sequence. Example: (safe-probe-read :r1 4 :r2 10) ;; Reads 4 bytes from r2 to r1 ;; Jumps forward 10 instructions on error
(sample-one-in-n n skip-jump-offset)Generate code to sample 1 in N events.
Uses random number generation for probabilistic sampling.
Parameters:
Returns instruction sequence.
Example: (sample-one-in-n 100 20) ;; Drops ~99% of events, keeps ~1%
Generate code to sample 1 in N events. Uses random number generation for probabilistic sampling. Parameters: - n: Sample rate (keep 1 in N events) - skip-jump-offset: Jump offset if event should be dropped Returns instruction sequence. Example: (sample-one-in-n 100 20) ;; Drops ~99% of events, keeps ~1%
Source operand selector (bit 3 of opcode)
Source operand selector (bit 3 of opcode)
(st size dst offset imm)Store immediate to memory.
Example: (st :dw :r1 4 42) ; (u64)(r1 + 4) = 42
Store immediate to memory. Example: (st :dw :r1 4 42) ; *(u64*)(r1 + 4) = 42
(stack-allocate size ptr-reg)Generate code to allocate space on the BPF stack.
Adjusts r10 (frame pointer) to create stack space.
Parameters:
Returns instruction sequence.
Example: (stack-allocate 64 :r1) ;; r1 = pointer to 64 bytes on stack
Generate code to allocate space on the BPF stack. Adjusts r10 (frame pointer) to create stack space. Parameters: - size: Number of bytes to allocate - ptr-reg: Register to receive pointer to allocated space Returns instruction sequence. Example: (stack-allocate 64 :r1) ;; r1 = pointer to 64 bytes on stack
(store-mem size dst offset src)Store register to memory (tutorial-compatible alias). Note: Uses [size dst offset src] order for readability.
Example: (store-mem :dw :r10 -8 :r6) ; (u64)(r10 - 8) = r6
Store register to memory (tutorial-compatible alias). Note: Uses [size dst offset src] order for readability. Example: (store-mem :dw :r10 -8 :r6) ; *(u64*)(r10 - 8) = r6
(stx size dst src offset)Store register to memory.
Example: (stx :dw :r1 :r0 4) ; (u64)(r1 + 4) = r0
Store register to memory. Example: (stx :dw :r1 :r0 4) ; *(u64*)(r1 + 4) = r0
(sub dst imm)Subtract immediate from register (64-bit).
Example: (sub :r0 10) ; r0 -= 10
Subtract immediate from register (64-bit). Example: (sub :r0 10) ; r0 -= 10
(sub-reg dst src)Subtract register from register (64-bit).
Example: (sub-reg :r0 :r1) ; r0 -= r1
Subtract register from register (64-bit). Example: (sub-reg :r0 :r1) ; r0 -= r1
(time-delta start-time-reg)(time-delta start-time-reg delta-reg)Generate code to measure time delta between two points.
Uses ktime-get-ns to measure elapsed time.
Parameters:
Returns two instruction sequences:
Example: (let [[start end] (time-delta :r6 :r7)] (concat start ;; ... code to measure ... end)) ;; r6 = start time ;; r7 = end time - start time
Generate code to measure time delta between two points.
Uses ktime-get-ns to measure elapsed time.
Parameters:
- start-time-reg: Register to store start time
- delta-reg: Register to store time delta (optional, default :r0)
Returns two instruction sequences:
1. Start: Get start time
2. End: Calculate delta
Example:
(let [[start end] (time-delta :r6 :r7)]
(concat
start
;; ... code to measure ...
end))
;; r6 = start time
;; r7 = end time - start time(trace-println msg-reg msg-len)(trace-println msg-reg msg-len arg1)(trace-println msg-reg msg-len arg1 arg2)(trace-println msg-reg msg-len arg1 arg2 arg3)Generate code for simple trace printing (debug only).
Simplified interface for bpf_trace_printk with a string message.
Parameters:
Returns instruction sequence.
WARNING: Use only for debugging!
Example: (trace-println :r1 14) ; Just format string (trace-println :r1 14 :r2 :r3) ; With arguments
Generate code for simple trace printing (debug only). Simplified interface for bpf_trace_printk with a string message. Parameters: - msg-reg: Register containing format string pointer - msg-len: Length of format string - arg-regs: Optional argument registers (up to 3) Returns instruction sequence. WARNING: Use only for debugging! Example: (trace-println :r1 14) ; Just format string (trace-println :r1 14 :r2 :r3) ; With arguments
(with-map-lookup map-reg key-reg null-jump-offset)(with-map-lookup map-reg key-reg null-jump-offset result-reg)Generate map lookup with NULL check pattern.
Looks up a map element and jumps to the specified offset if NULL.
Parameters:
Returns instruction sequence. Result pointer is in result-reg.
Example: (with-map-lookup :r1 :r2 5 :r6) ;; r6 = map_lookup(r1, r2) ;; if (r6 == NULL) jump forward 5 instructions
Generate map lookup with NULL check pattern. Looks up a map element and jumps to the specified offset if NULL. Parameters: - map-reg: Register containing map FD - key-reg: Register containing key pointer - null-jump-offset: Jump offset if lookup returns NULL - result-reg: Register to store the result (default :r0) Returns instruction sequence. Result pointer is in result-reg. Example: (with-map-lookup :r1 :r2 5 :r6) ;; r6 = map_lookup(r1, r2) ;; if (r6 == NULL) jump forward 5 instructions
(with-spinlock lock-ptr-reg body-insns)Generate code to execute a critical section with spinlock protection.
Acquires lock, executes code, and releases lock.
Parameters:
Returns instruction sequence.
Example: (with-spinlock :r1 [(mov :r0 42) (exit-insn)]) ;; Acquires lock, sets r0=42, releases lock, exits
Generate code to execute a critical section with spinlock protection. Acquires lock, executes code, and releases lock. Parameters: - lock-ptr-reg: Register containing pointer to bpf_spin_lock - body-insns: Instruction sequence to execute while holding lock Returns instruction sequence. Example: (with-spinlock :r1 [(mov :r0 42) (exit-insn)]) ;; Acquires lock, sets r0=42, releases lock, exits
(xor-op dst imm)Bitwise XOR with immediate (64-bit).
Example: (xor-op :r0 0xFF) ; r0 ^= 0xFF
Bitwise XOR with immediate (64-bit). Example: (xor-op :r0 0xFF) ; r0 ^= 0xFF
(xor-reg dst src)Bitwise XOR with register (64-bit).
Example: (xor-reg :r0 :r1) ; r0 ^= r1
Bitwise XOR with register (64-bit). Example: (xor-reg :r0 :r1) ; r0 ^= r1
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |