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
This commit is contained in:
Motomu Utsumi 2025-07-01 14:44:18 +09:00
commit e5dcaf78e3
2 changed files with 39 additions and 3 deletions

View file

@ -868,6 +868,22 @@ static bool isBtfSupported(enum bpf_map_type type) {
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 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
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 applyRelo(void* insnsPtr, Elf64_Addr offset, int fd) {
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++) {

View file

@ -220,7 +220,7 @@ static int (*bpf_sk_storage_delete_unsafe) (const void* sk_storage,
#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 @@ static int (*bpf_sk_storage_delete_unsafe) (const void* sk_storage,
.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 @@ static int (*bpf_sk_storage_delete_unsafe) (const void* sk_storage,
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 @@ static int (*bpf_sk_storage_delete_unsafe) (const void* sk_storage,
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 @@ static int (*bpf_sk_storage_delete_unsafe) (const void* sk_storage,
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"); \