BPF Syscall BPF_PROG_TEST_RUN
command
This command runs a loaded eBPF program in the kernel one or multiple times with a supplied input and records the output. This can be used to test or benchmark a program.
Return value
This command will return 0
on success or a error number (negative integer) if something went wrong.
Usage
This command can be used to test or benchmark programs. Not all program types support this feature, only the following program types can be tested or benchmarked:
BPF_PROG_TYPE_SOCK_OPS
BPF_PROG_TYPE_SYSCALL
BPF_PROG_TYPE_RAW_TRACEPOINT
BPF_PROG_TYPE_TRACING
BPF_PROG_TYPE_SOCKET_FILTER
BPF_PROG_TYPE_SCHED_CLS
BPF_PROG_TYPE_SCHED_ACT
BPF_PROG_TYPE_XDP
BPF_PROG_TYPE_CGROUP_SKB
BPF_PROG_TYPE_LWT_IN
BPF_PROG_TYPE_LWT_OUT
BPF_PROG_TYPE_LWT_XMIT
BPF_PROG_TYPE_LWT_SEG6LOCAL
BPF_PROG_TYPE_FLOW_DISSECTOR
Programs of BPF_PROG_TYPE_SYSCALL
are an exception, in the sense that this mechanism is the only way for the program to actually execute. Upon calling it can do further bpf syscalls for the purposes of acting a loader. For more details checkout its page.
Note
The test framework for BPF_PROG_TYPE_TRACING
programs seems to execute some internal self tests and populate the retval
with 1
or 2
depending on the outcome, but does not actually execute the program like you would expect to. This is as of kernel v6.2.
Attributes
prog_fd
This field indicates the file descriptor for the program you would like to test.
retval
This field will be set to the return value, returned by the program after calling the command. The meaning of the return value depends on the program type.
data_size_in
This field indicates the size of the data passed into data_in
This field is not supported for the following program types:
data_size_out
This field indicates the size of the buffer provided with data_out
. If the size is smaller than the data outputted by the program, the syscall command will return a -ENOSPC
value.
This field is not supported for the following program types:
data_in
This field indicates the data to provide to the program. It should be a pointer to a memory buffer in the calling program. The format depends on the data the program expects, it is not the context but rater the data referred to by the context such as xdp_md->data
or __sk_buff->data
.
This field is not supported for the following program types:
data_out
This field indicates the data after the program has potentially modified it. It should be a pointer to a memory buffer in the calling program.
This field is not supported for the following program types:
repeat
This field indicates how often the program should be ran for a single syscall command. This is useful when benchmarking a program to increase the significance of the duration
value.
This field is not supported for the following program types:
duration
This field indicates how long the execution of the program took in nanoseconds. If repeat
is larger than 1, the field will contain the avarage per-invokation run time for all repetitions.
This field is not supported for the following program types:
ctx_size_in
This field indicates the size of the ctx_in
buffer.
This field is not supported for programs of type BPF_PROG_TYPE_SYSCALL
.
ctx_size_out
This field indicates the size of the ctx_out
buffer. If this size is smaller than the actual context the kernel want to write back, the syscall command return an -ENOSPEC
error code.
This field is not supported for the following program types:
ctx_in
This field indicates the context with which the program should be invoked. This should be a pointer to a memory buffer. The structure of the memory depends on the context of the program type under test.
For programs of type BPF_PROG_TYPE_SOCK_OPS
the context must be the an array of 64-bit integers of the size equal to the amount of arguments of the operation.
For programs of type BPF_PROG_TYPE_SYSCALL
the value of this field is available to to the program one to one.
For programs of type BPF_PROG_TYPE_RAW_TRACEPOINT
the value of this field is available to the program one to one, and should thus match the structure of the tracepoint.
For programs of type BPF_PROG_TYPE_FLOW_DISSECTOR
the value of this field should match struct bpf_flow_keys
.
For programs of type BPF_PROG_TYPE_XDP
the value of this field should match struct xdp_md
. The egress_ifindex
field may not be set, the ingress_ifindex
and rx_queue_index
fields are mutually exclusive, and data
and data_end
are ignored and set automatically based on the supplied data_in
.
For all other program types (which all are skb-based) the value of this field should match struct __sk_buff
. However not all fields are allowed and some are generated, the following rules apply:
mark
can be setpriority
can be setingress_ifindex
can be setifindex
can be setcb
can be settstamp
can be setwire_len
can be setgso_segs
can be setgso_size
can be sethwtstamp
can be setprotocol
is inferred from thedata
passed in and can only beETH_P_IP
orETH_P_IPV6
.- All other fields may not be set, and should be zero
ctx_out
This field indicates the context after the program has executed. The kernel will write the modified context back to the memory indicated by this field. This field should be a pointer to a memory buffer in the calling program.
This field is not supported for the following program types:
flags
This field contains flags to modify behavior of the test. More details in the flags section.
This field is not supported for the following program types:
cpu
This field indicates the logical CPU on which the test program should be executed.
This field is only honoured when the BPF_F_TEST_RUN_ON_CPU
flag is set.
This field can only be used with BPF_PROG_TYPE_RAW_TRACEPOINT
programs.
batch_size
This field indicates the size of the batch of network packets to be be sent to the kernel at once.
This field only has meaning when the BPF_F_TEST_XDP_LIVE_FRAMES
flag is set.
This field only works for BPF_PROG_TYPE_XDP
programs.
Flags
BPF_F_TEST_RUN_ON_CPU
When set, this flag enable running the program on a specific CPU. This is necessary since the default value of 0
is a valid CPU index.
BPF_F_TEST_XDP_LIVE_FRAMES
When set, the packet after being processed by the program are injected into the network stack as if having arrived. This can be used to inject packets into the kernel for a number of tests.