libbpf: Add non-CO-RE variants of BPF_CORE_READ() macro family
authorAndrii Nakryiko <andrii@kernel.org>
Fri, 18 Dec 2020 23:56:13 +0000 (15:56 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 8 Jan 2021 21:39:24 +0000 (13:39 -0800)
BPF_CORE_READ(), in addition to handling CO-RE relocations, also allows much
nicer way to read data structures with nested pointers. Instead of writing
a sequence of bpf_probe_read() calls to follow links, one can just write
BPF_CORE_READ(a, b, c, d) to effectively do a->b->c->d read. This is a welcome
ability when porting BCC code, which (in most cases) allows exactly the
intuitive a->b->c->d variant.

This patch adds non-CO-RE variants of BPF_CORE_READ() family of macros for
cases where CO-RE is not supported (e.g., old kernels). In such cases, the
property of shortening a sequence of bpf_probe_read()s to a simple
BPF_PROBE_READ(a, b, c, d) invocation is still desirable, especially when
porting BCC code to libbpf. Yet, no CO-RE relocation is going to be emitted.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20201218235614.2284956-3-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/lib/bpf/bpf_core_read.h

index db0c735..9456aab 100644 (file)
@@ -308,6 +308,18 @@ enum bpf_enum_value_kind {
                     dst, (src), a, ##__VA_ARGS__)                          \
 })
 
+/* Non-CO-RE variant of BPF_CORE_READ_INTO() */
+#define BPF_PROBE_READ_INTO(dst, src, a, ...) ({                           \
+       ___core_read(bpf_probe_read, bpf_probe_read,                        \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
+/* Non-CO-RE variant of BPF_CORE_READ_USER_INTO() */
+#define BPF_PROBE_READ_USER_INTO(dst, src, a, ...) ({                      \
+       ___core_read(bpf_probe_read_user, bpf_probe_read_user,              \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
 /*
  * BPF_CORE_READ_STR_INTO() does same "pointer chasing" as
  * BPF_CORE_READ() for intermediate pointers, but then executes (and returns
@@ -324,6 +336,18 @@ enum bpf_enum_value_kind {
                     dst, (src), a, ##__VA_ARGS__)                          \
 })
 
+/* Non-CO-RE variant of BPF_CORE_READ_STR_INTO() */
+#define BPF_PROBE_READ_STR_INTO(dst, src, a, ...) ({                       \
+       ___core_read(bpf_probe_read_str, bpf_probe_read,                    \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
+/* Non-CO-RE variant of BPF_CORE_READ_USER_STR_INTO() */
+#define BPF_PROBE_READ_USER_STR_INTO(dst, src, a, ...) ({                  \
+       ___core_read(bpf_probe_read_user_str, bpf_probe_read_user,          \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
 /*
  * BPF_CORE_READ() is used to simplify BPF CO-RE relocatable read, especially
  * when there are few pointer chasing steps.
@@ -361,5 +385,19 @@ enum bpf_enum_value_kind {
        __r;                                                                \
 })
 
+/* Non-CO-RE variant of BPF_CORE_READ() */
+#define BPF_PROBE_READ(src, a, ...) ({                                     \
+       ___type((src), a, ##__VA_ARGS__) __r;                               \
+       BPF_PROBE_READ_INTO(&__r, (src), a, ##__VA_ARGS__);                 \
+       __r;                                                                \
+})
+
+/* Non-CO-RE variant of BPF_CORE_READ_USER() */
+#define BPF_PROBE_READ_USER(src, a, ...) ({                                \
+       ___type((src), a, ##__VA_ARGS__) __r;                               \
+       BPF_PROBE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__);            \
+       __r;                                                                \
+})
+
 #endif