On Mon, Oct 26, 2026 at 8:51 AM Leon Hwang <[email protected]> wrote:
>
> Since the iter_info and iter_info_len in struct bpf_link_create_opts are
> legacy, reuse the slot of iter_info to place log_opts.
>
> When adding log_opts support for iter link_create in the future, we will
> move the iter_info and iter_info_len to the last union, see below. And,
> keep the backward compatibility meanwhile, that uses iter_info if
> iter_info_len is set.
>
> struct bpf_link_create_opts {
> /* ... */
> union {
> /* ... */
> strut {
> struct bpf_iter_link_info *info;
> __u32 len;
> } iter;
> };
> };
>
> Signed-off-by: Leon Hwang <[email protected]>
> ---
> tools/lib/bpf/bpf.c | 20 +++++++++++++++++---
> tools/lib/bpf/bpf.h | 5 ++++-
> 2 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
> index aea534764dfe..38dcb31e8c0e 100644
> --- a/tools/lib/bpf/bpf.c
> +++ b/tools/lib/bpf/bpf.c
> @@ -794,6 +794,8 @@ int bpf_link_create(int prog_fd, int target_fd,
> {
> const size_t attr_sz = offsetofend(union bpf_attr, link_create);
> __u32 target_btf_id, iter_info_len, relative_id;
> + union bpf_iter_link_info *iter_info = NULL;
> + struct bpf_log_opts *log_opts = NULL;
> int fd, err, relative_fd;
> union bpf_attr attr;
>
> @@ -803,6 +805,14 @@ int bpf_link_create(int prog_fd, int target_fd,
> iter_info_len = OPTS_GET(opts, iter_info_len, 0);
> target_btf_id = OPTS_GET(opts, target_btf_id, 0);
>
> + if (iter_info_len && attach_type != BPF_TRACE_ITER)
> + return libbpf_err(-EINVAL);
> +
> + if (iter_info_len)
> + iter_info = OPTS_GET(opts, iter_info, (void *)0);
> + else
> + log_opts = OPTS_GET(opts, log_opts, (void *)0);
> +
> /* validate we don't have unexpected combinations of non-zero fields
> */
> if (iter_info_len || target_btf_id) {
> if (iter_info_len && target_btf_id)
> @@ -824,7 +834,7 @@ int bpf_link_create(int prog_fd, int target_fd,
>
> switch (attach_type) {
> case BPF_TRACE_ITER:
> - attr.link_create.iter_info = ptr_to_u64(OPTS_GET(opts,
> iter_info, (void *)0));
> + attr.link_create.iter_info = ptr_to_u64(iter_info);
> attr.link_create.iter_info_len = iter_info_len;
> break;
> case BPF_PERF_EVENT:
> @@ -960,12 +970,12 @@ int bpf_link_create(int prog_fd, int target_fd,
> return libbpf_err(-EINVAL);
> break;
> default:
> - if (!OPTS_ZEROED(opts, flags))
> + if (!OPTS_ZEROED(opts, iter_info_len))
semantically cleaner would be to use log_opts here instead of
iter_info_len, send in a follow up?
> return libbpf_err(-EINVAL);
> break;
> }
> proceed:
> - fd = sys_bpf_fd(BPF_LINK_CREATE, &attr, attr_sz);
> + fd = __sys_bpf_fd(BPF_LINK_CREATE, &attr, attr_sz, log_opts);
> if (fd >= 0)
> return fd;
> /* we'll get EINVAL if LINK_CREATE doesn't support attaching fentry
> @@ -975,6 +985,10 @@ int bpf_link_create(int prog_fd, int target_fd,
> if (err != -EINVAL)
> return libbpf_err(err);
>
> + /* bpf_raw_tracepoint_open() does not support log_opts */
> + if (log_opts)
> + return libbpf_err(err);
> +
> /* if user used features not supported by
> * BPF_RAW_TRACEPOINT_OPEN command, then just give up immediately
> */
> diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
> index 826d9cc9ab65..fe3b7fd8512b 100644
> --- a/tools/lib/bpf/bpf.h
> +++ b/tools/lib/bpf/bpf.h
> @@ -422,7 +422,10 @@ union bpf_iter_link_info; /* defined in up-to-date
> linux/bpf.h */
> struct bpf_link_create_opts {
> size_t sz; /* size of this struct for forward/backward compatibility
> */
> __u32 flags;
> - union bpf_iter_link_info *iter_info;
> + union {
> + union bpf_iter_link_info *iter_info;
> + struct bpf_log_opts *log_opts;
> + };
> __u32 iter_info_len;
in a follow up, let's add comment next to iter_info above and
iter_info_len here that these are deprecated and that iter.info and
iter.info_len should be used instead
applied series to bpf-next, thank you!
> __u32 target_btf_id;
> union {
> --
> 2.55.0
>