KernelUtils.h: isAtLeastKernelVersion(x,y,z) - default 'z' to 0

This seems to be the most common usecase.

Test: TreeHugger
Flag: EXEMPT PURE_REFACTOR
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I2de4d067b2f20680539cbddb31555864bcf957b1
This commit is contained in:
Maciej Żenczykowski 2025-09-12 08:19:40 -07:00
commit ee24054e2b
13 changed files with 66 additions and 66 deletions

View file

@ -46,7 +46,7 @@ class BpfRingbufTest : public ::testing::Test {
mRingbufPath("/sys/fs/bpf/map_bpfRingbufProg_test_ringbuf") {}
void SetUp() {
if (!android::bpf::isAtLeastKernelVersion(5, 8, 0)) {
if (!android::bpf::isAtLeastKernelVersion(5, 8)) {
GTEST_SKIP() << "BPF ring buffers not supported below 5.8";
}

View file

@ -107,7 +107,7 @@ class BpfMapRO {
protected:
void abortOnMismatch(bool writable) const {
if (!mMapFd.ok()) Abort(errno, "mMapFd %d is not valid", mMapFd.get());
if (isAtLeastKernelVersion(4, 14, 0)) {
if (isAtLeastKernelVersion(4, 14)) {
int flags = bpfGetFdMapFlags(mMapFd);
if (flags < 0) Abort(errno, "bpfGetFdMapFlags fail: flags=%d", flags);
if (flags & BPF_F_WRONLY) Abort(0, "map is write-only (flags=0x%X)", flags);
@ -228,7 +228,7 @@ class BpfMapRO {
// Does not allow early termination (via f erroring out) - may be implemented with bulk api
Result<void> forAll(const function<void(const Key &)> &f) const {
// No kernel bpfmap bulk lookup api which doesn't return both keys & values.
if (isAtLeastKernelVersion(5, 10, 0)) return doBulkLookupAndMaybeDelete(/*delete*/ false,
if (isAtLeastKernelVersion(5, 10)) return doBulkLookupAndMaybeDelete(/*delete*/ false,
[&f](const Key &key, const Value &) {
f(key);
}
@ -258,7 +258,7 @@ class BpfMapRO {
// Does not allow early termination (via f erroring out) - maybe implemented with bulk api
Result<void> forAll(const function<void(const Key &, const Value &)> &f) const {
if (isAtLeastKernelVersion(5, 10, 0)) return doBulkLookupAndMaybeDelete(/*delete*/ false, f);
if (isAtLeastKernelVersion(5, 10)) return doBulkLookupAndMaybeDelete(/*delete*/ false, f);
return iterate(
[&f](const Key &key, const Value &value) -> Result<void> {
f(key, value);
@ -379,7 +379,7 @@ class BpfMap : public BpfMapRW<Key, Value> {
}
Result<Value> readAndDeleteValue(const Key& key) {
if (isAtLeastKernelVersion(5, 4, 0)) {
if (isAtLeastKernelVersion(5, 4)) {
Value value;
if (!findAndDeleteMapEntry(mMapFd, &key, &value)) return value;
if (errno == ENOENT) return ERROR_FROM_ERRNO("read&DeleteVal");
@ -423,7 +423,7 @@ class BpfMap : public BpfMapRW<Key, Value> {
// Does not allow early termination (via f erroring out) - maybe implemented with bulk api
Result<void> consume(const std::function<void(const Key&, const Value&)>& f) {
if (isAtLeastKernelVersion(5, 10, 0)) return doBulkLookupAndMaybeDelete(/*delete*/true, f);
if (isAtLeastKernelVersion(5, 10)) return doBulkLookupAndMaybeDelete(/*delete*/true, f);
Result<Key> curKey = getFirstKey();
while (curKey.ok()) {
const Result<Key> &nextKey = getNextKey(curKey.value());

View file

@ -81,14 +81,14 @@ static constexpr unsigned minSupportedKernelVer =
#error "__ANDROID_API__ is pre-R"
#endif
static inline bool isAtLeastKernelVersion(unsigned major, unsigned minor, unsigned sub) {
static inline bool isAtLeastKernelVersion(unsigned major, unsigned minor, unsigned sub = 0) {
unsigned k = KVER(major, minor, sub);
if (k <= minSupportedKernelVer) return true;
return kernelVer >= k;
}
static inline bool isKernelVersion(unsigned major, unsigned minor) {
return isAtLeastKernelVersion(major, minor, 0) && !isAtLeastKernelVersion(major, minor + 1, 0);
return isAtLeastKernelVersion(major, minor) && !isAtLeastKernelVersion(major, minor + 1);
}
static inline bool __unused isLtsKernel() {

View file

@ -452,7 +452,7 @@ int readCodeSections(ElfObject& elfObj, vector<codeSection>& cs) {
}
static unsigned int sanitizeMapFlags(unsigned int map_flags) {
if (!isAtLeastKernelVersion(5, 10, 0)) map_flags &= ~BPF_F_MMAPABLE;
if (!isAtLeastKernelVersion(5, 10)) map_flags &= ~BPF_F_MMAPABLE;
return map_flags;
}
@ -464,7 +464,7 @@ static bool mapMatchesExpectations(const unique_fd& fd,
// This is because the primary failure mode we're trying to detect here
// is either a source code misconfiguration (which is likely kernel independent)
// or a newly introduced kernel feature/bug (which is unlikely to get backported to 4.9).
if (!isAtLeastKernelVersion(4, 14, 0)) return true;
if (!isAtLeastKernelVersion(4, 14)) return true;
// Assuming fd is a valid Bpf Map file descriptor then
// all the following should always succeed on a 4.14+ kernel.
@ -642,7 +642,7 @@ static int loadBtf(ElfObject &elfObj, struct btf *btf) {
if (ret) return ret;
}
if (!isAtLeastKernelVersion(5, 10, 0)) {
if (!isAtLeastKernelVersion(5, 10)) {
// Likely unnecessary on kernel 5.4 but untested.
sanitizeBtf(btf);
}
@ -778,7 +778,7 @@ static int pinMap(const borrowed_fd& fd, const struct bpf_map_def& mapDef) {
return -err;
}
if (isAtLeastKernelVersion(4, 14, 0)) {
if (isAtLeastKernelVersion(4, 14)) {
int mapId = bpfGetFdMapId(fd);
if (mapId == -1) {
const int err = errno;
@ -791,7 +791,7 @@ static int pinMap(const borrowed_fd& fd, const struct bpf_map_def& mapDef) {
}
static bool isMapTypeSupported(enum bpf_map_type type) {
if (type == BPF_MAP_TYPE_LPM_TRIE && !isAtLeastKernelVersion(4, 14, 0)) {
if (type == BPF_MAP_TYPE_LPM_TRIE && !isAtLeastKernelVersion(4, 14)) {
// On Linux Kernels older than 4.14 this map type doesn't exist - autoskip.
return false;
}
@ -799,7 +799,7 @@ static bool isMapTypeSupported(enum bpf_map_type type) {
}
static enum bpf_map_type sanitizeMapType(enum bpf_map_type type) {
if (type == BPF_MAP_TYPE_DEVMAP && !isAtLeastKernelVersion(4, 14, 0)) {
if (type == BPF_MAP_TYPE_DEVMAP && !isAtLeastKernelVersion(4, 14)) {
// 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()
@ -809,7 +809,7 @@ static enum bpf_map_type sanitizeMapType(enum bpf_map_type type) {
// Hence using an ARRAY instead of a DEVMAP simply makes life easier for userspace.
return BPF_MAP_TYPE_ARRAY;
}
if (type == BPF_MAP_TYPE_DEVMAP_HASH && !isAtLeastKernelVersion(5, 4, 0)) {
if (type == BPF_MAP_TYPE_DEVMAP_HASH && !isAtLeastKernelVersion(5, 4)) {
// 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.
@ -829,7 +829,7 @@ static int createMaps(ElfObject& elfObj, vector<struct bpf_map_def>& md, vector<
vector<char> btfData;
struct btf *btf = NULL;
auto btfGuard = base::make_scope_guard([&btf] { if (btf) btf__free(btf); });
if (isAtLeastKernelVersion(4, 19, 0)) {
if (isAtLeastKernelVersion(4, 19)) {
// On Linux Kernels older than 4.18 BPF_BTF_LOAD command doesn't exist.
ret = elfObj.readSectionByName(".BTF", btfData);
if (ret) {
@ -906,7 +906,7 @@ static int createMaps(ElfObject& elfObj, vector<struct bpf_map_def>& md, vector<
.max_entries = max_entries,
.map_flags = sanitizeMapFlags(md[i].map_flags),
};
if (isAtLeastKernelVersion(4, 15, 0))
if (isAtLeastKernelVersion(4, 15))
strlcpy(req.map_name, md[i].name(), sizeof(req.map_name));
bool haveBtf = btf && isBtfSupported(type);
@ -1038,7 +1038,7 @@ static int pinProg(const borrowed_fd& fd, const struct bpf_prog_def& progDef) {
static int validateProg(const borrowed_fd& fd, const char* const progPinLoc,
const unsigned int bpfloader_ver) {
if (!isAtLeastKernelVersion(4, 14, 0)) {
if (!isAtLeastKernelVersion(4, 14)) {
return 0;
}
int progId = bpfGetFdProgId(fd);
@ -1110,7 +1110,7 @@ static int loadCodeSections(ElfObject& elfObj, vector<codeSection>& cs, const st
.log_buf = ptr_to_u64(log_buf),
.expected_attach_type = cs[i].prog_def->attach_type,
};
if (isAtLeastKernelVersion(4, 15, 0))
if (isAtLeastKernelVersion(4, 15))
strlcpy(req.prog_name, cs[i].prog_def->name(), sizeof(req.prog_name));
fd.reset(bpf(BPF_PROG_LOAD, req));
@ -1317,7 +1317,7 @@ static int loadProgByLibbpf(const char* const elfPath, const unsigned int bpfloa
ret = bpf_object__load(obj);
if (ret) return ret;
// On Linux Kernels older than 4.18 BPF_BTF_LOAD command doesn't exist.
if (isAtLeastKernelVersion(4, 19, 0) && bpf_object__btf_fd(obj) < 0) return -1;
if (isAtLeastKernelVersion(4, 19) && bpf_object__btf_fd(obj) < 0) return -1;
ret = pinMaps(obj, md);
if (ret) return ret;
@ -1630,41 +1630,41 @@ static int doLoad(char** argv, char * const envp[]) {
// both S and T require kernel 4.9 (and eBpf support)
// (this also guarantees 'kernelVer' isn't an invalid uninitialized 0)
if (!isAtLeastKernelVersion(4, 9, 0)) {
if (!isAtLeastKernelVersion(4, 9)) {
ALOGE("Android S & T require kernel 4.9.");
return 3;
}
// U bumps the kernel requirement up to 4.14
if (isAtLeastU && !isAtLeastKernelVersion(4, 14, 0)) {
if (isAtLeastU && !isAtLeastKernelVersion(4, 14)) {
ALOGE("Android U requires kernel 4.14.");
return 4;
}
// V bumps the kernel requirement up to 4.19
// see also: //system/netd/tests/kernel_test.cpp TestKernel419
if (isAtLeastV && !isAtLeastKernelVersion(4, 19, 0)) {
if (isAtLeastV && !isAtLeastKernelVersion(4, 19)) {
ALOGE("Android V requires kernel 4.19.");
return 5;
}
// 25Q2 bumps the kernel requirement up to 5.4
// see also: //system/netd/tests/kernel_test.cpp TestKernel54
if (isAtLeast25Q2 && !isAtLeastKernelVersion(5, 4, 0)) {
if (isAtLeast25Q2 && !isAtLeastKernelVersion(5, 4)) {
ALOGE("Android 25Q2 requires kernel 5.4.");
return 6;
}
// 25Q4 bumps the kernel requirement up to 5.10
// see also: //system/netd/tests/kernel_test.cpp TestKernel510
if (isAtLeast25Q4 && !isAtLeastKernelVersion(5, 10, 0)) {
if (isAtLeast25Q4 && !isAtLeastKernelVersion(5, 10)) {
ALOGE("Android 25Q4 requires kernel 5.10.");
return 7;
}
// Technically already required by U, but only enforce on V+
// see also: //system/netd/tests/kernel_test.cpp TestKernel64Bit
if (isAtLeastV && isKernel32Bit() && isAtLeastKernelVersion(5, 16, 0)) {
if (isAtLeastV && isKernel32Bit() && isAtLeastKernelVersion(5, 16)) {
ALOGE("Android V+ platform with 32 bit kernel version >= 5.16.0 is unsupported");
if (!isTV()) return 8;
}
@ -1675,7 +1675,7 @@ static int doLoad(char** argv, char * const envp[]) {
}
// 6.6 is highest version supported by Android V, so this is effectively W+ (sdk=36+)
if (isKernel32Bit() && isAtLeastKernelVersion(6, 7, 0)) {
if (isKernel32Bit() && isAtLeastKernelVersion(6, 7)) {
ALOGE("Android platform with 32 bit kernel version >= 6.7.0 is unsupported");
return 10;
}
@ -1740,7 +1740,7 @@ static int doLoad(char** argv, char * const envp[]) {
* Note, however, that TV and Wear devices will continue to support 32-bit userspace
* on ARM64.
*/
if (isUserspace32bit() && isAtLeastKernelVersion(6, 2, 0)) {
if (isUserspace32bit() && isAtLeastKernelVersion(6, 2)) {
// Stuff won't work reliably, but...
if (isArm() && (isTV() || isWear())) {
// exempt Arm TV or Wear devices (arm32 ABI is far less problematic than x86-32)
@ -1765,7 +1765,7 @@ static int doLoad(char** argv, char * const envp[]) {
// Since officially Android only supports LTS, 6.13+ really means 6.18+,
// and won't be supported before 2026, most likely Android 17 / 26Q2.
// 6.13+ (implying 26Q2+) requires 64-bit userspace.
if (isUserspace32bit() && isAtLeastKernelVersion(6, 13, 0)) {
if (isUserspace32bit() && isAtLeastKernelVersion(6, 13)) {
// due to previous check only reachable on Arm && (<=T kernel uprev || TV || Wear)
ALOGE("64-bit userspace required on 6.13+ kernels.");
return 14;
@ -1804,7 +1804,7 @@ static int doLoad(char** argv, char * const envp[]) {
// (this writeFile is known to fail on at least 4.19, but always defaults to 0 on
// pre-5.13, on 5.13+ it depends on CONFIG_BPF_UNPRIV_DEFAULT_OFF)
if (!writeFile("/proc/sys/kernel/unprivileged_bpf_disabled", "0\n") &&
isAtLeastKernelVersion(5, 13, 0)) return 23;
isAtLeastKernelVersion(5, 13)) return 23;
}
if (isAtLeastU) {
@ -1858,7 +1858,7 @@ static int doLoad(char** argv, char * const envp[]) {
ALOGE("bpfGetNextMapId(zero) returned %u (errno %d)", mapId, errno);
return 33;
}
} else if (isAtLeastKernelVersion(4, 14, 0)) { // implies S through U QPR2
} else if (isAtLeastKernelVersion(4, 14)) { // implies S through U QPR2
// bpfGetNext{Prog,Map}Id require 4.14+
// furthermore since we're not running as root, we're not the initial
// platform bpfloader, so there may already be some maps & programs.
@ -1883,7 +1883,7 @@ static int doLoad(char** argv, char * const envp[]) {
// and thus it should return 0 with errno == ENOENT.
ALOGE("bpfGetNextMapId(final %d) returned %d errno %d", mapId, next, errno);
if (next || errno != ENOENT) return 35;
if (isAtLeastT || isAtLeastKernelVersion(4, 20, 0)) return 36;
if (isAtLeastT || isAtLeastKernelVersion(4, 20)) return 36;
// implies Android S with 4.14 or 4.19 kernel
ALOGW("Detected kernel with invalid BPF UAPI - disabling mainline use of eBPF.");
// leave a flag that we're 'done'

View file

@ -82,12 +82,12 @@ static Status initPrograms(const char* cg2_path) {
if (!isAtLeastT) return Status("S- platform is unsupported");
// S requires eBPF support which was only added in 4.9, so this should be satisfied.
if (!isAtLeastKernelVersion(4, 9, 0)) {
if (!isAtLeastKernelVersion(4, 9)) {
return Status("kernel version < 4.9.0 is unsupported");
}
// U bumps the kernel requirement up to 4.14
if (isAtLeastU && !isAtLeastKernelVersion(4, 14, 0)) {
if (isAtLeastU && !isAtLeastKernelVersion(4, 14)) {
return Status("U+ platform with kernel version < 4.14.0 is unsupported");
}
@ -97,12 +97,12 @@ static Status initPrograms(const char* cg2_path) {
}
// V bumps the kernel requirement up to 4.19
if (isAtLeastV && !isAtLeastKernelVersion(4, 19, 0)) {
if (isAtLeastV && !isAtLeastKernelVersion(4, 19)) {
return Status("V+ platform with kernel version < 4.19.0 is unsupported");
}
// 25Q2 bumps the kernel requirement up to 5.4
if (isAtLeast25Q2 && !isAtLeastKernelVersion(5, 4, 0)) {
if (isAtLeast25Q2 && !isAtLeastKernelVersion(5, 4)) {
return Status("25Q2+ platform with kernel version < 5.4.0 is unsupported");
}
@ -121,12 +121,12 @@ static Status initPrograms(const char* cg2_path) {
// cgroup if the program is pinned properly.
// TODO: delete the if statement once all devices should support cgroup
// socket filter (ie. the minimum kernel version required is 4.14).
if (isAtLeastKernelVersion(4, 14, 0)) {
if (isAtLeastKernelVersion(4, 14)) {
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_INET_CREATE_PROG_PATH,
cg_fd, BPF_CGROUP_INET_SOCK_CREATE));
}
if (isAtLeastKernelVersion(5, 10, 0)) {
if (isAtLeastKernelVersion(5, 10)) {
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_INET_RELEASE_PROG_PATH,
cg_fd, BPF_CGROUP_INET_SOCK_RELEASE));
}
@ -134,7 +134,7 @@ static Status initPrograms(const char* cg2_path) {
if (isAtLeastV) {
// V requires 4.19+, so technically this 2nd 'if' is not required, but it
// doesn't hurt us to try to support AOSP forks that try to support older kernels.
if (isAtLeastKernelVersion(4, 19, 0)) {
if (isAtLeastKernelVersion(4, 19)) {
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_CONNECT4_PROG_PATH,
cg_fd, BPF_CGROUP_INET4_CONNECT));
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_CONNECT6_PROG_PATH,
@ -149,7 +149,7 @@ static Status initPrograms(const char* cg2_path) {
cg_fd, BPF_CGROUP_UDP6_SENDMSG));
}
if (isAtLeastKernelVersion(5, 4, 0)) {
if (isAtLeastKernelVersion(5, 4)) {
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_GETSOCKOPT_PROG_PATH,
cg_fd, BPF_CGROUP_GETSOCKOPT));
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_SETSOCKOPT_PROG_PATH,
@ -157,7 +157,7 @@ static Status initPrograms(const char* cg2_path) {
}
}
if (isAtLeastKernelVersion(4, 19, 0)) {
if (isAtLeastKernelVersion(4, 19)) {
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_BIND4_PROG_PATH,
cg_fd, BPF_CGROUP_INET4_BIND));
RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_BIND6_PROG_PATH,
@ -172,14 +172,14 @@ static Status initPrograms(const char* cg2_path) {
if (queryProgram(cg_fd, BPF_CGROUP_INET6_BIND) <= 0) abort();
}
if (isAtLeastKernelVersion(5, 10, 0)) {
if (isAtLeastKernelVersion(5, 10)) {
if (queryProgram(cg_fd, BPF_CGROUP_INET_SOCK_RELEASE) <= 0) abort();
}
if (isAtLeastV) {
// V requires 4.19+, so technically this 2nd 'if' is not required, but it
// doesn't hurt us to try to support AOSP forks that try to support older kernels.
if (isAtLeastKernelVersion(4, 19, 0)) {
if (isAtLeastKernelVersion(4, 19)) {
if (queryProgram(cg_fd, BPF_CGROUP_INET4_CONNECT) <= 0) abort();
if (queryProgram(cg_fd, BPF_CGROUP_INET6_CONNECT) <= 0) abort();
if (queryProgram(cg_fd, BPF_CGROUP_UDP4_RECVMSG) <= 0) abort();
@ -188,7 +188,7 @@ static Status initPrograms(const char* cg2_path) {
if (queryProgram(cg_fd, BPF_CGROUP_UDP6_SENDMSG) <= 0) abort();
}
if (isAtLeastKernelVersion(5, 4, 0)) {
if (isAtLeastKernelVersion(5, 4)) {
if (queryProgram(cg_fd, BPF_CGROUP_GETSOCKOPT) <= 0) abort();
if (queryProgram(cg_fd, BPF_CGROUP_SETSOCKOPT) <= 0) abort();
}
@ -319,7 +319,7 @@ static void mapLockTest(void) {
Status BpfHandler::initMaps() {
// bpfLock() requires bpfGetFdMapId which is only available on 4.14+ kernels.
if (isAtLeastKernelVersion(4, 14, 0)) {
if (isAtLeastKernelVersion(4, 14)) {
mapLockTest();
}
@ -378,7 +378,7 @@ int BpfHandler::tagSocket(int sockFd, uint32_t tag, uid_t chargeUid, uid_t realU
// On 5.10+ the BPF_CGROUP_INET_SOCK_RELEASE hook takes care of cookie tag map cleanup
// during socket destruction. As such the socket destroy listener is superfluous.
if (!isAtLeastKernelVersion(5, 10, 0)) {
if (!isAtLeastKernelVersion(5, 10)) {
int socketProto;
socklen_t protoLen = sizeof(socketProto);
if (getsockopt(sockFd, SOL_SOCKET, SO_PROTOCOL, &socketProto, &protoLen)) {

View file

@ -191,7 +191,7 @@ TEST_F(BpfHandlerTest, TestTagSocketWithUnsupportedProtocol) {
int rawSocket = socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
EXPECT_LE(0, rawSocket);
EXPECT_NE(NONEXISTENT_COOKIE, getSocketCookie(rawSocket));
if (isAtLeastKernelVersion(5, 10, 0)) {
if (isAtLeastKernelVersion(5, 10)) {
EXPECT_EQ(0, mBh.tagSocket(rawSocket, TEST_TAG, TEST_UID, TEST_UID));
} else {
EXPECT_EQ(-EPROTONOSUPPORT, mBh.tagSocket(rawSocket, TEST_TAG, TEST_UID, TEST_UID));

View file

@ -203,7 +203,7 @@ TEST_F(BpfExistenceTest, TestPrograms) {
ASSERT_TRUE(isAtLeastS); // Q & R are no longer supported by mainline
// S requires Linux Kernel 4.9+ and thus requires eBPF support.
if (isAtLeastS) ASSERT_TRUE(isAtLeastKernelVersion(4, 9, 0));
if (isAtLeastS) ASSERT_TRUE(isAtLeastKernelVersion(4, 9));
// on S without a new enough DnsResolver apex, NetBpfLoad doesn't get triggered,
// and thus no mainline programs get loaded.
@ -215,28 +215,28 @@ TEST_F(BpfExistenceTest, TestPrograms) {
// T still only requires Linux Kernel 4.9+.
DO_EXPECT(isAtLeastT, MAINLINE_FOR_T_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(4, 14, 0), MAINLINE_FOR_T_4_14_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(4, 19, 0), MAINLINE_FOR_T_4_19_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_T_5_10_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(5, 15, 0), MAINLINE_FOR_T_5_15_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(4, 14), MAINLINE_FOR_T_4_14_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(4, 19), MAINLINE_FOR_T_4_19_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(5, 10), MAINLINE_FOR_T_5_10_PLUS);
DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(5, 15), MAINLINE_FOR_T_5_15_PLUS);
// U requires Linux Kernel 4.14+, but nothing (as yet) added or removed in U.
if (isAtLeastU) ASSERT_TRUE(isAtLeastKernelVersion(4, 14, 0));
if (isAtLeastU) ASSERT_TRUE(isAtLeastKernelVersion(4, 14));
DO_EXPECT(isAtLeastU, MAINLINE_FOR_U_PLUS);
DO_EXPECT(isAtLeastU && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_U_5_10_PLUS);
DO_EXPECT(isAtLeastU && isAtLeastKernelVersion(5, 10), MAINLINE_FOR_U_5_10_PLUS);
// V requires Linux Kernel 4.19+, but nothing (as yet) added or removed in V.
if (isAtLeastV) ASSERT_TRUE(isAtLeastKernelVersion(4, 19, 0));
if (isAtLeastV) ASSERT_TRUE(isAtLeastKernelVersion(4, 19));
DO_EXPECT(isAtLeastV, MAINLINE_FOR_V_PLUS);
DO_EXPECT(isAtLeastV && isAtLeastKernelVersion(5, 4, 0), MAINLINE_FOR_V_5_4_PLUS);
DO_EXPECT(isAtLeastV && isAtLeastKernelVersion(5, 4), MAINLINE_FOR_V_5_4_PLUS);
if (isAtLeast25Q2) ASSERT_TRUE(isAtLeastKernelVersion(5, 4, 0));
if (isAtLeast25Q2) ASSERT_TRUE(isAtLeastKernelVersion(5, 4));
DO_EXPECT(isAtLeast25Q2, MAINLINE_FOR_25Q2_PLUS);
if (isAtLeast25Q4) ASSERT_TRUE(isAtLeastKernelVersion(5, 10, 0));
if (isAtLeast25Q4) ASSERT_TRUE(isAtLeastKernelVersion(5, 10));
DO_EXPECT(isAtLeast26Q2, MAINLINE_FOR_26Q2_PLUS);
DO_EXPECT(isAtLeast26Q2 && isAtLeastKernelVersion(6, 1, 0), MAINLINE_FOR_26Q2_6_1_PLUS);
DO_EXPECT(isAtLeast26Q2 && isAtLeastKernelVersion(6, 1), MAINLINE_FOR_26Q2_6_1_PLUS);
for (const auto& file : mustExist) {
EXPECT_EQ(0, access(file.c_str(), R_OK)) << file << " does not exist";

View file

@ -118,7 +118,7 @@ int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats,
// specific iface
int64_t unknownIfaceBytesTotal = 0;
if (isAtLeastKernelVersion(5, 10, 0)) {
if (isAtLeastKernelVersion(5, 10)) {
// On 5.10+ bulk lookup api returns values for free, so just use forAll(f(K,V))
auto res = ifaceStatsMap.forAll(
[iface, stats, ifindex2name, &unknownIfaceBytesTotal, &ifaceStatsMap](const uint32_t& key, const StatsValue& value) {

View file

@ -61,7 +61,7 @@ static jint com_android_net_module_util_BpfMap_nativeBpfFdGet(JNIEnv *env, jclas
return -1;
}
if (bpf::isAtLeastKernelVersion(4, 14, 0)) {
if (bpf::isAtLeastKernelVersion(4, 14)) {
// These likely fail with -1 and set errno to EINVAL on <4.14
if (bpf::bpfGetFdKeySize(fd) != keySize) {
jniThrowErrnoException(env, "nativeBpfFdGet KeySize", EBADFD);

View file

@ -104,7 +104,7 @@ static int createTunTapImpl(JNIEnv *env, bool isTun, bool hasCarrier,
if (!hasCarrier) {
// Using IFF_NO_CARRIER is supported starting in kernel version >= 6.0
// Up until then, unsupported flags are ignored.
if (!bpf::isAtLeastKernelVersion(6, 0, 0)) {
if (!bpf::isAtLeastKernelVersion(6, 0)) {
throwException(env, EOPNOTSUPP, "IFF_NO_CARRIER not supported",
ifr.ifr_name);
return -1;

View file

@ -497,7 +497,7 @@ int isEthernet(const char *iface, bool &isEthernet) {
// shipped with Android S, so (for safety) let's limit ourselves to
// >5.10, ie. 5.11+ as a guarantee we're on Android T+ and thus no
// longer need this non-upstream compatibility logic
static bool is_pre_5_11_kernel = !bpf::isAtLeastKernelVersion(5, 11, 0);
static bool is_pre_5_11_kernel = !bpf::isAtLeastKernelVersion(5, 11);
if (is_pre_5_11_kernel)
return false;
}

View file

@ -82,7 +82,7 @@ TEST(LibTcUtilsTest, AddAndDeleteBpfFilter) {
// TODO: this should likely be in the tethering module, where using netd.h would be ok
static constexpr char bpfProgPath[] =
"/sys/fs/bpf/tethering/prog_offload_schedcls_tether_downstream6_ether";
const int errNOENT = bpf::isAtLeastKernelVersion(4, 19, 0) ? ENOENT : EINVAL;
const int errNOENT = bpf::isAtLeastKernelVersion(4, 19) ? ENOENT : EINVAL;
// static test values
static constexpr bool ingress = true;
@ -118,7 +118,7 @@ TEST(LibTcUtilsTest, AddAndDeleteIngressPoliceFilter) {
ASSERT_LE(3, fd);
close(fd);
const int errNOENT = bpf::isAtLeastKernelVersion(4, 19, 0) ? ENOENT : EINVAL;
const int errNOENT = bpf::isAtLeastKernelVersion(4, 19) ? ENOENT : EINVAL;
// static test values
static constexpr unsigned rateInBytesPerSec =

View file

@ -39,7 +39,7 @@ class ConnectivityNativeBinderTest : public ::testing::Test {
GTEST_SKIP() << "Should be at least U device.";
// Skip test case if not on 5.4 kernel which is required by bpf prog.
if (!android::bpf::isAtLeastKernelVersion(5, 4, 0))
if (!android::bpf::isAtLeastKernelVersion(5, 4))
GTEST_SKIP() << "Kernel should be at least 5.4.";
// If there are already ports being blocked on device store the