summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChenbo Feng <fengc@google.com>2019-02-14 22:38:40 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-02-14 22:38:40 -0800
commitee1baa2595f2b4ca49cbcfafc187c8664358452a (patch)
treeced0287197758ccc76eaff59d4deb2de197e01e6
parent58f2a67c68d3de7504086fb076789fc56636b240 (diff)
parent4ff780c0e50b636fcf6d4597c52053503174acb6 (diff)
downloadandroid_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.cpp30
-rw-r--r--libbpf_android/include/bpf/BpfUtils.h29
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;