Add detailed kernel version when checking bpf support
For devices with 4.14 kernel shipping with bpf feature, they support more
functionality compared to 4.9 kernels. So when checking if the device
supports a given bpf feature, return a bpf level dependent on the detailed
kernel version instead of a simple boolean. This information would be
useful when we support new features such as map_in_map and cgroup socket
filters.
Bug: 111441138
Test: libnetdbpf_test, netd_integration_test
Change-Id: Ib51a56a35643ad76b58987ba1938c69905d28141
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 @@
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 @@
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) {