KFunc bpf_iter_num_new
Initialize a new number iterator.
Definition
This kfunc initializes the iterator it
, priming it to do a numeric iteration from start
to end
where start <= i < end
.
If any of the input arguments are invalid, constructor should make sure to still initialize it such that subsequent bpf_iter_num_next()
calls will return NULL
. I.e., on error, return error and construct empty iterator.
int bpf_iter_num_new(struct bpf_iter_num *it, int start, int end)
Usage
These open coded iterators allow you to do iteration over kernel objects like iterator programs. Except we can just use a classic iterator pattern.
This specific iterator is a numeric iterator which allows us to iterate over a range of numbers. Effectively this gives us yet another way to do a for loop in BPF. The advantage of this method over bounded loops is that the verifier only has to check two states, the bpf_iter_num_next
can return NULL or a integer between start
and end
. So no matter the size of the range, the verifier only has to check these two states, it understands the contract that the iterator will always produce a NULL at some point and terminate.
The advantages over the bpf_loop
is that we keep the same scope, and we don't have to move variables back and forth between the main program and the callback via the context.
Program types
The following program types can make use of this kfunc:
BPF_PROG_TYPE_CGROUP_SKB
BPF_PROG_TYPE_CGROUP_SOCK_ADDR
BPF_PROG_TYPE_LSM
BPF_PROG_TYPE_LWT_IN
BPF_PROG_TYPE_LWT_OUT
BPF_PROG_TYPE_LWT_SEG6LOCAL
BPF_PROG_TYPE_LWT_XMIT
BPF_PROG_TYPE_NETFILTER
BPF_PROG_TYPE_SCHED_ACT
BPF_PROG_TYPE_SCHED_CLS
BPF_PROG_TYPE_SK_SKB
BPF_PROG_TYPE_SOCKET_FILTER
BPF_PROG_TYPE_STRUCT_OPS
BPF_PROG_TYPE_SYSCALL
BPF_PROG_TYPE_TRACING
BPF_PROG_TYPE_XDP
Example
struct bpf_iter_num it;
int *v;
bpf_iter_num_new(&it, 2, 5);
while ((v = bpf_iter_num_next(&it))) {
bpf_printk("X = %d", *v);
}
bpf_iter_num_destroy(&it);
Above snippet should output "X = 2", "X = 3", "X = 4". Note that 5 is exclusive and is not returned. This matches similar APIs (e.g., slices in Go or Rust) that implement a range of elements, where end index is non-inclusive.
Libbpf also provides macros to provide a more natural feeling way to write the above:
int *v;
bpf_for(v, start, end) {
bpf_printk("X = %d", *v);
}
There is also a repeat macros:
int i = 0;
bpf_repeat(5) {
bpf_printk("X = %d", i);
i++;
}