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:
parent
3c8fae388e
commit
e5dcaf78e3
2 changed files with 39 additions and 3 deletions
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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"); \
|
||||
|
|
|
|||
Loading…
Reference in a new issue