Renames src/shared/bpf-dlopen.{c,h} to src/shared/bpf-util.{c,h} and
folds the former src/shared/bpf-compat.h (struct forward decl and
compat_bpf_map_create() helper) into the new header.
Aligns dlopen_bpf() with the standard wrapper pattern: drops the
manual dlopen_safe()/dlsym_many_or_warn()/TAKE_PTR(dl) plumbing and
the bespoke 'cached' int in favor of dlopen_many_sym_or_warn() inside
a FOREACH_STRING() soname-fallback loop.
Unifies declaration of the version-specific symbols (bpf_create_map,
bpf_map_create, bpf_object__next_map, bpf_token_create) into a single
DISABLE_WARNING_REDUNDANT_DECLS block in the header, and alphabetically
merges the DLSYM_PROTOTYPE list. DLSYM_OPTIONAL is used to load each
one — call sites already handle NULL (compat_bpf_map_create() and the
sym_bpf_object__next_map guard in userns-restrict.c). bpf_token_create
additionally defaults to a missing_bpf_token_create() stub returning
-ENOSYS, so callers can branch on the errno instead of NULL-checking
the pointer.
Updates test-bpf-token to match: drops the compile-time
LIBBPF_MAJOR_VERSION ≥ 1.5 gate and the direct <bpf/bpf.h> include in
favor of dlopen_bpf() + sym_bpf_token_create(), and treats -ENOSYS as
the test-skip path (covering both 'libbpf too old' and 'kernel lacks
BPF_TOKEN_CREATE support').
67 lines
2.1 KiB
C
67 lines
2.1 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "bpf-util.h"
|
|
#include "bpf-link.h"
|
|
#include "serialize.h"
|
|
|
|
bool bpf_can_link_program(struct bpf_program *prog) {
|
|
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
|
|
|
|
assert(prog);
|
|
|
|
if (dlopen_bpf(LOG_DEBUG) < 0)
|
|
return false;
|
|
|
|
/* Pass invalid cgroup fd intentionally. */
|
|
link = sym_bpf_program__attach_cgroup(prog, /* cgroup_fd= */ -1);
|
|
|
|
/* EBADF indicates that bpf_link is supported by kernel. */
|
|
return bpf_get_error_translated(link) == -EBADF;
|
|
}
|
|
|
|
bool bpf_can_link_lsm_program(struct bpf_program *prog) {
|
|
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
|
|
|
|
assert(prog);
|
|
|
|
if (dlopen_bpf(LOG_DEBUG) < 0)
|
|
return false;
|
|
|
|
link = sym_bpf_program__attach_lsm(prog);
|
|
|
|
/* If bpf_program__attach_lsm fails the resulting value stores libbpf error code instead of memory
|
|
* pointer. That is the case when the helper is called on architectures where BPF trampoline (hence
|
|
* BPF_LSM_MAC attach type) is not supported. */
|
|
return bpf_get_error_translated(link) == 0;
|
|
}
|
|
|
|
int bpf_serialize_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *link) {
|
|
assert(key);
|
|
|
|
if (!link)
|
|
return -ENOENT;
|
|
|
|
if (bpf_get_error_translated(link) != 0)
|
|
return -EINVAL;
|
|
|
|
return serialize_fd(f, fds, key, sym_bpf_link__fd(link));
|
|
}
|
|
|
|
struct bpf_link* bpf_link_free(struct bpf_link *link) {
|
|
/* If libbpf wasn't dlopen()ed, sym_bpf_link__destroy might be unresolved (NULL), so let's not try to
|
|
* call it if link is NULL. link might also be a non-null "error pointer", but such a value can only
|
|
* originate from a call to libbpf, but that means that libbpf is available, and we can let
|
|
* bpf_link__destroy() handle it. */
|
|
if (link)
|
|
(void) sym_bpf_link__destroy(link);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct ring_buffer* bpf_ring_buffer_free(struct ring_buffer *rb) {
|
|
if (rb) /* See the comment in bpf_link_free(). */
|
|
sym_ring_buffer__free(rb);
|
|
|
|
return NULL;
|
|
}
|