diff options
author | Chenbo Feng <fengc@google.com> | 2019-02-14 22:38:40 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-02-14 22:38:40 -0800 |
commit | ee1baa2595f2b4ca49cbcfafc187c8664358452a (patch) | |
tree | ced0287197758ccc76eaff59d4deb2de197e01e6 | |
parent | 58f2a67c68d3de7504086fb076789fc56636b240 (diff) | |
parent | 4ff780c0e50b636fcf6d4597c52053503174acb6 (diff) | |
download | android_system_bpf-ee1baa2595f2b4ca49cbcfafc187c8664358452a.tar.gz android_system_bpf-ee1baa2595f2b4ca49cbcfafc187c8664358452a.tar.bz2 android_system_bpf-ee1baa2595f2b4ca49cbcfafc187c8664358452a.zip |
Merge "Add detailed kernel version when checking bpf support" am: 7dacd1b72a am: d61ee6c7d8
am: 4ff780c0e5
Change-Id: I0a3cc532cb6203f2a4b098906f238ab81e465b7c
-rw-r--r-- | libbpf_android/BpfUtils.cpp | 30 | ||||
-rw-r--r-- | libbpf_android/include/bpf/BpfUtils.h | 29 |
2 files changed, 47 insertions, 12 deletions
diff --git a/libbpf_android/BpfUtils.cpp b/libbpf_android/BpfUtils.cpp index 74585b2..109715b 100644 --- a/libbpf_android/BpfUtils.cpp +++ b/libbpf_android/BpfUtils.cpp @@ -237,7 +237,17 @@ int synchronizeKernelRCU() { return 0; } -bool hasBpfSupport() { +std::string BpfLevelToString(BpfLevel bpfLevel) { + switch (bpfLevel) { + case BpfLevel::NONE: return "NONE_SUPPORT"; + case BpfLevel::BASIC: return "BPF_LEVEL_BASIC"; + case BpfLevel::EXTENDED: return "BPF_LEVEL_EXTENDED"; + // No default statement. We want to see errors of the form: + // "enumeration value 'BPF_LEVEL_xxx' not handled in switch [-Werror,-Wswitch]". + } +} + +BpfLevel getBpfSupportLevel() { struct utsname buf; int kernel_version_major; int kernel_version_minor; @@ -248,18 +258,22 @@ bool hasBpfSupport() { api_level = GetUintProperty<uint64_t>("ro.build.version.sdk", 0); } + // Check if the device is shipped originally with android P. + if (api_level < MINIMUM_API_REQUIRED) return BpfLevel::NONE; + int ret = uname(&buf); if (ret) { - return false; + return BpfLevel::NONE; } char dummy; ret = sscanf(buf.release, "%d.%d%c", &kernel_version_major, &kernel_version_minor, &dummy); - if (ret >= 2 && - ((kernel_version_major > 4) || (kernel_version_major == 4 && kernel_version_minor >= 9))) { - // Check if the device is shipped originally with android P. - return api_level >= MINIMUM_API_REQUIRED; - } - return false; + // Check the device kernel version + if (ret < 2) return BpfLevel::NONE; + if (kernel_version_major > 4 || (kernel_version_major == 4 && kernel_version_minor >= 14)) + return BpfLevel::EXTENDED; + if (kernel_version_major == 4 && kernel_version_minor >= 9) return BpfLevel::BASIC; + + return BpfLevel::NONE; } int loadAndPinProgram(BpfProgInfo* prog, Slice progBlock) { diff --git a/libbpf_android/include/bpf/BpfUtils.h b/libbpf_android/include/bpf/BpfUtils.h index 296b0fd..77a18fa 100644 --- a/libbpf_android/include/bpf/BpfUtils.h +++ b/libbpf_android/include/bpf/BpfUtils.h @@ -121,6 +121,18 @@ struct BpfMapInfo { } }; +enum class BpfLevel { + // Devices shipped before P or kernel version is lower than 4.9 do not + // have eBPF enabled. + NONE, + // Devices shipped in P with android 4.9 kernel only have the basic eBPF + // functionalities such as xt_bpf and cgroup skb filter. + BASIC, + // For devices that have 4.14 kernel. It supports advanced features like + // map_in_map and cgroup socket filter. + EXTENDED, +}; + #ifndef DEFAULT_OVERFLOWUID #define DEFAULT_OVERFLOWUID 65534 #endif @@ -145,14 +157,23 @@ int bpfFdGet(const char* pathname, uint32_t flags); int attachProgram(bpf_attach_type type, uint32_t prog_fd, uint32_t cg_fd); int detachProgram(bpf_attach_type type, uint32_t cg_fd); uint64_t getSocketCookie(int sockFd); -bool hasBpfSupport(); +std::string BpfLevelToString(BpfLevel BpfLevel); +BpfLevel getBpfSupportLevel(); int parseProgramsFromFile(const char* path, BpfProgInfo* programs, size_t size, const std::vector<BpfMapInfo>& mapPatterns); int synchronizeKernelRCU(); -#define SKIP_IF_BPF_NOT_SUPPORTED \ - do { \ - if (!hasBpfSupport()) return; \ +#define SKIP_IF_BPF_NOT_SUPPORTED \ + do { \ + if (android::bpf::getBpfSupportLevel() == android::bpf::BpfLevel::NONE) { \ + GTEST_LOG_(INFO) << "This test is skipped since bpf is not available\n"; \ + return; \ + } \ + } while (0) + +#define SKIP_IF_BPF_SUPPORTED \ + do { \ + if (android::bpf::getBpfSupportLevel() != android::bpf::BpfLevel::NONE) return; \ } while (0) constexpr int BPF_CONTINUE = 0; |