From 5b7b9f10dcab5d40c993ccd17838381f0c35d879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Mon, 4 Aug 2025 16:26:37 -0700 Subject: [PATCH 1/3] bpf/progs: automate function name determination from prog section name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test: TreeHugger Flag: EXEMPT mainline Signed-off-by: Maciej Żenczykowski Change-Id: Id381a721bfeabdca3b513d71b805546b09617273 --- bpf/progs/clatd.c | 10 +-- bpf/progs/dscpPolicy.c | 3 +- bpf/progs/include/bpf_helpers.h | 71 ++++++++------- bpf/progs/netd.c | 106 ++++++++++------------- bpf/progs/offload.c | 148 ++++++++++++++------------------ 5 files changed, 151 insertions(+), 187 deletions(-) diff --git a/bpf/progs/clatd.c b/bpf/progs/clatd.c index a14807c2bf..7f128dbde6 100644 --- a/bpf/progs/clatd.c +++ b/bpf/progs/clatd.c @@ -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; diff --git a/bpf/progs/dscpPolicy.c b/bpf/progs/dscpPolicy.c index 47e13ffebb..2b11e5c12a 100644 --- a/bpf/progs/dscpPolicy.c +++ b/bpf/progs/dscpPolicy.c @@ -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; diff --git a/bpf/progs/include/bpf_helpers.h b/bpf/progs/include/bpf_helpers.h index a3edd8a589..b200960faf 100644 --- a/bpf/progs/include/bpf_helpers.h +++ b/bpf/progs/include/bpf_helpers.h @@ -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_prefix = "/sys/fs/bpf/" pindir "/prog_" BPF_OBJ_NAME "_", \ + }; \ + 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) diff --git a/bpf/progs/netd.c b/bpf/progs/netd.c index 55b5f145dd..9c300654b8 100644 --- a/bpf/progs/netd.c +++ b/bpf/progs/netd.c @@ -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). diff --git a/bpf/progs/offload.c b/bpf/progs/offload.c index 92bb3f3a7b..51221064d1 100644 --- a/bpf/progs/offload.c +++ b/bpf/progs/offload.c @@ -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; } From 0be5b17e61f7dd1f35eb229108353d414cbabb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Mon, 4 Aug 2025 17:12:35 -0700 Subject: [PATCH 2/3] bpf: switch progs from using 'pin_prefix' to 'pin_location' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: I discovered that C considers: char s[4] = "abcd"; a valid initialization without a terminating NULL, resulting in an invalid string. (Specifically pinned programs had a '\1' as their last char due to little endian encoding of the next field in the array of prog def structs) The simplest workaround appears to be to explicitly add a "\0" That results in a string/array that ends with 2 NULLs, and the compiler will at most *strip* the final one. ie. char s[4] = "abcd\0"; fails to compile. Obviously: char s[100] = "abcd\0"; also does the right thing, since it 0-pads with or without the extra null. Test: TreeHugger Flag: EXEMPT mainline Signed-off-by: Maciej Żenczykowski Change-Id: Iaeb8db2cd4750f8521a971382b9f9f9f216195b2 --- bpf/loader/NetBpfLoad.cpp | 24 +++++------ bpf/progs/include/bpf_helpers.h | 76 ++++++++++++++++----------------- bpf/progs/include/bpf_map_def.h | 4 +- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp index ac0b5a81d5..29c6042709 100644 --- a/bpf/loader/NetBpfLoad.cpp +++ b/bpf/loader/NetBpfLoad.cpp @@ -1005,7 +1005,7 @@ static int pinProg(const borrowed_fd& fd, const struct bpf_prog_def& progDef, 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 +1030,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 +1079,9 @@ static int loadCodeSections(ElfObject& elfObj, vector& 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 +1136,10 @@ static int loadCodeSections(ElfObject& elfObj, vector& 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(), cs[i].prog_def->pin_location); 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 +1268,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(), cs[i].prog_def->pin_location); 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; diff --git a/bpf/progs/include/bpf_helpers.h b/bpf/progs/include/bpf_helpers.h index b200960faf..4a2ad1454e 100644 --- a/bpf/progs/include/bpf_helpers.h +++ b/bpf/progs/include/bpf_helpers.h @@ -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,24 +531,24 @@ 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, 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_prefix = "/sys/fs/bpf/" pindir "/prog_" BPF_OBJ_NAME "_", \ - }; \ - SECTION(#TYPE "/" #NAME "$" #VER) \ +#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, VER, prog_uid, prog_gid, min_kv, max_kv, \ diff --git a/bpf/progs/include/bpf_map_def.h b/bpf/progs/include/bpf_map_def.h index 5a92765a06..f3e04b8da7 100644 --- a/bpf/progs/include/bpf_map_def.h +++ b/bpf/progs/include/bpf_map_def.h @@ -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. From 283689d3215b147b2677a8813010faf60cf3deac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Mon, 4 Aug 2025 18:05:25 -0700 Subject: [PATCH 3/3] NetBpfLoad: remove spurious explicit pin location from pinProg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test: TreeHugger Flag: EXEMPT mainline/noop Signed-off-by: Maciej Żenczykowski Change-Id: I17432e1495e776afd33df63037c092dc544e36e2 --- bpf/loader/NetBpfLoad.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp index 29c6042709..acf3d9df4f 100644 --- a/bpf/loader/NetBpfLoad.cpp +++ b/bpf/loader/NetBpfLoad.cpp @@ -964,8 +964,7 @@ static void applyMapRelo(ElfObject& elfObj, const vector& 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,30 +974,30 @@ 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; } @@ -1136,7 +1135,7 @@ static int loadCodeSections(ElfObject& elfObj, vector& cs, const st if (!fd.ok()) return fd.get(); if (!reuse) { - ret = pinProg(fd, cs[i].prog_def.value(), cs[i].prog_def->pin_location); + ret = pinProg(fd, cs[i].prog_def.value()); if (ret) return ret; } ret = validateProg(fd, cs[i].prog_def->pin_location, bpfloader_ver); @@ -1275,7 +1274,7 @@ static int pinProgs(const struct bpf_object * obj, } int fd = bpf_program__fd(prog); - ret = pinProg(fd, cs[i].prog_def.value(), cs[i].prog_def->pin_location); + ret = pinProg(fd, cs[i].prog_def.value()); if (ret) return ret; ret = validateProg(fd, cs[i].prog_def->pin_location, bpfloader_ver); if (ret) return ret;