Currently libbpf supports bpf_map__attach_struct_ops() with signature: LIBBPF_API struct bpf_link * bpf_map__attach_struct_ops(const struct bpf_map *map); To support cookie for struct_ops attachment, an additional argument is needed. The argument is a pointer to a structure containing all the option used for bpf_link_create. Add the new API: LIBBPF_API struct bpf_link * bpf_map__attach_struct_ops_opts(const struct bpf_map *map, const struct bpf_struct_ops_opts *opts); Signed-off-by: Amery Hung <ameryhung@xxxxxxxxx> --- tools/lib/bpf/bpf.c | 5 +++++ tools/lib/bpf/bpf.h | 3 +++ tools/lib/bpf/libbpf.c | 14 +++++++++++++- tools/lib/bpf/libbpf.h | 10 ++++++++++ tools/lib/bpf/libbpf.map | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index ab40dbf9f020..c1e66e190982 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -881,6 +881,11 @@ int bpf_link_create(int prog_fd, int target_fd, if (!OPTS_ZEROED(opts, cgroup)) return libbpf_err(-EINVAL); break; + case BPF_STRUCT_OPS: + attr.link_create.struct_ops.cookie = OPTS_GET(opts, struct_ops.cookie, 0); + if (!OPTS_ZEROED(opts, struct_ops)) + return libbpf_err(-EINVAL); + break; default: if (!OPTS_ZEROED(opts, flags)) return libbpf_err(-EINVAL); diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 7252150e7ad3..2386ad4a295c 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -443,6 +443,9 @@ struct bpf_link_create_opts { __u32 relative_id; __u64 expected_revision; } cgroup; + struct { + __u64 cookie; + } struct_ops; }; size_t :0; }; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index aee36402f0a3..f5b71eccd5cc 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -13110,10 +13110,20 @@ static int bpf_link__detach_struct_ops(struct bpf_link *link) struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map) { + return bpf_map__attach_struct_ops_opts(map, NULL); +} + +struct bpf_link *bpf_map__attach_struct_ops_opts(const struct bpf_map *map, + const struct bpf_struct_ops_opts *opts) +{ + LIBBPF_OPTS(bpf_link_create_opts, link_create_opts); struct bpf_link_struct_ops *link; __u32 zero = 0; int err, fd; + if (!OPTS_VALID(opts, bpf_struct_ops_opts)) + return libbpf_err_ptr(-EINVAL); + if (!bpf_map__is_struct_ops(map)) { pr_warn("map '%s': can't attach non-struct_ops map\n", map->name); return libbpf_err_ptr(-EINVAL); @@ -13149,7 +13159,9 @@ struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map) return &link->link; } - fd = bpf_link_create(map->fd, 0, BPF_STRUCT_OPS, NULL); + link_create_opts.struct_ops.cookie = OPTS_GET(opts, cookie, 0); + + fd = bpf_link_create(map->fd, 0, BPF_STRUCT_OPS, &link_create_opts); if (fd < 0) { free(link); return libbpf_err_ptr(fd); diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index d1cf813a057b..a4a758a8a25b 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -894,6 +894,16 @@ bpf_program__attach_cgroup_opts(const struct bpf_program *prog, int cgroup_fd, struct bpf_map; +struct bpf_struct_ops_opts { + /* size of this struct, for forward/backward compatibility */ + size_t sz; + __u64 cookie; + size_t :0; +}; +#define bpf_struct_ops_opts__last_field cookie + +LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops_opts(const struct bpf_map *map, + const struct bpf_struct_ops_opts* opts); LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map); LIBBPF_API int bpf_link__update_map(struct bpf_link *link, const struct bpf_map *map); diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 1bbf77326420..6998300c766a 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -439,6 +439,7 @@ LIBBPF_1.6.0 { bpf_object__prepare; bpf_prog_stream_read; bpf_program__attach_cgroup_opts; + bpf_map__attach_struct_ops_opts; bpf_program__func_info; bpf_program__func_info_cnt; bpf_program__line_info; -- 2.47.1