Skip to content

BPF Syscall BPF_PROG_TEST_RUN command

v4.12

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:

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

v4.12

This field indicates the file descriptor for the program you would like to test.

retval

v4.12

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

v4.12

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

v4.12

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

v4.12

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

v4.12

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

v4.12

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

v4.12

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

v5.2

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

v5.2

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

v5.2

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 set
  • priority can be set
  • ingress_ifindex can be set
  • ifindex can be set
  • cb can be set
  • tstamp can be set
  • wire_len can be set
  • gso_segs can be set
  • gso_size can be set
  • hwtstamp can be set
  • protocol is inferred from the data passed in and can only be ETH_P_IP or ETH_P_IPV6.
  • All other fields may not be set, and should be zero

ctx_out

v5.2

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

v5.10

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

v5.10

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

v5.18

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.