d10ef2b825
Add a new unified OPTS-based low-level API for program loading, bpf_prog_load() ([0]). bpf_prog_load() accepts few "mandatory" parameters as input arguments (program type, name, license, instructions) and all the other optional (as in not required to specify for all types of BPF programs) fields into struct bpf_prog_load_opts. This makes all the other non-extensible APIs variant for BPF_PROG_LOAD obsolete and they are slated for deprecation in libbpf v0.7: - bpf_load_program(); - bpf_load_program_xattr(); - bpf_verify_program(). Implementation-wise, internal helper libbpf__bpf_prog_load is refactored to become a public bpf_prog_load() API. struct bpf_prog_load_params used internally is replaced by public struct bpf_prog_load_opts. Unfortunately, while conceptually all this is pretty straightforward, the biggest complication comes from the already existing bpf_prog_load() *high-level* API, which has nothing to do with BPF_PROG_LOAD command. We try really hard to have a new API named bpf_prog_load(), though, because it maps naturally to BPF_PROG_LOAD command. For that, we rename old bpf_prog_load() into bpf_prog_load_deprecated() and mark it as COMPAT_VERSION() for shared library users compiled against old version of libbpf. Statically linked users and shared lib users compiled against new version of libbpf headers will get "rerouted" to bpf_prog_deprecated() through a macro helper that decides whether to use new or old bpf_prog_load() based on number of input arguments (see ___libbpf_overload in libbpf_common.h). To test that existing bpf_prog_load()-using code compiles and works as expected, I've compiled and ran selftests as is. I had to remove (locally) selftest/bpf/Makefile -Dbpf_prog_load=bpf_prog_test_load hack because it was conflicting with the macro-based overload approach. I don't expect anyone else to do something like this in practice, though. This is testing-specific way to replace bpf_prog_load() calls with special testing variant of it, which adds extra prog_flags value. After testing I kept this selftests hack, but ensured that we use a new bpf_prog_load_deprecated name for this. This patch also marks bpf_prog_load() and bpf_prog_load_xattr() as deprecated. bpf_object interface has to be used for working with struct bpf_program. Libbpf doesn't support loading just a bpf_program. The silver lining is that when we get to libbpf 1.0 all these complication will be gone and we'll have one clean bpf_prog_load() low-level API with no backwards compatibility hackery surrounding it. [0] Closes: https://github.com/libbpf/libbpf/issues/284 Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20211103220845.2676888-4-andrii@kernel.org
79 lines
2.8 KiB
C
79 lines
2.8 KiB
C
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
|
|
|
/*
|
|
* Common user-facing libbpf helpers.
|
|
*
|
|
* Copyright (c) 2019 Facebook
|
|
*/
|
|
|
|
#ifndef __LIBBPF_LIBBPF_COMMON_H
|
|
#define __LIBBPF_LIBBPF_COMMON_H
|
|
|
|
#include <string.h>
|
|
#include "libbpf_version.h"
|
|
|
|
#ifndef LIBBPF_API
|
|
#define LIBBPF_API __attribute__((visibility("default")))
|
|
#endif
|
|
|
|
#define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
|
|
|
/* Mark a symbol as deprecated when libbpf version is >= {major}.{minor} */
|
|
#define LIBBPF_DEPRECATED_SINCE(major, minor, msg) \
|
|
__LIBBPF_MARK_DEPRECATED_ ## major ## _ ## minor \
|
|
(LIBBPF_DEPRECATED("libbpf v" # major "." # minor "+: " msg))
|
|
|
|
#define __LIBBPF_CURRENT_VERSION_GEQ(major, minor) \
|
|
(LIBBPF_MAJOR_VERSION > (major) || \
|
|
(LIBBPF_MAJOR_VERSION == (major) && LIBBPF_MINOR_VERSION >= (minor)))
|
|
|
|
/* Add checks for other versions below when planning deprecation of API symbols
|
|
* with the LIBBPF_DEPRECATED_SINCE macro.
|
|
*/
|
|
#if __LIBBPF_CURRENT_VERSION_GEQ(0, 6)
|
|
#define __LIBBPF_MARK_DEPRECATED_0_6(X) X
|
|
#else
|
|
#define __LIBBPF_MARK_DEPRECATED_0_6(X)
|
|
#endif
|
|
#if __LIBBPF_CURRENT_VERSION_GEQ(0, 7)
|
|
#define __LIBBPF_MARK_DEPRECATED_0_7(X) X
|
|
#else
|
|
#define __LIBBPF_MARK_DEPRECATED_0_7(X)
|
|
#endif
|
|
|
|
/* This set of internal macros allows to do "function overloading" based on
|
|
* number of arguments provided by used in backwards-compatible way during the
|
|
* transition to libbpf 1.0
|
|
* It's ugly but necessary evil that will be cleaned up when we get to 1.0.
|
|
* See bpf_prog_load() overload for example.
|
|
*/
|
|
#define ___libbpf_cat(A, B) A ## B
|
|
#define ___libbpf_select(NAME, NUM) ___libbpf_cat(NAME, NUM)
|
|
#define ___libbpf_nth(_1, _2, _3, _4, _5, _6, N, ...) N
|
|
#define ___libbpf_cnt(...) ___libbpf_nth(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
|
|
#define ___libbpf_overload(NAME, ...) ___libbpf_select(NAME, ___libbpf_cnt(__VA_ARGS__))(__VA_ARGS__)
|
|
|
|
/* Helper macro to declare and initialize libbpf options struct
|
|
*
|
|
* This dance with uninitialized declaration, followed by memset to zero,
|
|
* followed by assignment using compound literal syntax is done to preserve
|
|
* ability to use a nice struct field initialization syntax and **hopefully**
|
|
* have all the padding bytes initialized to zero. It's not guaranteed though,
|
|
* when copying literal, that compiler won't copy garbage in literal's padding
|
|
* bytes, but that's the best way I've found and it seems to work in practice.
|
|
*
|
|
* Macro declares opts struct of given type and name, zero-initializes,
|
|
* including any extra padding, it with memset() and then assigns initial
|
|
* values provided by users in struct initializer-syntax as varargs.
|
|
*/
|
|
#define LIBBPF_OPTS(TYPE, NAME, ...) \
|
|
struct TYPE NAME = ({ \
|
|
memset(&NAME, 0, sizeof(struct TYPE)); \
|
|
(struct TYPE) { \
|
|
.sz = sizeof(struct TYPE), \
|
|
__VA_ARGS__ \
|
|
}; \
|
|
})
|
|
|
|
#endif /* __LIBBPF_LIBBPF_COMMON_H */
|