NetBpfLoad: Add libbpf-style map definitions for libbpf support
This updates the BPF map macros so programs can be loaded by both the
existing code and the libbpf.
The macros now generate ".maps" section in addition to the
".android_maps" section.
To prevent name collisions, the legacy map definitions are suffixed with
_def. This CL also adds the readMapNames method to get map names from
the ".android_maps" section, allowing the existing code path to continue
working.
Bug: 428792764
Flag: EXEMPT no-op
Test: TH
Change-Id: Ibe6f100b5684bc85d2cf9c100f2431740fa516ca
diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp
index b88cb66..44070b7 100644
--- a/bpf/loader/NetBpfLoad.cpp
+++ b/bpf/loader/NetBpfLoad.cpp
@@ -868,6 +868,22 @@
return type != BPF_MAP_TYPE_DEVMAP_HASH && type != BPF_MAP_TYPE_RINGBUF;
}
+static int readMapNames(ifstream& elfFile, vector<string>& mapNames) {
+ int ret = getSectionSymNames(elfFile, ".android_maps", mapNames);
+ if (ret) return ret;
+
+ const string suffix = "_def";
+ for (string& name : mapNames) {
+ if (EndsWith(name, suffix)) {
+ name.erase(name.length() - suffix.length());
+ } else {
+ ALOGE("Failed to get map names, invalid symbol in .android_maps: %s", name.c_str());
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>& mapFds,
const char* prefix, const unsigned int bpfloader_ver) {
int ret;
@@ -880,7 +896,7 @@
if (ret == -2) return 0; // no maps to read
if (ret) return ret;
- ret = getSectionSymNames(elfFile, ".android_maps", mapNames);
+ ret = readMapNames(elfFile, mapNames);
if (ret) return ret;
struct btf *btf = NULL;
@@ -1120,7 +1136,7 @@
static void applyMapRelo(ifstream& elfFile, vector<unique_fd> &mapFds, vector<codeSection>& cs) {
vector<string> mapNames;
- int ret = getSectionSymNames(elfFile, ".android_maps", mapNames);
+ int ret = readMapNames(elfFile, mapNames);
if (ret) return;
for (int k = 0; k != (int)cs.size(); k++) {
diff --git a/bpf/progs/include/bpf_helpers.h b/bpf/progs/include/bpf_helpers.h
index f9ab7de..76ef5a2 100644
--- a/bpf/progs/include/bpf_helpers.h
+++ b/bpf/progs/include/bpf_helpers.h
@@ -220,7 +220,7 @@
#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, \
usr, grp, md, selinux, pindir, share, minkver, \
maxkver, minloader, maxloader, mapflags) \
- const struct bpf_map_def SECTION(".android_maps") the_map = { \
+ const struct bpf_map_def SECTION(".android_maps") the_map##_def = { \
.type = BPF_MAP_TYPE_##TYPE, \
.key_size = (keysize), \
.value_size = (valuesize), \
@@ -238,6 +238,23 @@
.shared = (share).shared, \
};
+#define __uint(name, val) int (*name)[val]
+#define __type(name, val) typeof(val) *name
+
+#define DEFINE_LIBBPF_MAP(the_map, TYPE, KeyType, ValueType, num_entries) \
+ struct { \
+ __uint(type, BPF_MAP_TYPE_##TYPE); \
+ __type(key, KeyType); \
+ __type(value, ValueType); \
+ __uint(max_entries, ABSOLUTE(num_entries)); \
+ } the_map SECTION(".maps");
+
+#define DEFINE_LIBBPF_RINGBUF(the_map, num_entries) \
+ struct { \
+ __uint(type, BPF_MAP_TYPE_RINGBUF); \
+ __uint(max_entries, ABSOLUTE(num_entries)); \
+ } the_map SECTION(".maps");
+
// 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
@@ -250,6 +267,7 @@
DEFINE_BPF_MAP_BASE(the_map, RINGBUF, 0, 0, size_bytes, usr, grp, md, \
selinux, pindir, share, KVER_5_10, KVER_INF, \
min_loader, max_loader, 0); \
+ DEFINE_LIBBPF_RINGBUF(the_map, size_bytes); \
\
_Static_assert((size_bytes) >= 4096, "min 4 kiB ringbuffer size"); \
_Static_assert((size_bytes) <= 0x10000000, "max 256 MiB ringbuffer size"); \
@@ -284,6 +302,7 @@
DEFINE_BPF_MAP_BASE(the_map, SK_STORAGE, sizeof(uint32_t), sizeof(ValueType), \
0, usr, grp, md, selinux, pindir, share, \
KVER_5_10, KVER_INF, min_loader, max_loader, mapFlags); \
+ DEFINE_LIBBPF_MAP(the_map, SK_STORAGE, uint32_t, ValueType, 0); \
BPF_ANNOTATE_KV_PAIR(the_map, uint32_t, ValueType); \
\
static inline __always_inline __unused ValueType* bpf_##the_map##_get( \
@@ -324,6 +343,7 @@
DEFINE_BPF_MAP_BASE(the_map, TYPE, sizeof(KeyType), sizeof(ValueType), \
num_entries, usr, grp, md, selinux, pindir, share, \
KVER_NONE, KVER_INF, min_loader, max_loader, mapFlags); \
+ DEFINE_LIBBPF_MAP(the_map, TYPE, KeyType, ValueType, num_entries); \
BPF_MAP_ASSERT_OK(BPF_MAP_TYPE_##TYPE, (num_entries), (md)); \
_Static_assert(sizeof(KeyType) < 1024, "aosp/2370288 requires < 1024 byte keys"); \
_Static_assert(sizeof(ValueType) < 65536, "aosp/2370288 requires < 65536 byte values"); \