Add macro to create BPF ring buffers.
BPF ring buffers are defined like maps, but cannot specify a key or
value size (attempting to do so is a verifier error). This change also
adds the type-safe methods for interacting with the map (output, reserve
and submit).
Bug: 246985031
Test: local run of Network Tracing w/ ring buffers
Change-Id: Ie8a47d987be6cb219fe7d73f2c61a56e3a3ab21a
diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
index c652c76..ea56593 100644
--- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -137,6 +137,14 @@
BPF_FUNC_map_update_elem;
static int (*bpf_map_delete_elem_unsafe)(const struct bpf_map_def* map,
const void* key) = (void*)BPF_FUNC_map_delete_elem;
+static int (*bpf_ringbuf_output_unsafe)(const struct bpf_map_def* ringbuf,
+ const void* data, __u64 size, __u64 flags) = (void*)
+ BPF_FUNC_ringbuf_output;
+static void* (*bpf_ringbuf_reserve_unsafe)(const struct bpf_map_def* ringbuf,
+ __u64 size, __u64 flags) = (void*)
+ BPF_FUNC_ringbuf_reserve;
+static void (*bpf_ringbuf_submit_unsafe)(const void* data, __u64 flags) = (void*)
+ BPF_FUNC_ringbuf_submit;
#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
struct ____btf_map_##name { \
@@ -147,6 +155,50 @@
__attribute__ ((section(".maps." #name), used)) \
____btf_map_##name = { }
+#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, \
+ usr, grp, md, selinux, pindir, share, minkver, \
+ maxkver) \
+ const struct bpf_map_def SECTION("maps") the_map = { \
+ .type = BPF_MAP_TYPE_##TYPE, \
+ .key_size = (keysize), \
+ .value_size = (valuesize), \
+ .max_entries = (num_entries), \
+ .map_flags = 0, \
+ .uid = (usr), \
+ .gid = (grp), \
+ .mode = (md), \
+ .bpfloader_min_ver = DEFAULT_BPFLOADER_MIN_VER, \
+ .bpfloader_max_ver = DEFAULT_BPFLOADER_MAX_VER, \
+ .min_kver = (minkver), \
+ .max_kver = (maxkver), \
+ .selinux_context = (selinux), \
+ .pin_subdir = (pindir), \
+ .shared = (share), \
+ };
+
+// Type safe macro to declare a ring buffer and related output functions.
+// Compatibility:
+// * BPF ring buffers are only available kernels 5.8 and above. Any program
+// accessing the ring buffer should set a program level min_kver >= 5.8.
+// * The definition below sets a map min_kver of 5.8 which requires targeting
+// a BPFLOADER_MIN_VER >= BPFLOADER_S_VERSION.
+#define DEFINE_BPF_RINGBUF(the_map, ValueType, size_bytes, usr, grp, md, \
+ selinux, pindir, share) \
+ DEFINE_BPF_MAP_BASE(the_map, RINGBUF, 0, 0, size_bytes, usr, grp, md, \
+ selinux, pindir, share, KVER(5, 8, 0), KVER_INF); \
+ static inline __always_inline __unused int bpf_##the_map##_output( \
+ const ValueType* v) { \
+ return bpf_ringbuf_output_unsafe(&the_map, v, sizeof(*v), 0); \
+ } \
+ static inline __always_inline __unused \
+ ValueType* bpf_##the_map##_reserve() { \
+ return bpf_ringbuf_reserve_unsafe(&the_map, sizeof(ValueType), 0); \
+ } \
+ static inline __always_inline __unused void bpf_##the_map##_submit( \
+ const ValueType* v) { \
+ bpf_ringbuf_submit_unsafe(v, 0); \
+ }
+
/* There exist buggy kernels with pre-T OS, that due to
* kernel patch "[ALPS05162612] bpf: fix ubsan error"
* do not support userspace writes into non-zero index of bpf map arrays.
@@ -167,23 +219,9 @@
/* type safe macro to declare a map and related accessor functions */
#define DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
selinux, pindir, share) \
- const struct bpf_map_def SECTION("maps") the_map = { \
- .type = BPF_MAP_TYPE_##TYPE, \
- .key_size = sizeof(KeyType), \
- .value_size = sizeof(ValueType), \
- .max_entries = (num_entries), \
- .map_flags = 0, \
- .uid = (usr), \
- .gid = (grp), \
- .mode = (md), \
- .bpfloader_min_ver = DEFAULT_BPFLOADER_MIN_VER, \
- .bpfloader_max_ver = DEFAULT_BPFLOADER_MAX_VER, \
- .min_kver = KVER_NONE, \
- .max_kver = KVER_INF, \
- .selinux_context = selinux, \
- .pin_subdir = pindir, \
- .shared = share, \
- }; \
+ DEFINE_BPF_MAP_BASE(the_map, TYPE, sizeof(KeyType), sizeof(ValueType), \
+ num_entries, usr, grp, md, selinux, pindir, share, \
+ KVER_NONE, KVER_INF); \
BPF_MAP_ASSERT_OK(BPF_MAP_TYPE_##TYPE, (num_entries), (md)); \
BPF_ANNOTATE_KV_PAIR(the_map, KeyType, ValueType); \
\