[PATCH bpf-next v2 5/6] libbpf: Add bpf_link_create_log API

From: Leon Hwang

Date: Mon Oct 19 2026 - 13:29:58 EST


Add a new API to accept the log opts, instead of extending the existing
struct bpf_link_create_opts.

Appending log_opts to struct bpf_link_create_opts would place them after
attach-type-specific fields of varying sizes, making it difficult to
extend the struct while preserving forward compatibility.

For example, adding log_opts would prevent extending uprobe_multi
directly with a new build_id field. Instead, a separate union would
be needed:

struct bpf_link_create_opts {
/* ... */
union {
/* ... */
struct {
/* ... */
__u32 path_fd;
} uprobe_multi;
};
struct bpf_log_opts *log_opts;
union {
struct {
__u64 build_id;
} uprobe_multi_ext;
};
size_t :0;
};

Without log_opts, build_id could be added directly to uprobe_multi:

struct bpf_link_create_opts {
/* ... */
union {
/* ... */
struct {
/* ... */
__u32 path_fd;
__u64 build_id;
} uprobe_multi;
};
size_t :0;
};

Introduce bpf_link_create_log() to accept struct bpf_log_opts separately,
preserving the forward compatibility of struct bpf_link_create_opts.

Signed-off-by: Leon Hwang <leon.hwang@xxxxxxxxx>
---
tools/lib/bpf/bpf.c | 28 ++++++++++++++++++++++++----
tools/lib/bpf/bpf.h | 5 +++++
tools/lib/bpf/libbpf.map | 2 ++
3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 9a2107d4f6d8..263a1d516a02 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -788,9 +788,10 @@ int bpf_prog_detach2(int prog_fd, int target_fd, enum bpf_attach_type type)
return bpf_prog_detach_opts(prog_fd, target_fd, type, NULL);
}

-int bpf_link_create(int prog_fd, int target_fd,
- enum bpf_attach_type attach_type,
- const struct bpf_link_create_opts *opts)
+static int __bpf_link_create(int prog_fd, int target_fd,
+ enum bpf_attach_type attach_type,
+ const struct bpf_link_create_opts *opts,
+ struct bpf_log_opts *log_opts)
{
const size_t attr_sz = offsetofend(union bpf_attr, link_create);
__u32 target_btf_id, iter_info_len, relative_id;
@@ -965,7 +966,7 @@ int bpf_link_create(int prog_fd, int target_fd,
break;
}
proceed:
- fd = sys_bpf_fd(BPF_LINK_CREATE, &attr, attr_sz);
+ fd = __sys_bpf_fd(&attr, attr_sz, BPF_LINK_CREATE, log_opts);
if (fd >= 0)
return fd;
/* we'll get EINVAL if LINK_CREATE doesn't support attaching fentry
@@ -975,6 +976,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
*/
@@ -999,6 +1004,21 @@ int bpf_link_create(int prog_fd, int target_fd,
}
}

+int bpf_link_create(int prog_fd, int target_fd,
+ enum bpf_attach_type attach_type,
+ const struct bpf_link_create_opts *opts)
+{
+ return __bpf_link_create(prog_fd, target_fd, attach_type, opts, NULL);
+}
+
+int bpf_link_create_log(int prog_fd, int target_fd,
+ enum bpf_attach_type attach_type,
+ const struct bpf_link_create_opts *opts,
+ struct bpf_log_opts *log_opts)
+{
+ return __bpf_link_create(prog_fd, target_fd, attach_type, opts, log_opts);
+}
+
int bpf_link_detach(int link_fd)
{
const size_t attr_sz = offsetofend(union bpf_attr, link_detach);
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 826d9cc9ab65..dedaf8086902 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -484,6 +484,11 @@ LIBBPF_API int bpf_link_create(int prog_fd, int target_fd,
enum bpf_attach_type attach_type,
const struct bpf_link_create_opts *opts);

+LIBBPF_API int bpf_link_create_log(int prog_fd, int target_fd,
+ enum bpf_attach_type attach_type,
+ const struct bpf_link_create_opts *opts,
+ struct bpf_log_opts *log_opts);
+
LIBBPF_API int bpf_link_detach(int link_fd);

struct bpf_link_update_opts {
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index eeba4072a5da..f6eb57151f7d 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -475,4 +475,6 @@ LIBBPF_1.8.0 {
} LIBBPF_1.7.0;

LIBBPF_1.9.0 {
+ global:
+ bpf_link_create_log;
} LIBBPF_1.8.0;
--
2.55.0