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/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 @@
}
};
+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 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;