Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

defprog

defprog defines a BPF program. Each defprog form compiles into one program section in the output ELF object.

Syntax

(defprog name (:type :xdp :section nil :license "GPL")
  body...)
ParameterDefaultDescription
name--Symbol naming the program
:type:xdpBPF program type
:sectionnilELF section name (defaults to lowercase type)
:license"GPL"License string embedded in the ELF

Program Types

KeywordBPF Program TypeContext Argument
:xdpBPF_PROG_TYPE_XDPxdp_md pointer
:socket-filterBPF_PROG_TYPE_SOCKET_FILTER__sk_buff pointer
:tracepointBPF_PROG_TYPE_TRACEPOINTTracepoint args pointer
:kprobeBPF_PROG_TYPE_KPROBEpt_regs pointer
:cgroup-skbBPF_PROG_TYPE_CGROUP_SKB__sk_buff pointer
:cgroup-sockBPF_PROG_TYPE_CGROUP_SOCKbpf_sock pointer
:cgroup-sock-addrBPF_PROG_TYPE_CGROUP_SOCK_ADDRbpf_sock_addr pointer

Return Value

The last expression in the body is implicitly returned as the program's return code. There is no explicit return form. For XDP programs, this is typically an XDP action constant:

(defprog drop-all (:type :xdp)
  XDP_DROP)

Section Names

The ELF section name defaults to the lowercase string form of the program type. For example, a :kprobe program gets the section name "kprobe". To override this -- for instance, to attach to a specific kernel function -- pass :section explicitly:

(defprog trace-exec (:type :kprobe :section "kprobe/sys_execve")
  0)

License

The :license parameter controls the license string embedded in the ELF. It defaults to "GPL". Some BPF helper functions are restricted to GPL-licensed programs. If you set a non-GPL license, calls to GPL-only helpers will be rejected by the kernel verifier at load time.

Multiple Programs

Multiple defprog forms in the same source file compile into a single ELF object, each in its own section. This is useful for tail call dispatch or for bundling related programs:

(defmap dispatch :type :prog-array
  :key-size 4
  :value-size 4
  :max-entries 4)

(defprog handler-a (:type :xdp :section "xdp/handler_a")
  ;; Handle protocol A
  XDP_PASS)

(defprog handler-b (:type :xdp :section "xdp/handler_b")
  ;; Handle protocol B
  XDP_DROP)

(defprog main (:type :xdp)
  ;; Dispatch to sub-programs via tail call
  (tail-call dispatch 0)
  XDP_PASS)

Full Example

A minimal tracepoint program that records events to a ring buffer:

(defstruct event
  (pid u32)
  (ts u64))

(defmap events :type :ringbuf
  :max-entries (* 256 1024))

(defprog trace-sched (:type :tracepoint
                      :section "tracepoint/sched/sched_process_exec")
  (with-ringbuf (e events (sizeof event))
    (setf (event-pid e) (get-current-pid-tgid)
          (event-ts e) (ktime-get-ns)))
  0)