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:
parent
8d04b03a69
commit
ee24054e2b
1 changed files with 66 additions and 66 deletions
|
|
@ -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'
|
||||
|
|
|
|||
Loading…
Reference in a new issue