mirror of
https://github.com/netdata/libbpf.git
synced 2026-11-05 17:30:15 +08:00
libbpf: Support attaching struct_ops to a cgroup
Add bpf_map__attach_cgroup_opts() to attach a struct_ops map to a cgroup through a BPF link. Also extend struct bpf_prog_query_opts with a type_id field so a BPF_STRUCT_OPS query on a cgroup can select the struct_ops type to enumerate. Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Amery Hung <ameryhung@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://patch.msgid.link/20260917200542.3689605-14-ameryhung@gmail.com
This commit is contained in:
1 parent
bc48d4e164
commit
ab48c6f1ba
5 files changed
+72
-1
No files matched your search
@@ -934,6 +934,7 @@ int bpf_link_create(int prog_fd, int target_fd,
|
||||
case BPF_CGROUP_GETSOCKOPT:
|
||||
case BPF_CGROUP_SETSOCKOPT:
|
||||
case BPF_LSM_CGROUP:
|
||||
case BPF_STRUCT_OPS:
|
||||
relative_fd = OPTS_GET(opts, cgroup.relative_fd, 0);
|
||||
relative_id = OPTS_GET(opts, cgroup.relative_id, 0);
|
||||
if (relative_fd && relative_id)
|
||||
@@ -1056,6 +1057,7 @@ int bpf_prog_query_opts(int target, enum bpf_attach_type type,
|
||||
attr.query.attach_type = type;
|
||||
attr.query.query_flags = OPTS_GET(opts, query_flags, 0);
|
||||
attr.query.count = OPTS_GET(opts, count, 0);
|
||||
attr.query.type_id = OPTS_GET(opts, type_id, 0);
|
||||
attr.query.prog_ids = ptr_to_u64(OPTS_GET(opts, prog_ids, NULL));
|
||||
attr.query.link_ids = ptr_to_u64(OPTS_GET(opts, link_ids, NULL));
|
||||
attr.query.prog_attach_flags = ptr_to_u64(OPTS_GET(opts, prog_attach_flags, NULL));
|
||||
|
||||
@@ -637,9 +637,10 @@ struct bpf_prog_query_opts {
|
||||
__u32 *link_ids;
|
||||
__u32 *link_attach_flags;
|
||||
__u64 revision;
|
||||
__u32 type_id;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_prog_query_opts__last_field revision
|
||||
#define bpf_prog_query_opts__last_field type_id
|
||||
|
||||
/**
|
||||
* @brief **bpf_prog_query_opts()** queries the BPF programs and BPF links
|
||||
|
||||
@@ -14174,6 +14174,70 @@ struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map)
|
||||
return &link->link;
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_map__attach_cgroup_opts(const struct bpf_map *map, int cgroup_fd,
|
||||
const struct bpf_cgroup_opts *opts)
|
||||
{
|
||||
LIBBPF_OPTS(bpf_link_create_opts, link_create_opts);
|
||||
struct bpf_link_struct_ops *link;
|
||||
__u32 relative_id, zero = 0;
|
||||
int err, fd, relative_fd;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_cgroup_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);
|
||||
}
|
||||
|
||||
if (map->fd < 0) {
|
||||
pr_warn("map '%s': can't attach BPF map without FD (was it created?)\n", map->name);
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
}
|
||||
|
||||
if (!(map->def.map_flags & BPF_F_LINK)) {
|
||||
pr_warn("map '%s': can't attach to cgroup without BPF_F_LINK\n", map->name);
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
}
|
||||
|
||||
relative_id = OPTS_GET(opts, relative_id, 0);
|
||||
relative_fd = OPTS_GET(opts, relative_fd, 0);
|
||||
|
||||
if (relative_fd && relative_id) {
|
||||
pr_warn("map '%s': relative_fd and relative_id cannot be set at the same time\n",
|
||||
map->name);
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
}
|
||||
|
||||
link_create_opts.cgroup.expected_revision = OPTS_GET(opts, expected_revision, 0);
|
||||
link_create_opts.cgroup.relative_fd = relative_fd;
|
||||
link_create_opts.cgroup.relative_id = relative_id;
|
||||
link_create_opts.flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
link = calloc(1, sizeof(*link));
|
||||
if (!link)
|
||||
return libbpf_err_ptr(-ENOMEM);
|
||||
|
||||
err = bpf_map_update_elem(map->fd, &zero, map->st_ops->kern_vdata, 0);
|
||||
if (err && err != -EBUSY) {
|
||||
free(link);
|
||||
return libbpf_err_ptr(err);
|
||||
}
|
||||
|
||||
link->link.detach = bpf_link__detach_struct_ops;
|
||||
|
||||
fd = bpf_link_create(map->fd, cgroup_fd, BPF_STRUCT_OPS, &link_create_opts);
|
||||
if (fd < 0) {
|
||||
free(link);
|
||||
return libbpf_err_ptr(fd);
|
||||
}
|
||||
|
||||
link->link.fd = fd;
|
||||
link->map_fd = map->fd;
|
||||
|
||||
return &link->link;
|
||||
}
|
||||
|
||||
/*
|
||||
* Swap the back struct_ops of a link with a new struct_ops map.
|
||||
*/
|
||||
|
||||
@@ -960,6 +960,9 @@ bpf_program__attach_cgroup_opts(const struct bpf_program *prog, int cgroup_fd,
|
||||
struct bpf_map;
|
||||
|
||||
LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map);
|
||||
LIBBPF_API struct bpf_link *bpf_map__attach_cgroup_opts(const struct bpf_map *map,
|
||||
int cgroup_fd,
|
||||
const struct bpf_cgroup_opts *opts);
|
||||
LIBBPF_API int bpf_link__update_map(struct bpf_link *link, const struct bpf_map *map);
|
||||
|
||||
struct bpf_iter_attach_opts {
|
||||
|
||||
@@ -458,6 +458,7 @@ LIBBPF_1.7.0 {
|
||||
|
||||
LIBBPF_1.8.0 {
|
||||
global:
|
||||
bpf_map__attach_cgroup_opts;
|
||||
bpf_program__add_flags;
|
||||
bpf_program__attach_tracing_multi;
|
||||
bpf_program__clear_flags;
|
||||
|
||||
Reference in new issue
Block a user