BPF program loading and attachment
BPF program loading and attachment
(attach-fentry prog {:keys [function] :as opts})Attach BPF program to a kernel function entry point using fentry.
Fentry is a modern, efficient alternative to kprobes that uses BTF (BPF Type Format) for type-safe function argument access.
There are two ways to use this:
Load program separately, then attach: (let [prog (load-fentry-program {:insns bytecode :function "tcp_v4_connect"})] (attach-fentry prog {}))
Or provide the function name if not already set: (attach-fentry prog {:function "tcp_v4_connect"})
Options:
Requirements:
Attach BPF program to a kernel function entry point using fentry.
Fentry is a modern, efficient alternative to kprobes that uses BTF
(BPF Type Format) for type-safe function argument access.
There are two ways to use this:
1. Load program separately, then attach:
(let [prog (load-fentry-program {:insns bytecode
:function "tcp_v4_connect"})]
(attach-fentry prog {}))
2. Or provide the function name if not already set:
(attach-fentry prog {:function "tcp_v4_connect"})
Options:
- :function - Kernel function name (optional if program was loaded with load-fentry-program)
Requirements:
- Kernel 5.5+ with BTF support
- Program must be loaded with :prog-type :tracing(attach-fexit prog {:keys [function] :as opts})Attach BPF program to a kernel function exit point using fexit.
Fexit is similar to fentry but triggers when the function returns, allowing access to the return value.
See attach-fentry for usage details.
Attach BPF program to a kernel function exit point using fexit. Fexit is similar to fentry but triggers when the function returns, allowing access to the return value. See attach-fentry for usage details.
(attach-kprobe prog
{:keys [function retprobe? pid cpu]
:or {retprobe? false pid -1 cpu 0}})Attach BPF program to a kprobe using perf events
This uses the tracefs-based approach which is widely compatible:
Options:
Attach BPF program to a kprobe using perf events This uses the tracefs-based approach which is widely compatible: 1. Creates a kprobe event in /sys/kernel/debug/tracing/kprobe_events 2. Opens a perf event for that tracepoint 3. Attaches the BPF program via PERF_EVENT_IOC_SET_BPF Options: - :function - Kernel function name to probe - :retprobe? - If true, attach to function return (default: false) - :pid - PID to attach to (default: -1 for all processes) - :cpu - CPU to attach to (default: 0)
(attach-kretprobe prog options)Attach BPF program to a kretprobe (function return probe)
Attach BPF program to a kretprobe (function return probe)
(attach-raw-tracepoint prog {:keys [name]})Attach BPF program to a raw tracepoint
Options:
Attach BPF program to a raw tracepoint Options: - :name - Tracepoint name (e.g., 'sched_process_exec')
(attach-tracepoint prog {:keys [category name pid cpu] :or {pid -1 cpu 0}})Attach BPF program to a tracepoint
Options:
Note: For perf-based tracepoints, at least one of pid or cpu must be non-negative. If pid=-1, you must specify a cpu. If cpu=-1, you must specify a pid. Use :cpu 0 to attach to all processes on CPU 0.
Attach BPF program to a tracepoint Options: - :category - Tracepoint category (e.g., 'sched') - :name - Tracepoint name (e.g., 'sched_switch') - :pid - PID to attach to (default: -1 for all processes) - :cpu - CPU to attach to (default: 0) Note: For perf-based tracepoints, at least one of pid or cpu must be non-negative. If pid=-1, you must specify a cpu. If cpu=-1, you must specify a pid. Use :cpu 0 to attach to all processes on CPU 0.
(attach-uprobe prog
{:keys [binary offset retprobe? pid cpu]
:or {retprobe? false pid -1 cpu 0}})Attach BPF program to a uprobe using perf events
This uses the tracefs-based approach which is widely compatible:
Options:
Example: ;; Attach to malloc in libc (attach-uprobe prog {:binary "/lib/x86_64-linux-gnu/libc.so.6" :offset "malloc"})
;; Attach to specific offset (attach-uprobe prog {:binary "/usr/bin/myapp" :offset 0x1234})
Attach BPF program to a uprobe using perf events
This uses the tracefs-based approach which is widely compatible:
1. Creates a uprobe event in /sys/kernel/debug/tracing/uprobe_events
2. Opens a perf event for that tracepoint
3. Attaches the BPF program via PERF_EVENT_IOC_SET_BPF
Options:
- :binary - Path to the binary or library to probe (e.g., "/lib/x86_64-linux-gnu/libc.so.6")
- :offset - Offset or symbol name within the binary (e.g., 0x9d850 or "malloc")
- :retprobe? - If true, attach to function return (default: false)
- :pid - PID to attach to (default: -1 for all processes)
- :cpu - CPU to attach to (default: 0)
Example:
;; Attach to malloc in libc
(attach-uprobe prog {:binary "/lib/x86_64-linux-gnu/libc.so.6"
:offset "malloc"})
;; Attach to specific offset
(attach-uprobe prog {:binary "/usr/bin/myapp"
:offset 0x1234})(attach-uretprobe prog options)Attach BPF program to a uretprobe (function return probe)
Attach BPF program to a uretprobe (function return probe)
(build-test-packet protocol
{:keys [src-mac dst-mac src-ip dst-ip src-port dst-port
payload]
:or {src-mac "00:00:00:00:00:01"
dst-mac "00:00:00:00:00:02"
src-ip "10.0.0.1"
dst-ip "10.0.0.2"
src-port 12345
dst-port 80
payload nil}})Build a test packet for BPF program testing.
Creates a minimal Ethernet/IP/TCP or UDP packet for testing XDP and TC programs.
Parameters:
Returns a byte array containing the packet.
Build a test packet for BPF program testing. Creates a minimal Ethernet/IP/TCP or UDP packet for testing XDP and TC programs. Parameters: - protocol: :tcp or :udp - opts: Map with: - :src-mac - Source MAC (default: "00:00:00:00:00:01") - :dst-mac - Destination MAC (default: "00:00:00:00:00:02") - :src-ip - Source IP (default: "10.0.0.1") - :dst-ip - Destination IP (default: "10.0.0.2") - :src-port - Source port (default: 12345) - :dst-port - Destination port (default: 80) - :payload - Optional payload bytes Returns a byte array containing the packet.
(close-program prog)Close a BPF program and detach all attachments
Close a BPF program and detach all attachments
(close-tail-call-chain chain
&
{:keys [close-programs?] :or {close-programs? true}})Close a tail call chain and all its programs.
Parameters:
Close a tail call chain and all its programs. Parameters: - chain: TailCallChain to close - :close-programs? - Whether to close the individual programs (default: true)
(create-prog-array max-entries & {:keys [name] :or {name "prog_array"}})Create a program array map for tail calls.
Parameters:
Returns a BPF map suitable for use with bpf_tail_call.
Create a program array map for tail calls. Parameters: - max-entries: Maximum number of programs (indices 0 to max-entries-1) - name: Optional name for the map Returns a BPF map suitable for use with bpf_tail_call.
(create-simple-program &
{:keys [type bytecode name license] :or {license "GPL"}})Create a simple BPF program from bytecode
Example: (create-simple-program :type :kprobe :bytecode [0x95 0x00 0x00 0x00 0x00 0x00 0x00 0x00] ; BPF_EXIT :name "my_prog")
Create a simple BPF program from bytecode Example: (create-simple-program :type :kprobe :bytecode [0x95 0x00 0x00 0x00 0x00 0x00 0x00 0x00] ; BPF_EXIT :name "my_prog")
(create-tail-call-chain programs
&
{:keys [max-entries name]
:or {max-entries 32 name "tail_call_chain"}})Create a tail call chain with multiple BPF programs.
A tail call chain allows BPF programs to call each other in sequence, useful for breaking up large programs or implementing state machines.
Parameters:
Returns a TailCallChain record.
Example: (create-tail-call-chain [{:program entry-prog :index 0} {:program parse-prog :index 1} {:program action-prog :index 2}] :name "my_chain")
Create a tail call chain with multiple BPF programs.
A tail call chain allows BPF programs to call each other in sequence,
useful for breaking up large programs or implementing state machines.
Parameters:
- programs: Vector of {:program BpfProgram :index int} maps
- :max-entries: Maximum programs in chain (default: 32)
- :name: Name for the prog_array map
Returns a TailCallChain record.
Example:
(create-tail-call-chain
[{:program entry-prog :index 0}
{:program parse-prog :index 1}
{:program action-prog :index 2}]
:name "my_chain")(get-pinned-program path {:keys [prog-type prog-name]})Get a pinned program from BPF filesystem
Get a pinned program from BPF filesystem
(get-tail-call-program chain index)Get the program at a specific index in a tail call chain.
Returns the BpfProgram or nil if not found.
Get the program at a specific index in a tail call chain. Returns the BpfProgram or nil if not found.
(load-fentry-program {:keys [insns function fexit? prog-name license log-level]
:or {fexit? false license "GPL" log-level 1}})Load a BPF program for fentry/fexit attachment.
Fentry/fexit programs require special loading with:
Options:
Returns a BpfProgram record with :btf-id in metadata.
Load a BPF program for fentry/fexit attachment. Fentry/fexit programs require special loading with: - prog-type: :tracing - expected-attach-type: :trace-fentry or :trace-fexit - attach-btf-id: BTF type ID of the target function Options: - :insns - BPF bytecode - :function - Kernel function name to attach to - :fexit? - If true, load as fexit (default: false for fentry) - :prog-name - Optional program name - :license - License string (default: 'GPL') - :log-level - Verifier log level (default: 1) Returns a BpfProgram record with :btf-id in metadata.
(load-from-elf file-path
&
{:keys [section-name prog-type license prog-name]
:or {section-name ".text" license "GPL"}})Load BPF program from ELF object file Note: This is a simplified version. Full ELF parsing not yet implemented.
Load BPF program from ELF object file Note: This is a simplified version. Full ELF parsing not yet implemented.
(load-program {:keys [prog-type insns insn-count license prog-name log-level
kern-version prog-flags expected-attach-type prog-btf-fd
attach-btf-id]
:or {log-level 1
license "GPL"
kern-version (utils/get-kernel-version)
prog-flags 0}})Load a BPF program into the kernel
Options:
Load a BPF program into the kernel Options: - :prog-type - Program type (:kprobe, :tracepoint, :xdp, :tracing, etc.) - :insns - BPF instructions as byte array or pointer - :insn-count - Number of instructions (auto-calculated if insns is byte array) - :license - License string (e.g., 'GPL') - :prog-name - Optional program name - :log-level - Verifier log level (0=off, 1=basic, 2=verbose) - :kern-version - Kernel version (default: current kernel) - :expected-attach-type - Expected attach type for certain prog types - :attach-btf-id - BTF type ID for fentry/fexit programs
(pin-program prog path)Pin program to BPF filesystem
Pin program to BPF filesystem
(program-attached? prog)Check if a BPF program has any active attachments.
Returns true if the program has one or more attachments.
Check if a BPF program has any active attachments. Returns true if the program has one or more attachments.
(program-exists? prog)Check if a BPF program is still valid and loaded in the kernel.
Returns true if the program FD is valid and the program exists. Returns false if the program has been closed or unloaded.
Note: This is a simple check that verifies the FD is positive. The kernel will return EBADF on operations if the FD is invalid.
Check if a BPF program is still valid and loaded in the kernel. Returns true if the program FD is valid and the program exists. Returns false if the program has been closed or unloaded. Note: This is a simple check that verifies the FD is positive. The kernel will return EBADF on operations if the FD is invalid.
(register-tail-call prog-array-fd index program)Register a BPF program in a prog_array at the specified index.
Parameters:
Example: (register-tail-call prog-array 0 entry-program) (register-tail-call prog-array 1 handler-program) (register-tail-call prog-array 2 exit-program)
Register a BPF program in a prog_array at the specified index. Parameters: - prog-array-fd: File descriptor of the prog_array map - index: Index at which to register the program (0 to max-entries-1) - program: BpfProgram to register Example: (register-tail-call prog-array 0 entry-program) (register-tail-call prog-array 1 handler-program) (register-tail-call prog-array 2 exit-program)
(tail-call-chain-size chain)Get the number of programs registered in a tail call chain.
Get the number of programs registered in a tail call chain.
(test-run-program
prog
{:keys [data-in data-size-out ctx-in ctx-size-out repeat flags cpu]
:or {data-size-out nil ctx-in nil ctx-size-out 0 repeat 1 flags 0 cpu 0}
:as opts})Run a BPF program in test mode with synthetic input.
This uses the BPF_PROG_TEST_RUN command to execute a BPF program without attaching it to a real hook. Useful for testing XDP, TC, and other packet-processing programs.
Parameters:
Returns a map with:
Example: ;; Test an XDP program with a synthetic packet (test-run-program xdp-prog {:data-in (build-test-packet :tcp {}) :repeat 1000}) ;; => {:retval 2 :data-out [...] :duration-ns 150}
Supported program types:
Note: Requires kernel 4.12+ for basic support, 5.10+ for full features.
Run a BPF program in test mode with synthetic input.
This uses the BPF_PROG_TEST_RUN command to execute a BPF program
without attaching it to a real hook. Useful for testing XDP, TC,
and other packet-processing programs.
Parameters:
- prog: BpfProgram to test (or program fd as integer)
- opts: Map with:
- :data-in - Input data (byte array, e.g., packet data)
- :data-size-out - Size of output buffer (default: size of data-in or 256)
- :ctx-in - Optional context data (program-type specific)
- :ctx-size-out - Size of context output buffer (default: 0)
- :repeat - Number of times to run (default: 1, for benchmarking)
- :flags - Test run flags (default: 0)
- :cpu - CPU to run on (default: 0)
Returns a map with:
- :retval - Return value from BPF program (e.g., XDP_PASS=2, XDP_DROP=1)
- :data-out - Output data (modified packet)
- :ctx-out - Output context (if ctx-size-out > 0)
- :duration-ns - Execution time in nanoseconds (average if repeat > 1)
- :data-size-out - Actual size of output data
Example:
;; Test an XDP program with a synthetic packet
(test-run-program xdp-prog
{:data-in (build-test-packet :tcp {})
:repeat 1000})
;; => {:retval 2 :data-out [...] :duration-ns 150}
Supported program types:
- XDP (xdp_md context)
- Sched CLS/ACT (sk_buff context)
- Socket filter
- Raw tracepoint
- Flow dissector
Note: Requires kernel 4.12+ for basic support, 5.10+ for full features.(unregister-tail-call prog-array-fd index)Remove a program from a prog_array at the specified index.
Parameters:
Remove a program from a prog_array at the specified index. Parameters: - prog-array-fd: File descriptor of the prog_array map - index: Index to clear
(with-program [binding prog-spec] & body)Load a program and ensure it's closed after use
Load a program and ensure it's closed after use
(with-tail-call-chain [binding programs & opts] & body)Create and manage a tail call chain with automatic cleanup.
Example: (with-tail-call-chain [chain [{:program p1 :index 0} {:program p2 :index 1}]] ;; Use the chain (attach-xdp (:entry-program chain) "eth0") (Thread/sleep 10000))
Create and manage a tail call chain with automatic cleanup.
Example:
(with-tail-call-chain [chain [{:program p1 :index 0}
{:program p2 :index 1}]]
;; Use the chain
(attach-xdp (:entry-program chain) "eth0")
(Thread/sleep 10000))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 |