Merge "BpfUtils: fix sdk level detection logic for 25Q3+" into main

This commit is contained in:
Maciej Żenczykowski 2025-09-12 17:04:28 -07:00 • committed by Android (Google) Code Review
commit c231a533ba
3 changed files with 49 additions and 30 deletions

View file

@ -24,6 +24,7 @@
#include <string.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/system_properties.h>
#include <sys/utsname.h>
#include <android-base/properties.h>
@ -34,19 +35,46 @@
namespace android {
namespace bpf {
const bool unreleased = (base::GetProperty("ro.build.version.codename", "REL") != "REL");
const int api_level = unreleased ? 10000 : android_get_device_api_level();
const bool isAtLeastR = (api_level >= 30);
const bool isAtLeastS = (api_level >= 31);
// Sv2 is 32
const bool isAtLeastT = (api_level >= 33);
const bool isAtLeastU = (api_level >= 34);
const bool isAtLeastV = (api_level >= 35);
const bool isAtLeast25Q2 = (api_level >= 36); // 36.0
const bool isAtLeast25Q3 = (api_level > 36); // 36.0+ (TODO: fix this!)
const bool isAtLeast25Q4 = false; // 36.1
const bool isAtLeast26Q1 = false; // 36.1+
const bool isAtLeast26Q2 = false; // 37.0
static inline int get_api_level_full() {
// This fetches/parses 'ro.build.version.sdk' system property.
const int api_level = android_get_device_api_level();
// Before Baklava/25Q2 there is no 'sdk_full'
if (api_level < 36) return api_level * 100; // 3x -> 3x00
// Fetch and parse the 'sdk_full' system property.
char value[92] = {};
if (__system_property_get("ro.build.version.sdk_full", value) < 1) abort();
int major, minor;
if (sscanf(value, "%d.%d", &major, &minor) != 2) abort();
if (major < 36 || minor < 0 || minor > 9) abort();
const int api_level_full = major * 100 + minor * 10; // 3x.y -> 3xy0
// Fetch and parse our platform provided .rc file - this provides quarterly info as well
FILE * f = fopen("/system/etc/init/netbpfload.rc", "re");
if (!f) abort();
int y, q, a, b, c;
if (fscanf(f, "# %d %d %d %d %d #", &y, &q, &a, &b, &c) != 5) abort();
if (a < 36 || b < 0 || b > 9 || c < 0 || c > 4) abort();
fclose(f);
const int api_level_fuller = a * 100 + b * 10 + c * 2; // 3x.y.z -> 3xy[2z]
const bool unreleased = (base::GetProperty("ro.build.version.codename", "REL") != "REL");
return std::max(api_level_fuller, api_level_full) + unreleased;
}
const int api_level_full = get_api_level_full();
const bool isAtLeastR = (api_level_full >= 3000); // 30
const bool isAtLeastS = (api_level_full >= 3100); // 31
const bool isAtLeastSv2 = (api_level_full >= 3200); // 32
const bool isAtLeastT = (api_level_full >= 3300); // 33
const bool isAtLeastU = (api_level_full >= 3400); // 34
const bool isAtLeastV = (api_level_full >= 3500); // 35
const bool isAtLeast25Q2 = (api_level_full >= 3600); // 36.0
const bool isAtLeast25Q3 = (api_level_full >= 3602); // 36.0+
const bool isAtLeast25Q4 = (api_level_full >= 3610); // 36.1
const bool isAtLeast26Q1 = (api_level_full >= 3612); // 36.1+
const bool isAtLeast26Q2 = (api_level_full >= 3700); // 37.0
// See kernel's net/core/sock_diag.c __sock_gen_cookie()
// the implementation of which guarantees 0 will never be returned,

View file

@ -1394,7 +1394,7 @@ static bool loadObject(const unsigned int bpfloader_ver,
#define BPFROOT APEXROOT "/etc/bpf/mainline/"
static bool loadAllObjects(const unsigned int bpfloader_ver) {
bool libbpf = isAtLeast25Q3 || useLibBpf;
bool libbpf = isAtLeast26Q1 || useLibBpf;
if (!loadObject(bpfloader_ver, BPFROOT "offload.o")) return false;
if (!loadObject(bpfloader_ver, BPFROOT "test.o", libbpf)) return false;
if (isAtLeastT) {
@ -1586,7 +1586,7 @@ static int doLoad(char** argv, char * const envp[]) {
const bool runningAsRoot = !getuid(); // true iff U QPR3 or V+
const int first_api_level = GetIntProperty("ro.board.first_api_level", api_level);
const int first_api_level = GetIntProperty("ro.board.first_api_level", api_level_full / 100);
// last in U QPR2 beta1
const bool has_platform_bpfloader_rc = exists("/system/etc/init/bpfloader.rc");
@ -1594,19 +1594,10 @@ static int doLoad(char** argv, char * const envp[]) {
const bool has_platform_netbpfload_rc = exists("/system/etc/init/netbpfload.rc");
// Version of Network BpfLoader depends on the Android OS version
unsigned int bpfloader_ver = BPFLOADER_MAINLINE_S_VERSION;
if (isAtLeastT) bpfloader_ver = BPFLOADER_MAINLINE_T_VERSION;
if (isAtLeastU) bpfloader_ver = BPFLOADER_MAINLINE_U_VERSION;
if (isAtLeastV) bpfloader_ver = BPFLOADER_MAINLINE_V_VERSION;
if (isAtLeast25Q2) bpfloader_ver = BPFLOADER_MAINLINE_25Q2_VERSION;
if (isAtLeast25Q3) bpfloader_ver = BPFLOADER_MAINLINE_25Q3_VERSION;
if (isAtLeast25Q4) bpfloader_ver = BPFLOADER_MAINLINE_25Q4_VERSION;
if (isAtLeast26Q1) bpfloader_ver = BPFLOADER_MAINLINE_26Q1_VERSION;
if (isAtLeast26Q2) bpfloader_ver = BPFLOADER_MAINLINE_26Q2_VERSION;
unsigned int bpfloader_ver = api_level_full;
ALOGI("NetBpfLoad v0.%u (%s) api:%d/%d kver:%07x (%s) libbpf: v%u.%u "
"uid:%d rc:%d%d",
bpfloader_ver, argv[0], android_get_device_api_level(), api_level,
ALOGI("NetBpfLoad v%u (%s) api:%d kver:%07x (%s) libbpf: v%u.%u uid:%d rc:%d%d",
bpfloader_ver, argv[0], android_get_device_api_level(),
kernelVer, describeArch(), libbpf_major_version(),
libbpf_minor_version(), getuid(), has_platform_bpfloader_rc,
has_platform_netbpfload_rc);

View file

@ -210,7 +210,7 @@ _Static_assert(_Alignof(struct bpf_prog_def) == 4, "_Alignof struct bpf_prog_def
#define BPFLOADER_MAINLINE_U_VERSION 3400u // Android U (34)
#define BPFLOADER_MAINLINE_V_VERSION 3500u // Android V (35)
#define BPFLOADER_MAINLINE_25Q2_VERSION 3600u // Android 25Q2 (36.0)
#define BPFLOADER_MAINLINE_25Q3_VERSION 3601u // Android 25Q3 (36.0+)
#define BPFLOADER_MAINLINE_25Q3_VERSION 3602u // Android 25Q3 (36.0+)
#define BPFLOADER_MAINLINE_25Q4_VERSION 3610u // Android 25Q4 (36.1)
#define BPFLOADER_MAINLINE_26Q1_VERSION 3611u // Android 26Q1 (36.1+)
#define BPFLOADER_MAINLINE_26Q1_VERSION 3612u // Android 26Q1 (36.1+)
#define BPFLOADER_MAINLINE_26Q2_VERSION 3700u // Android 26Q2 (37.0)