summaryrefslogtreecommitdiff
path: root/libbpf_android
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2021-03-04 07:27:38 -0800
committerMaciej Żenczykowski <maze@google.com>2021-03-05 06:00:59 +0000
commitcb358de06790032415709c982baf1226f68a13a0 (patch)
tree7450fc0430d81102816d75ae0d16b5ba6030d6fc /libbpf_android
parentfd59a4a0a624f4e3161742b25818c30deef30d4f (diff)
downloadbpf-cb358de06790032415709c982baf1226f68a13a0.tar.gz
bpfloader: auto-demote DEVMAP/DEVMAP_HASH map types on too old kernels
Basically: <4.14: DEVMAP -> ARRAY <5.4: DEVMAP_HASH -> HASH See added comments for explanation of why, but basically: This allows our bpf program .o files to load maps on all kernel versions, even if those map types are not supported by the kernel. This avoids the need for code that conditionally creates maps based on kernel version. Any program that actually attempts to use one of these maps will fail to load, but programs are already loaded conditionally based on kernel version so this is not a problem. Test: atest, TreeHugger Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I1a1d73b68de3606423de078fddb224402621e154
Diffstat (limited to 'libbpf_android')
-rw-r--r--libbpf_android/Loader.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index e0d56e4..dbd198d 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -446,7 +446,28 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
ALOGD("bpf_create_map reusing map %s, ret: %d\n", mapNames[i].c_str(), fd.get());
reuse = true;
} else {
- fd.reset(bpf_create_map(md[i].type, mapNames[i].c_str(), md[i].key_size, md[i].value_size,
+ enum bpf_map_type type = md[i].type;
+ if (type == BPF_MAP_TYPE_DEVMAP && !isAtLeastKernelVersion(4, 14, 0)) {
+ // On Linux Kernels older than 4.14 this map type doesn't exist, but it can kind
+ // of be approximated: ARRAY has the same userspace api, though it is not usable
+ // by the same ebpf programs. However, that's okay because the bpf_redirect_map()
+ // helper doesn't exist on 4.9 anyway (so the bpf program would fail to load,
+ // and thus needs to be tagged as 4.14+ either way), so there's nothing useful you
+ // could do with a DEVMAP anyway (that isn't already provided by an ARRAY)...
+ // Hence using an ARRAY instead of a DEVMAP simply makes life easier for userspace.
+ type = BPF_MAP_TYPE_ARRAY;
+ }
+ if (type == BPF_MAP_TYPE_DEVMAP_HASH && !isAtLeastKernelVersion(5, 4, 0)) {
+ // On Linux Kernels older than 5.4 this map type doesn't exist, but it can kind
+ // of be approximated: HASH has the same userspace visible api.
+ // However it cannot be used by ebpf programs in the same way.
+ // Since bpf_redirect_map() only requires 4.14, a program using a DEVMAP_HASH map
+ // would fail to load (due to trying to redirect to a HASH instead of DEVMAP_HASH).
+ // One must thus tag any BPF_MAP_TYPE_DEVMAP_HASH + bpf_redirect_map() using
+ // programs as being 5.4+...
+ type = BPF_MAP_TYPE_HASH;
+ }
+ fd.reset(bpf_create_map(type, mapNames[i].c_str(), md[i].key_size, md[i].value_size,
md[i].max_entries, md[i].map_flags));
saved_errno = errno;
ALOGD("bpf_create_map name %s, ret: %d\n", mapNames[i].c_str(), fd.get());