Merge changes I17432e14,Iaeb8db2c,Id381a721 into main

* changes:
  NetBpfLoad: remove spurious explicit pin location from pinProg()
  bpf: switch progs from using 'pin_prefix' to 'pin_location'
  bpf/progs: automate function name determination from prog section name
This commit is contained in:
Maciej Żenczykowski 2025-08-05 09:41:19 -07:00 • committed by Android (Google) Code Review
commit 911747b01f
7 changed files with 194 additions and 233 deletions

View file

@ -964,8 +964,7 @@ static void applyMapRelo(ElfObject& elfObj, const vector<struct bpf_map_def>& md
}
}
static int pinProg(const borrowed_fd& fd, const struct bpf_prog_def& progDef,
const string& progPinLoc) {
static int pinProg(const borrowed_fd& fd, const struct bpf_prog_def& progDef) {
int ret;
if (progDef.create_location[0]) {
ret = bpfFdPin(fd, progDef.create_location);
@ -975,37 +974,37 @@ static int pinProg(const borrowed_fd& fd, const struct bpf_prog_def& progDef,
return -err;
}
ret = renameat2(AT_FDCWD, progDef.create_location,
AT_FDCWD, progPinLoc.c_str(), RENAME_NOREPLACE);
AT_FDCWD, progDef.pin_location, RENAME_NOREPLACE);
if (ret) {
const int err = errno;
ALOGE("rename %s %s -> %d [%d:%s]", progDef.create_location, progPinLoc.c_str(), ret,
ALOGE("rename %s %s -> %d [%d:%s]", progDef.create_location, progDef.pin_location, ret,
err, strerror(err));
return -err;
}
} else {
ret = bpfFdPin(fd, progPinLoc.c_str());
ret = bpfFdPin(fd, progDef.pin_location);
if (ret) {
const int err = errno;
ALOGE("create %s -> %d [%d:%s]", progPinLoc.c_str(), ret, err, strerror(err));
ALOGE("create %s -> %d [%d:%s]", progDef.pin_location, ret, err, strerror(err));
return -err;
}
}
if (chmod(progPinLoc.c_str(), 0440)) {
if (chmod(progDef.pin_location, 0440)) {
const int err = errno;
ALOGE("chmod %s 0440 -> [%d:%s]", progPinLoc.c_str(), err, strerror(err));
ALOGE("chmod %s 0440 -> [%d:%s]", progDef.pin_location, err, strerror(err));
return -err;
}
if (chown(progPinLoc.c_str(), (uid_t)progDef.uid,
if (chown(progDef.pin_location, (uid_t)progDef.uid,
(gid_t)progDef.gid)) {
const int err = errno;
ALOGE("chown %s %d %d -> [%d:%s]", progPinLoc.c_str(), progDef.uid,
ALOGE("chown %s %d %d -> [%d:%s]", progDef.pin_location, progDef.uid,
progDef.gid, err, strerror(err));
return -err;
}
return 0;
}
static int validateProg(const borrowed_fd& fd, string& progPinLoc,
static int validateProg(const borrowed_fd& fd, const char* const progPinLoc,
const unsigned int bpfloader_ver) {
if (!isAtLeastKernelVersion(4, 14, 0)) {
return 0;
@ -1030,10 +1029,10 @@ static int validateProg(const borrowed_fd& fd, string& progPinLoc,
ALOGE("bpfGetFdXlatProgLen failed, ret: %d", err);
return -err;
}
ALOGI("prog %s id %d len jit:%d xlat:%d", progPinLoc.c_str(), progId, jitLen, xlatLen);
ALOGI("prog %s id %d len jit:%d xlat:%d", progPinLoc, progId, jitLen, xlatLen);
if (!jitLen && bpfloader_ver >= BPFLOADER_MAINLINE_25Q2_VERSION) {
ALOGE("Kernel eBPF JIT failure for %s", progPinLoc.c_str());
ALOGE("Kernel eBPF JIT failure for %s", progPinLoc);
return -ENOTSUP;
}
return 0;
@ -1079,10 +1078,9 @@ static int loadCodeSections(ElfObject& elfObj, vector<codeSection>& cs, const st
name = name.substr(0, name.find_last_of('$'));
bool reuse = false;
string progPinLoc = string(cs[i].prog_def->pin_prefix) + name;
if (access(progPinLoc.c_str(), F_OK) == 0) {
fd.reset(retrieveProgram(progPinLoc.c_str()));
ALOGD("New bpf prog load reusing prog %s, ret: %d (%s)", progPinLoc.c_str(), fd.get(),
if (access(cs[i].prog_def->pin_location, F_OK) == 0) {
fd.reset(retrieveProgram(cs[i].prog_def->pin_location));
ALOGD("New bpf prog load reusing prog %s, ret: %d (%s)", cs[i].prog_def->pin_location, fd.get(),
!fd.ok() ? std::strerror(errno) : "ok");
reuse = true;
} else {
@ -1137,10 +1135,10 @@ static int loadCodeSections(ElfObject& elfObj, vector<codeSection>& cs, const st
if (!fd.ok()) return fd.get();
if (!reuse) {
ret = pinProg(fd, cs[i].prog_def.value(), progPinLoc);
ret = pinProg(fd, cs[i].prog_def.value());
if (ret) return ret;
}
ret = validateProg(fd, progPinLoc, bpfloader_ver);
ret = validateProg(fd, cs[i].prog_def->pin_location, bpfloader_ver);
if (ret) return ret;
}
@ -1269,17 +1267,16 @@ static int pinProgs(const struct bpf_object * obj,
string name = cs[i].name;
name = name.substr(0, name.find_last_of('$'));
string progPinLoc = string(cs[i].prog_def->pin_prefix) + name;
if (access(progPinLoc.c_str(), F_OK) == 0) {
if (access(cs[i].prog_def->pin_location, F_OK) == 0) {
// TODO: Skip loading lower priority program
ALOGI("Higher priority program is already pinned, skip pinning %s", cs[i].name.c_str());
continue;
}
int fd = bpf_program__fd(prog);
ret = pinProg(fd, cs[i].prog_def.value(), progPinLoc);
ret = pinProg(fd, cs[i].prog_def.value());
if (ret) return ret;
ret = validateProg(fd, progPinLoc, bpfloader_ver);
ret = validateProg(fd, cs[i].prog_def->pin_location, bpfloader_ver);
if (ret) return ret;
}
return 0;

View file

@ -247,29 +247,29 @@ static inline __always_inline int nat64(struct __sk_buff* skb,
return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER(schedcls, "ingress6_clat_ether$4_14", AID_ROOT, AID_SYSTEM, sched_cls_ingress6_clat_ether_4_14, KVER_4_14)
DEFINE_BPF_PROG_KVER(schedcls, ingress6_clat_ether, 4_14, AID_ROOT, AID_SYSTEM, KVER_4_14)
(struct __sk_buff* skb) {
return nat64(skb, ETHER, KVER_4_14);
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "ingress6_clat_ether$4_9", AID_ROOT, AID_SYSTEM, sched_cls_ingress6_clat_ether_4_9, KVER_NONE, KVER_4_14)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, ingress6_clat_ether, 4_9, AID_ROOT, AID_SYSTEM, KVER_NONE, KVER_4_14)
(struct __sk_buff* skb) {
return nat64(skb, ETHER, KVER_NONE);
}
DEFINE_BPF_PROG_KVER(schedcls, "ingress6_clat_rawip$4_14", AID_ROOT, AID_SYSTEM, sched_cls_ingress6_clat_rawip_4_14, KVER_4_14)
DEFINE_BPF_PROG_KVER(schedcls, ingress6_clat_rawip, 4_14, AID_ROOT, AID_SYSTEM, KVER_4_14)
(struct __sk_buff* skb) {
return nat64(skb, RAWIP, KVER_4_14);
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "ingress6_clat_rawip$4_9", AID_ROOT, AID_SYSTEM, sched_cls_ingress6_clat_rawip_4_9, KVER_NONE, KVER_4_14)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, ingress6_clat_rawip, 4_9, AID_ROOT, AID_SYSTEM, KVER_NONE, KVER_4_14)
(struct __sk_buff* skb) {
return nat64(skb, RAWIP, KVER_NONE);
}
DEFINE_BPF_MAP_GRW(clat_egress4_map, HASH, ClatEgress4Key, ClatEgress4Value, 16, AID_SYSTEM)
DEFINE_BPF_PROG(schedcls, "egress4_clat_rawip", AID_ROOT, AID_SYSTEM, sched_cls_egress4_clat_rawip)
DEFINE_BPF_PROG(schedcls, egress4_clat_rawip, , AID_ROOT, AID_SYSTEM)
(struct __sk_buff* skb) {
// Must be meta-ethernet IPv4 frame
if (skb->protocol != htons(ETH_P_IP)) return TC_ACT_PIPE;

View file

@ -264,8 +264,7 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, const boo
return;
}
DEFINE_BPF_PROG_KVER(schedcls, "set_dscp_ether", AID_ROOT, AID_SYSTEM, schedcls_set_dscp_ether,
KVER_5_15)
DEFINE_BPF_PROG_KVER(schedcls, set_dscp_ether, , AID_ROOT, AID_SYSTEM, KVER_5_15)
(struct __sk_buff* skb) {
if (skb->pkt_type != PACKET_HOST) return TC_ACT_PIPE;

View file

@ -244,26 +244,26 @@ static long (*bpf_sk_storage_delete_unsafe) (const void* sk_storage,
type == BPF_MAP_TYPE_SK_STORAGE) ? BPF_F_NO_PREALLOC : 0) \
)
#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, usr, grp, md, \
selinux, pindir, minkver, maxkver, minloader, maxloader, mapflags) \
VALIDATE_SELINUX_CONTEXT(minloader, selinux); \
VALIDATE_PIN_DIR(minloader, pindir); \
const struct bpf_map_def SECTION(".android_maps") the_map##_def = { \
.type = BPF_MAP_TYPE_##TYPE, \
.key_size = (keysize), \
.value_size = (valuesize), \
.max_entries = ABSOLUTE(num_entries), \
.map_flags = DEFAULT_BPF_MAP_FLAGS(BPF_MAP_TYPE_##TYPE, num_entries, mapflags), \
.uid = (usr), \
.gid = (grp), \
.mode = (md), \
.bpfloader_min_ver = (minloader), \
.bpfloader_max_ver = (maxloader), \
.min_kver = (minkver).kver, \
.max_kver = (maxkver).kver, \
.create_location = CREATE_LOCATION(selinux), \
.pin_location = "/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_" #the_map, \
.name_idx = __builtin_strlen("/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_"), \
#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, usr, grp, md, \
selinux, pindir, minkver, maxkver, minloader, maxloader, mapflags) \
VALIDATE_SELINUX_CONTEXT(minloader, selinux); \
VALIDATE_PIN_DIR(minloader, pindir); \
const struct bpf_map_def SECTION(".android_maps") the_map##_def = { \
.type = BPF_MAP_TYPE_##TYPE, \
.key_size = (keysize), \
.value_size = (valuesize), \
.max_entries = ABSOLUTE(num_entries), \
.map_flags = DEFAULT_BPF_MAP_FLAGS(BPF_MAP_TYPE_##TYPE, num_entries, mapflags), \
.uid = (usr), \
.gid = (grp), \
.mode = (md), \
.bpfloader_min_ver = (minloader), \
.bpfloader_max_ver = (maxloader), \
.min_kver = (minkver).kver, \
.max_kver = (maxkver).kver, \
.create_location = CREATE_LOCATION(selinux), \
.pin_location = "/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_" #the_map "\0", \
.name_idx = __builtin_strlen("/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_"), \
};
#define __uint(name, val) int (*name)[val]
@ -531,30 +531,30 @@ static long (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BP
#define BPF_PROG_ATTACH_TYPE_sysctl BPF_CGROUP_SYSCTL
#define BPF_PROG_ATTACH_TYPE_xdp BPF_PROG_ATTACH_TYPE_DEFAULT
#define DEFINE_BPF_PROG_EXT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
min_loader, max_loader, opt, selinux, pindir) \
VALIDATE_SELINUX_CONTEXT(min_loader, selinux); \
VALIDATE_PIN_DIR(min_loader, pindir); \
const struct bpf_prog_def SECTION(".android_progs") the_prog##_def = { \
.type = BPF_PROG_TYPE_##TYPE, \
.attach_type = BPF_PROG_ATTACH_TYPE_##TYPE, \
.uid = (prog_uid), \
.gid = (prog_gid), \
.min_kver = (min_kv).kver, \
.max_kver = (max_kv).kver, \
.optional = (opt).optional, \
.bpfloader_min_ver = (min_loader), \
.bpfloader_max_ver = (max_loader), \
.create_location = CREATE_LOCATION(selinux), \
.pin_prefix = "/sys/fs/bpf/" pindir "/prog_" BPF_OBJ_NAME "_", \
}; \
SECTION(#TYPE "/" NAME) \
long the_prog
#define DEFINE_BPF_PROG_EXT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv, \
min_loader, max_loader, opt, selinux, pindir) \
VALIDATE_SELINUX_CONTEXT(min_loader, selinux); \
VALIDATE_PIN_DIR(min_loader, pindir); \
const struct bpf_prog_def SECTION(".android_progs") TYPE##_##NAME##_##VER##_def = { \
.type = BPF_PROG_TYPE_##TYPE, \
.attach_type = BPF_PROG_ATTACH_TYPE_##TYPE, \
.uid = (prog_uid), \
.gid = (prog_gid), \
.min_kver = (min_kv).kver, \
.max_kver = (max_kv).kver, \
.optional = (opt).optional, \
.bpfloader_min_ver = (min_loader), \
.bpfloader_max_ver = (max_loader), \
.create_location = CREATE_LOCATION(selinux), \
.pin_location = "/sys/fs/bpf/" pindir "/prog_" BPF_OBJ_NAME "_" #TYPE "_" #NAME "\0", \
}; \
SECTION(#TYPE "/" #NAME "$" #VER) \
long TYPE##_##NAME##_##VER
#define DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
opt) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, opt, \
#define DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv, \
opt) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv, \
BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, opt, \
DEFAULT_BPF_MAP_SELINUX_CONTEXT, DEFAULT_BPF_PIN_SUBDIR)
// Programs (here used in the sense of functions/sections) marked optional are allowed to fail
@ -569,26 +569,25 @@ static long (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BP
// ie. a non-optional program in a critical .o is mandatory for kernels matching the min/max kver.
// programs requiring a kernel version >= min_kv && < max_kv
#define DEFINE_BPF_PROG_KVER_RANGE(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
#define DEFINE_BPF_PROG_KVER_RANGE(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv, \
MANDATORY)
#define DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, \
max_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
#define DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, max_kv, \
OPTIONAL)
// programs requiring a kernel version >= min_kv
#define DEFINE_BPF_PROG_KVER(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, KVER_INF, \
#define DEFINE_BPF_PROG_KVER(TYPE, NAME, VER, prog_uid, prog_gid, min_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, KVER_INF, \
MANDATORY)
#define DEFINE_OPTIONAL_BPF_PROG_KVER(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, min_kv, KVER_INF, \
#define DEFINE_OPTIONAL_BPF_PROG_KVER(TYPE, NAME, VER, prog_uid, prog_gid, min_kv) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, min_kv, KVER_INF, \
OPTIONAL)
// programs with no kernel version requirements
#define DEFINE_BPF_PROG(TYPE, NAME, prog_uid, prog_gid, the_prog) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, KVER_NONE, KVER_INF, \
#define DEFINE_BPF_PROG(TYPE, NAME, VER, prog_uid, prog_gid) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, KVER_NONE, KVER_INF, \
MANDATORY)
#define DEFINE_OPTIONAL_BPF_PROG(TYPE, NAME, prog_uid, prog_gid, the_prog) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, prog_uid, prog_gid, the_prog, KVER_NONE, KVER_INF, \
#define DEFINE_OPTIONAL_BPF_PROG(TYPE, NAME, VER, prog_uid, prog_gid) \
DEFINE_BPF_PROG_KVER_RANGE_OPT(TYPE, NAME, VER, prog_uid, prog_gid, KVER_NONE, KVER_INF, \
OPTIONAL)

View file

@ -109,7 +109,7 @@ struct optional_bool { bool optional; };
// Length of strings (incl. selinux_context and pin_subdir)
// in the bpf_map_def and bpf_prog_def structs.
#define BPF_DEF_CHAR_ARRAY_SIZE 66 // must be even for alignment sanity
#define BPF_DEF_CHAR_ARRAY_SIZE 70 // must be even for alignment sanity
/*
* Map structure to be used by Android eBPF C programs. The Android eBPF loader
@ -185,7 +185,7 @@ struct bpf_prog_def {
unsigned int bpfloader_max_ver;
char create_location[BPF_DEF_CHAR_ARRAY_SIZE];
char pin_prefix[BPF_DEF_CHAR_ARRAY_SIZE];
char pin_location[BPF_DEF_CHAR_ARRAY_SIZE];
};
// This needs to be updated whenever the above structure definition is expanded.

View file

@ -113,34 +113,34 @@ DEFINE_BPF_MAP_EXT(local_net_blocked_uid_map, HASH, uint32_t, bool, -1000,
// program (see XT_BPF_MODE_PATH_PINNED) and then the iptables binary (or rather
// the kernel acting on behalf of it) must be able to retrieve the pinned program
// for the reload to succeed
#define DEFINE_XTBPF_PROG(TYPE, NAME, the_prog) \
DEFINE_BPF_PROG(TYPE, NAME, AID_ROOT, AID_NET_ADMIN, the_prog)
#define DEFINE_XTBPF_PROG(TYPE, NAME, VER) \
DEFINE_BPF_PROG(TYPE, NAME, VER, AID_ROOT, AID_NET_ADMIN)
// programs that need to be usable by netd, but not by netutils_wrappers
// (this is because these are currently attached by the mainline provided libnetd_updatable .so
// which is loaded into netd and thus runs as netd uid/gid/selinux context)
#define DEFINE_NETD_BPF_PROG_RANGES(TYPE, NAME, the_prog, minKV, maxKV, min_loader, max_loader) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, AID_ROOT, AID_ROOT, the_prog, \
minKV, maxKV, min_loader, max_loader, MANDATORY, \
#define DEFINE_NETD_BPF_PROG_RANGES(TYPE, NAME, VER, minKV, maxKV, min_loader, max_loader) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, VER, AID_ROOT, AID_ROOT, \
minKV, maxKV, min_loader, max_loader, MANDATORY, \
"netd_readonly", DEFAULT_BPF_PIN_SUBDIR)
#define DEFINE_NETD_BPF_PROG_KVER_RANGE(TYPE, NAME, the_prog, minKV, maxKV) \
DEFINE_NETD_BPF_PROG_RANGES(TYPE, NAME, the_prog, minKV, maxKV, BPFLOADER_MIN_VER, BPFLOADER_MAX_VER)
#define DEFINE_NETD_BPF_PROG_KVER_RANGE(TYPE, NAME, VER, minKV, maxKV) \
DEFINE_NETD_BPF_PROG_RANGES(TYPE, NAME, VER, minKV, maxKV, BPFLOADER_MIN_VER, BPFLOADER_MAX_VER)
#define DEFINE_NETD_BPF_PROG_KVER(TYPE, NAME, the_prog, min_kv) \
DEFINE_NETD_BPF_PROG_KVER_RANGE(TYPE, NAME, the_prog, min_kv, KVER_INF)
#define DEFINE_NETD_BPF_PROG_KVER(TYPE, NAME, VER, min_kv) \
DEFINE_NETD_BPF_PROG_KVER_RANGE(TYPE, NAME, VER, min_kv, KVER_INF)
#define DEFINE_NETD_BPF_PROG(TYPE, NAME, the_prog) \
DEFINE_NETD_BPF_PROG_KVER(TYPE, NAME, the_prog, KVER_NONE)
#define DEFINE_NETD_BPF_PROG(TYPE, NAME, VER) \
DEFINE_NETD_BPF_PROG_KVER(TYPE, NAME, VER, KVER_NONE)
#define DEFINE_NETD_V_BPF_PROG_KVER(TYPE, NAME, the_prog, minKV) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, AID_ROOT, AID_ROOT, the_prog, minKV, \
KVER_INF, BPFLOADER_MAINLINE_V_VERSION, BPFLOADER_MAX_VER, MANDATORY, \
#define DEFINE_NETD_V_BPF_PROG_KVER(TYPE, NAME, VER, minKV) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, VER, AID_ROOT, AID_ROOT, minKV, \
KVER_INF, BPFLOADER_MAINLINE_V_VERSION, BPFLOADER_MAX_VER, MANDATORY, \
"netd_readonly", DEFAULT_BPF_PIN_SUBDIR)
// programs that only need to be usable by the system server
#define DEFINE_SYS_BPF_PROG(TYPE, NAME, the_prog) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, AID_ROOT, AID_NET_ADMIN, the_prog, KVER_NONE, KVER_INF, \
#define DEFINE_SYS_BPF_PROG(TYPE, NAME, VER) \
DEFINE_BPF_PROG_EXT(TYPE, NAME, VER, AID_ROOT, AID_NET_ADMIN, KVER_NONE, KVER_INF, \
BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, MANDATORY, \
"net_shared", DEFAULT_BPF_PIN_SUBDIR)
@ -608,46 +608,40 @@ static __always_inline inline int bpf_traffic_account(struct __sk_buff* skb,
// ----- cgroupskb/ingress/stats -----
// Android 25Q2+ 5.10+ (localnet protection + tracing)
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, "ingress_stats$5_10_25q2",
bpf_cgroup_ingress_5_10_25q2, KVER_5_10, KVER_INF,
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, ingress_stats, 5_10_25q2, KVER_5_10, KVER_INF,
BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, INGRESS, KVER_5_10, SDK_LEVEL_25Q2);
}
// Android 25Q2+ 5.4 (localnet protection)
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, "ingress_stats$5_4_25q2",
bpf_cgroup_ingress_5_4_25q2, KVER_5_4, KVER_5_10,
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, ingress_stats, 5_4_25q2, KVER_5_4, KVER_5_10,
BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, INGRESS, KVER_5_4, SDK_LEVEL_25Q2);
}
// Android U/V 5.10+ (tracing)
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, "ingress_stats$5_10_u",
bpf_cgroup_ingress_5_10_u, KVER_5_10, KVER_INF,
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, ingress_stats, 5_10_u, KVER_5_10, KVER_INF,
BPFLOADER_MAINLINE_U_VERSION, BPFLOADER_MAINLINE_25Q2_VERSION)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, INGRESS, KVER_5_10, SDK_LEVEL_U);
}
// Android T/U/V/25Q2 5.4 & T 5.10/5.15
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "ingress_stats$5_4",
bpf_cgroup_ingress_5_4, KVER_5_4, KVER_INF)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, ingress_stats, 5_4, KVER_5_4, KVER_INF)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, INGRESS, KVER_5_4, SDK_LEVEL_T);
}
// Android T/U/V 4.19
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "ingress_stats$4_19",
bpf_cgroup_ingress_4_19, KVER_4_19, KVER_5_4)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, ingress_stats, 4_19, KVER_4_19, KVER_5_4)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, INGRESS, KVER_4_19, SDK_LEVEL_T);
}
// Android T 4.9 & T/U 4.14
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "ingress_stats$4_9",
bpf_cgroup_ingress_4_9, KVER_NONE, KVER_4_19)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, ingress_stats, 4_9, KVER_NONE, KVER_4_19)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, INGRESS, KVER_NONE, SDK_LEVEL_T);
}
@ -655,46 +649,40 @@ DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "ingress_stats$4_9",
// ----- cgroupskb/egress/stats -----
// Android 25Q2+ 5.10+ (localnet protection + tracing)
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, "egress_stats$5_10_25q2",
bpf_cgroup_egress_5_10_25q2, KVER_5_10, KVER_INF,
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, egress_stats, 5_10_25q2, KVER_5_10, KVER_INF,
BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, EGRESS, KVER_5_10, SDK_LEVEL_25Q2);
}
// Android 25Q2+ 5.4 (localnet protection)
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, "egress_stats$5_4_25q2",
bpf_cgroup_egress_5_4_25q2, KVER_5_4, KVER_5_10,
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, egress_stats, 5_4_25q2, KVER_5_4, KVER_5_10,
BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, EGRESS, KVER_5_4, SDK_LEVEL_25Q2);
}
// Android U/V 5.10+ (tracing)
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, "egress_stats$5_10_u",
bpf_cgroup_egress_5_10_u, KVER_5_10, KVER_INF,
DEFINE_NETD_BPF_PROG_RANGES(cgroupskb, egress_stats, 5_10_u, KVER_5_10, KVER_INF,
BPFLOADER_MAINLINE_U_VERSION, BPFLOADER_MAINLINE_25Q2_VERSION)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, EGRESS, KVER_5_10, SDK_LEVEL_U);
}
// Android T/U/V/25Q2 5.4 & T 5.10/5.15
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "egress_stats$5_4",
bpf_cgroup_egress_5_4, KVER_5_4, KVER_INF)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, egress_stats, 5_4, KVER_5_4, KVER_INF)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, EGRESS, KVER_5_4, SDK_LEVEL_T);
}
// Android T/U/V 4.19
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "egress_stats$4_19",
bpf_cgroup_egress_4_19, KVER_4_19, KVER_5_4)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, egress_stats, 4_19, KVER_4_19, KVER_5_4)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, EGRESS, KVER_4_19, SDK_LEVEL_T);
}
// Android T 4.9 & T/U 4.14
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "egress_stats$4_9",
bpf_cgroup_egress_4_9, KVER_NONE, KVER_4_19)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, egress_stats, 4_9, KVER_NONE, KVER_4_19)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, EGRESS, KVER_NONE, SDK_LEVEL_T);
}
@ -702,7 +690,7 @@ DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupskb, "egress_stats$4_9",
// -----
// WARNING: Android T's non-updatable netd depends on the name of this program.
DEFINE_XTBPF_PROG(skfilter, "egress_xtbpf", xt_bpf_egress_prog)
DEFINE_XTBPF_PROG(skfilter, egress_xtbpf, )
(struct __sk_buff* skb) {
// Clat daemon does not generate new traffic, all its traffic is accounted for already
// on the v4-* interfaces (except for the 20 (or 28) extra bytes of IPv6 vs IPv4 overhead,
@ -721,7 +709,7 @@ DEFINE_XTBPF_PROG(skfilter, "egress_xtbpf", xt_bpf_egress_prog)
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
DEFINE_XTBPF_PROG(skfilter, "ingress_xtbpf", xt_bpf_ingress_prog)
DEFINE_XTBPF_PROG(skfilter, ingress_xtbpf, )
(struct __sk_buff* skb) {
// Clat daemon traffic is not accounted by virtue of iptables raw prerouting drop rule
// (in clat_raw_PREROUTING chain), which triggers before this (in bw_raw_PREROUTING chain).
@ -733,8 +721,7 @@ DEFINE_XTBPF_PROG(skfilter, "ingress_xtbpf", xt_bpf_ingress_prog)
return XTBPF_MATCH;
}
DEFINE_SYS_BPF_PROG(schedact, "ingress_account",
tc_bpf_ingress_account_prog)
DEFINE_SYS_BPF_PROG(schedact, ingress_account, )
(struct __sk_buff* skb) {
if (is_received_skb(skb)) {
// Account for ingress traffic before tc drops it.
@ -745,7 +732,7 @@ DEFINE_SYS_BPF_PROG(schedact, "ingress_account",
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
DEFINE_XTBPF_PROG(skfilter, "allowlist_xtbpf", xt_bpf_allowlist_prog)
DEFINE_XTBPF_PROG(skfilter, allowlist_xtbpf, )
(struct __sk_buff* skb) {
uint32_t sock_uid = bpf_get_socket_uid(skb);
if (is_system_uid(sock_uid)) return XTBPF_MATCH;
@ -764,7 +751,7 @@ DEFINE_XTBPF_PROG(skfilter, "allowlist_xtbpf", xt_bpf_allowlist_prog)
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
DEFINE_XTBPF_PROG(skfilter, "denylist_xtbpf", xt_bpf_denylist_prog)
DEFINE_XTBPF_PROG(skfilter, denylist_xtbpf, )
(struct __sk_buff* skb) {
uint32_t sock_uid = bpf_get_socket_uid(skb);
UidOwnerValue* denylistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
@ -796,18 +783,17 @@ static __always_inline inline int inet_socket_create(struct bpf_sock* sk,
return (get_app_permissions() & BPF_PERMISSION_INTERNET) ? BPF_ALLOW : BPF_DISALLOW;
}
DEFINE_NETD_BPF_PROG_KVER(cgroupsock, "inet_create$5_10", inet_socket_create_5_10, KVER_5_10)
DEFINE_NETD_BPF_PROG_KVER(cgroupsock, inet_create, 5_10, KVER_5_10)
(struct bpf_sock* sk) {
return inet_socket_create(sk, KVER_5_10);
}
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupsock, "inet_create$4_14",
inet_socket_create_4_14, KVER_4_14, KVER_5_10)
DEFINE_NETD_BPF_PROG_KVER_RANGE(cgroupsock, inet_create, 4_14, KVER_4_14, KVER_5_10)
(struct bpf_sock* sk) {
return inet_socket_create(sk, KVER_4_14);
}
DEFINE_NETD_BPF_PROG_KVER(cgroupsockrelease, "inet_release", inet_socket_release, KVER_5_10)
DEFINE_NETD_BPF_PROG_KVER(cgroupsockrelease, inet_release, , KVER_5_10)
(struct bpf_sock* sk) {
uint64_t cookie = bpf_get_sk_cookie(sk);
if (cookie) bpf_cookie_tag_map_delete_elem(&cookie);
@ -860,47 +846,47 @@ static inline __always_inline int block_port(struct bpf_sock_addr *ctx) {
return BPF_ALLOW;
}
DEFINE_NETD_BPF_PROG_KVER(bind4, "inet4_bind", inet4_bind, KVER_4_19)
DEFINE_NETD_BPF_PROG_KVER(bind4, inet4_bind, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return block_port(ctx);
}
DEFINE_NETD_BPF_PROG_KVER(bind6, "inet6_bind", inet6_bind, KVER_4_19)
DEFINE_NETD_BPF_PROG_KVER(bind6, inet6_bind, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return block_port(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(connect4, "inet4_connect", inet4_connect, KVER_4_19)
DEFINE_NETD_V_BPF_PROG_KVER(connect4, inet4_connect, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return check_localhost(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(connect6, "inet6_connect", inet6_connect, KVER_4_19)
DEFINE_NETD_V_BPF_PROG_KVER(connect6, inet6_connect, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return check_localhost(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(recvmsg4, "udp4_recvmsg", udp4_recvmsg, KVER_4_19)
DEFINE_NETD_V_BPF_PROG_KVER(recvmsg4, udp4_recvmsg, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return check_localhost(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(recvmsg6, "udp6_recvmsg", udp6_recvmsg, KVER_4_19)
DEFINE_NETD_V_BPF_PROG_KVER(recvmsg6, udp6_recvmsg, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return check_localhost(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(sendmsg4, "udp4_sendmsg", udp4_sendmsg, KVER_4_19)
DEFINE_NETD_V_BPF_PROG_KVER(sendmsg4, udp4_sendmsg, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return check_localhost(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(sendmsg6, "udp6_sendmsg", udp6_sendmsg, KVER_4_19)
DEFINE_NETD_V_BPF_PROG_KVER(sendmsg6, udp6_sendmsg, , KVER_4_19)
(struct bpf_sock_addr *ctx) {
return check_localhost(ctx);
}
DEFINE_NETD_V_BPF_PROG_KVER(getsockopt, "prog", getsockopt_prog, KVER_5_4)
DEFINE_NETD_V_BPF_PROG_KVER(getsockopt, prog, , KVER_5_4)
(struct bpf_sockopt *ctx) {
// Tell kernel to return 'original' kernel reply (instead of the bpf modified buffer)
// This is important if the answer is larger than PAGE_SIZE (max size this bpf hook can provide)
@ -908,7 +894,7 @@ DEFINE_NETD_V_BPF_PROG_KVER(getsockopt, "prog", getsockopt_prog, KVER_5_4)
return BPF_ALLOW;
}
DEFINE_NETD_V_BPF_PROG_KVER(setsockopt, "prog", setsockopt_prog, KVER_5_4)
DEFINE_NETD_V_BPF_PROG_KVER(setsockopt, prog, , KVER_5_4)
(struct bpf_sockopt *ctx) {
// Tell kernel to use/process original buffer provided by userspace.
// This is important if it is larger than PAGE_SIZE (max size this bpf hook can handle).

View file

@ -257,27 +257,27 @@ static inline __always_inline int do_forward6(struct __sk_buff* skb,
}
// implementation for 5.4+ (can use skb->gso_{segs,size})
DEFINE_BPF_PROG_KVER(schedcls, "tether_downstream6_ether$5_4", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream6_ether_5_4, KVER_5_4)
DEFINE_BPF_PROG_KVER(schedcls, tether_downstream6_ether, 5_4, AID_ROOT, AID_NETWORK_STACK,
KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, ETHER, DOWNSTREAM, KVER_5_4);
}
DEFINE_BPF_PROG_KVER(schedcls, "tether_upstream6_ether$5_4", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream6_ether_5_4, KVER_5_4)
DEFINE_BPF_PROG_KVER(schedcls, tether_upstream6_ether, 5_4, AID_ROOT, AID_NETWORK_STACK,
KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, ETHER, UPSTREAM, KVER_5_4);
}
// implementation for 4.9/4.14/4.19
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream6_ether", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream6_ether, KVER_NONE, KVER_5_4)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream6_ether, , AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, ETHER, DOWNSTREAM, KVER_NONE);
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream6_ether", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream6_ether, KVER_NONE, KVER_5_4)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream6_ether, , AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, ETHER, UPSTREAM, KVER_NONE);
}
@ -296,40 +296,40 @@ DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream6_ether", AID_ROOT, AID_NET
// and in system/netd/tests/binder_test.cpp NetdBinderTest TetherOffloadForwarding.
//
// Hence, these mandatory (must load successfully) implementations for 5.4+ kernels:
DEFINE_BPF_PROG_KVER(schedcls, "tether_downstream6_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream6_rawip_5_4, KVER_5_4)
DEFINE_BPF_PROG_KVER(schedcls, tether_downstream6_rawip, 5_4, AID_ROOT, AID_NETWORK_STACK,
KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, RAWIP, DOWNSTREAM, KVER_5_4);
}
DEFINE_BPF_PROG_KVER(schedcls, "tether_upstream6_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream6_rawip_5_4, KVER_5_4)
DEFINE_BPF_PROG_KVER(schedcls, tether_upstream6_rawip, 5_4, AID_ROOT, AID_NETWORK_STACK,
KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, RAWIP, UPSTREAM, KVER_5_4);
}
// and for 4.14/4.19 kernels
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream6_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream6_rawip_4_14, KVER_4_14, KVER_5_4)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream6_rawip, 4_14, AID_ROOT, AID_NETWORK_STACK,
KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, RAWIP, DOWNSTREAM, KVER_4_14);
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream6_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream6_rawip_4_14, KVER_4_14, KVER_5_4)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream6_rawip, 4_14, AID_ROOT, AID_NETWORK_STACK,
KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward6(skb, RAWIP, UPSTREAM, KVER_4_14);
}
// and define no-op stubs for pre-4.14 kernels.
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream6_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream6_rawip_stub, KVER_NONE, KVER_4_14)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream6_rawip, stub, AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_4_14)
(__unused struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream6_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream6_rawip_stub, KVER_NONE, KVER_4_14)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream6_rawip, stub, AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_4_14)
(__unused struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
@ -644,26 +644,26 @@ static inline __always_inline int do_forward4(struct __sk_buff* skb,
// Full featured (required) implementations for 5.10+ kernels (these are S+ by definition)
DEFINE_BPF_PROG_KVER(schedcls, "tether_downstream4_rawip$5_10", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_5_10, KVER_5_10)
DEFINE_BPF_PROG_KVER(schedcls, tether_downstream4_rawip, 5_10, AID_ROOT, AID_NETWORK_STACK,
KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, DOWNSTREAM, UPDATETIME, KVER_5_10);
}
DEFINE_BPF_PROG_KVER(schedcls, "tether_upstream4_rawip$5_10", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_5_10, KVER_5_10)
DEFINE_BPF_PROG_KVER(schedcls, tether_upstream4_rawip, 5_10, AID_ROOT, AID_NETWORK_STACK,
KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, UPSTREAM, UPDATETIME, KVER_5_10);
}
DEFINE_BPF_PROG_KVER(schedcls, "tether_downstream4_ether$5_10", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_5_10, KVER_5_10)
DEFINE_BPF_PROG_KVER(schedcls, tether_downstream4_ether, 5_10, AID_ROOT, AID_NETWORK_STACK,
KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, DOWNSTREAM, UPDATETIME, KVER_5_10);
}
DEFINE_BPF_PROG_KVER(schedcls, "tether_upstream4_ether$5_10", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_5_10, KVER_5_10)
DEFINE_BPF_PROG_KVER(schedcls, tether_upstream4_ether, 5_10, AID_ROOT, AID_NETWORK_STACK,
KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, UPSTREAM, UPDATETIME, KVER_5_10);
}
@ -671,34 +671,26 @@ DEFINE_BPF_PROG_KVER(schedcls, "tether_upstream4_ether$5_10", AID_ROOT, AID_NETW
// Full featured (optional) implementations for 5.4-S kernels
// (optional, because we need to be able to fallback for 5.4 pre-S kernels)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_rawip$opt54",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_opt54,
KVER_5_4, KVER_5_10)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_rawip, opt54,
AID_ROOT, AID_NETWORK_STACK, KVER_5_4, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, DOWNSTREAM, UPDATETIME, KVER_5_4);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_rawip$opt54",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_opt54,
KVER_5_4, KVER_5_10)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_rawip, opt54,
AID_ROOT, AID_NETWORK_STACK, KVER_5_4, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, UPSTREAM, UPDATETIME, KVER_5_4);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_ether$opt54",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_opt54,
KVER_5_4, KVER_5_10)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_ether, opt54,
AID_ROOT, AID_NETWORK_STACK, KVER_5_4, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, DOWNSTREAM, UPDATETIME, KVER_5_4);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$opt54",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_opt54,
KVER_5_4, KVER_5_10)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_ether, opt54,
AID_ROOT, AID_NETWORK_STACK, KVER_5_4, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, UPSTREAM, UPDATETIME, KVER_5_4);
}
@ -706,34 +698,26 @@ DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$opt54",
// Full featured (optional) implementations for 4.14-S & 4.19-S kernels
// (optional, because we need to be able to fallback for 4.14/4.19 pre-S kernels)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_rawip$opt",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_opt,
KVER_4_14, KVER_5_4)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_rawip, opt,
AID_ROOT, AID_NETWORK_STACK, KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, DOWNSTREAM, UPDATETIME, KVER_4_14);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_rawip$opt",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_opt,
KVER_4_14, KVER_5_4)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_rawip, opt,
AID_ROOT, AID_NETWORK_STACK, KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, UPSTREAM, UPDATETIME, KVER_4_14);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_ether$opt",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_opt,
KVER_4_14, KVER_5_4)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_ether, opt,
AID_ROOT, AID_NETWORK_STACK, KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, DOWNSTREAM, UPDATETIME, KVER_4_14);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$opt",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_opt,
KVER_4_14, KVER_5_4)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_ether, opt,
AID_ROOT, AID_NETWORK_STACK, KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, UPSTREAM, UPDATETIME, KVER_4_14);
}
@ -752,14 +736,14 @@ DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$opt",
// RAWIP: Required for 5.4-R kernels -- which always support bpf_skb_change_head().
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_5_4, KVER_5_4, KVER_5_10)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_rawip, 5_4, AID_ROOT, AID_NETWORK_STACK,
KVER_5_4, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, DOWNSTREAM, NO_UPDATETIME, KVER_5_4);
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_5_4, KVER_5_4, KVER_5_10)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_rawip, 5_4, AID_ROOT, AID_NETWORK_STACK,
KVER_5_4, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, UPSTREAM, NO_UPDATETIME, KVER_5_4);
}
@ -767,32 +751,28 @@ DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_rawip$5_4", AID_ROOT, AID
// RAWIP: Optional for 4.14/4.19 (R) kernels -- which support bpf_skb_change_head().
// [Note: fallback for 4.14/4.19 (P/Q) kernels is below in stub section]
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_rawip$4_14",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_4_14,
KVER_4_14, KVER_5_4)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_rawip, 4_14,
AID_ROOT, AID_NETWORK_STACK, KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, DOWNSTREAM, NO_UPDATETIME, KVER_4_14);
}
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_rawip$4_14",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_4_14,
KVER_4_14, KVER_5_4)
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_rawip, 4_14,
AID_ROOT, AID_NETWORK_STACK, KVER_4_14, KVER_5_4)
(struct __sk_buff* skb) {
return do_forward4(skb, RAWIP, UPSTREAM, NO_UPDATETIME, KVER_4_14);
}
// ETHER: Required for 4.14-Q/R, 4.19-Q/R & 5.4-R kernels.
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_ether$4_14", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_4_14, KVER_4_14, KVER_5_10)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_ether, 4_14, AID_ROOT, AID_NETWORK_STACK,
KVER_4_14, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, DOWNSTREAM, NO_UPDATETIME, KVER_4_14);
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$4_14", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_4_14, KVER_4_14, KVER_5_10)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_ether, 4_14, AID_ROOT, AID_NETWORK_STACK,
KVER_4_14, KVER_5_10)
(struct __sk_buff* skb) {
return do_forward4(skb, ETHER, UPSTREAM, NO_UPDATETIME, KVER_4_14);
}
@ -801,28 +781,28 @@ DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$4_14", AID_ROOT, AI
// RAWIP: 4.9-P/Q, 4.14-P/Q & 4.19-Q kernels -- without bpf_skb_change_head() for tc programs
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_stub, KVER_NONE, KVER_5_4)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_rawip, stub, AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_5_4)
(__unused struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_stub, KVER_NONE, KVER_5_4)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_rawip, stub, AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_5_4)
(__unused struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
// ETHER: 4.9-P/Q kernel
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_downstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_stub, KVER_NONE, KVER_4_14)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_downstream4_ether, stub, AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_4_14)
(__unused struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE(schedcls, "tether_upstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_stub, KVER_NONE, KVER_4_14)
DEFINE_BPF_PROG_KVER_RANGE(schedcls, tether_upstream4_ether, stub, AID_ROOT, AID_NETWORK_STACK,
KVER_NONE, KVER_4_14)
(__unused struct __sk_buff* skb) {
return TC_ACT_PIPE;
}