Merge "Merge aosp-24Q3-ts-dev" into aosp-main-future
diff --git a/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java b/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
index ac4d8b1..2202106 100644
--- a/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
+++ b/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
@@ -65,6 +65,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.DeviceConfigUtils;
 import com.android.networkstack.tethering.UpstreamNetworkState;
 
 import java.util.ArrayList;
@@ -86,6 +88,11 @@
     private static final String SETTINGS_PKG_NAME = "com.android.settings";
     private static final String SYSTEMUI_PKG_NAME = "com.android.systemui";
     private static final String GMS_PKG_NAME = "com.google.android.gms";
+    /**
+     * A feature flag to control whether upstream data usage metrics should be enabled.
+     */
+    private static final String TETHER_UPSTREAM_DATA_USAGE_METRICS =
+            "tether_upstream_data_usage_metrics";
     private final SparseArray<NetworkTetheringReported.Builder> mBuilderMap = new SparseArray<>();
     private final SparseArray<Long> mDownstreamStartTime = new SparseArray<Long>();
     private final ArrayList<RecordUpstreamEvent> mUpstreamEventList = new ArrayList<>();
@@ -119,6 +126,16 @@
         public long timeNow() {
             return System.currentTimeMillis();
         }
+
+        /**
+         * Indicates whether {@link #TETHER_UPSTREAM_DATA_USAGE_METRICS} is enabled.
+         */
+        public boolean isUpstreamDataUsageMetricsEnabled(Context context) {
+            // Getting data usage requires building a NetworkTemplate. However, the
+            // NetworkTemplate#Builder API was introduced in Android T.
+            return SdkLevel.isAtLeastT() && DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+                    context, TETHER_UPSTREAM_DATA_USAGE_METRICS);
+        }
     }
 
     /**
@@ -135,16 +152,36 @@
         mDependencies = dependencies;
     }
 
+    private static class DataUsage {
+        final long mTxBytes;
+        final long mRxBytes;
+
+        DataUsage(long txBytes, long rxBytes) {
+            mTxBytes = txBytes;
+            mRxBytes = rxBytes;
+        }
+
+        public long getTxBytes() {
+            return mTxBytes;
+        }
+
+        public long getRxBytes() {
+            return mRxBytes;
+        }
+    }
+
     private static class RecordUpstreamEvent {
-        public final long mStartTime;
-        public final long mStopTime;
-        public final UpstreamType mUpstreamType;
+        final long mStartTime;
+        final long mStopTime;
+        final UpstreamType mUpstreamType;
+        final DataUsage mDataUsage;
 
         RecordUpstreamEvent(final long startTime, final long stopTime,
-                final UpstreamType upstream) {
+                final UpstreamType upstream, final DataUsage dataUsage) {
             mStartTime = startTime;
             mStopTime = stopTime;
             mUpstreamType = upstream;
+            mDataUsage = dataUsage;
         }
     }
 
@@ -182,6 +219,15 @@
         statsBuilder.setErrorCode(errorCodeToEnum(errCode));
     }
 
+    private DataUsage calculateDataUsage(@Nullable UpstreamType upstream) {
+        if (upstream != null && mDependencies.isUpstreamDataUsageMetricsEnabled(mContext)
+                && isUsageSupportedForUpstreamType(upstream)) {
+            // TODO: Implement data usage calculation for the upstream type.
+            return new DataUsage(0L, 0L);
+        }
+        return new DataUsage(0L, 0L);
+    }
+
     /**
      * Update the list of upstream types and their duration whenever the current upstream type
      * changes.
@@ -193,8 +239,9 @@
 
         final long newTime = mDependencies.timeNow();
         if (mCurrentUpstream != null) {
+            final DataUsage dataUsage = calculateDataUsage(upstream);
             mUpstreamEventList.add(new RecordUpstreamEvent(mCurrentUpStreamStartTime, newTime,
-                    mCurrentUpstream));
+                    mCurrentUpstream, dataUsage));
         }
         mCurrentUpstream = upstream;
         mCurrentUpStreamStartTime = newTime;
@@ -245,13 +292,14 @@
             final long startTime = Math.max(downstreamStartTime, event.mStartTime);
             // Handle completed upstream events.
             addUpstreamEvent(upstreamEventsBuilder, startTime, event.mStopTime,
-                    event.mUpstreamType, 0L /* txBytes */, 0L /* rxBytes */);
+                    event.mUpstreamType, event.mDataUsage.mTxBytes, event.mDataUsage.mRxBytes);
         }
         final long startTime = Math.max(downstreamStartTime, mCurrentUpStreamStartTime);
         final long stopTime = mDependencies.timeNow();
         // Handle the last upstream event.
+        final DataUsage dataUsage = calculateDataUsage(mCurrentUpstream);
         addUpstreamEvent(upstreamEventsBuilder, startTime, stopTime, mCurrentUpstream,
-                0L /* txBytes */, 0L /* rxBytes */);
+                dataUsage.mTxBytes, dataUsage.mRxBytes);
         statsBuilder.setUpstreamEvents(upstreamEventsBuilder);
         statsBuilder.setDurationMillis(stopTime - downstreamStartTime);
     }
diff --git a/bpf_progs/block.c b/bpf_progs/block.c
index 152dda6..0e2dba9 100644
--- a/bpf_progs/block.c
+++ b/bpf_progs/block.c
@@ -14,24 +14,16 @@
  * limitations under the License.
  */
 
-#include <linux/types.h>
-#include <linux/bpf.h>
-#include <netinet/in.h>
-#include <stdint.h>
-
 // The resulting .o needs to load on Android T+
 #define BPFLOADER_MIN_VER BPFLOADER_MAINLINE_T_VERSION
 
-#include "bpf_helpers.h"
-
-static const int ALLOW = 1;
-static const int DISALLOW = 0;
+#include "bpf_net_helpers.h"
 
 DEFINE_BPF_MAP_GRW(blocked_ports_map, ARRAY, int, uint64_t,
         1024 /* 64K ports -> 1024 u64s */, AID_SYSTEM)
 
 static inline __always_inline int block_port(struct bpf_sock_addr *ctx) {
-    if (!ctx->user_port) return ALLOW;
+    if (!ctx->user_port) return BPF_ALLOW;
 
     switch (ctx->protocol) {
         case IPPROTO_TCP:
@@ -42,7 +34,7 @@
         case IPPROTO_SCTP:
             break;
         default:
-            return ALLOW; // unknown protocols are allowed
+            return BPF_ALLOW; // unknown protocols are allowed
     }
 
     int key = ctx->user_port >> 6;
@@ -51,10 +43,10 @@
     uint64_t *val = bpf_blocked_ports_map_lookup_elem(&key);
     // Lookup should never fail in reality, but if it does return here to keep the
     // BPF verifier happy.
-    if (!val) return ALLOW;
+    if (!val) return BPF_ALLOW;
 
-    if ((*val >> shift) & 1) return DISALLOW;
-    return ALLOW;
+    if ((*val >> shift) & 1) return BPF_DISALLOW;
+    return BPF_ALLOW;
 }
 
 // the program need to be accessible/loadable by netd (from netd updatable plugin)
@@ -75,4 +67,3 @@
 
 LICENSE("Apache 2.0");
 CRITICAL("ConnectivityNative");
-DISABLE_BTF_ON_USER_BUILDS();
diff --git a/bpf_progs/bpf_net_helpers.h b/bpf_progs/bpf_net_helpers.h
index ba2f26b..a86c3e6 100644
--- a/bpf_progs/bpf_net_helpers.h
+++ b/bpf_progs/bpf_net_helpers.h
@@ -17,21 +17,72 @@
 #pragma once
 
 #include <linux/bpf.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
 #include <linux/if_packet.h>
-#include <stdbool.h>
-#include <stdint.h>
-
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/tcp.h>
 // bionic kernel uapi linux/udp.h header is munged...
 #define __kernel_udphdr udphdr
 #include <linux/udp.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "bpf_helpers.h"
+
+// IP flags. (from kernel's include/net/ip.h)
+#define IP_CE      0x8000  // Flag: "Congestion" (really reserved 'evil bit')
+#define IP_DF      0x4000  // Flag: "Don't Fragment"
+#define IP_MF      0x2000  // Flag: "More Fragments"
+#define IP_OFFSET  0x1FFF  // "Fragment Offset" part
+
+// IPv6 fragmentation header. (from kernel's include/net/ipv6.h)
+struct frag_hdr {
+    __u8   nexthdr;
+    __u8   reserved;        // always zero
+    __be16 frag_off;        // 13 bit offset, 2 bits zero, 1 bit "More Fragments"
+    __be32 identification;
+};
+
+// ----- Helper functions for offsets to fields -----
+
+// They all assume simple IP packets:
+//   - no VLAN ethernet tags
+//   - no IPv4 options (see IPV4_HLEN/TCP4_OFFSET/UDP4_OFFSET)
+//   - no IPv6 extension headers
+//   - no TCP options (see TCP_HLEN)
+
+//#define ETH_HLEN sizeof(struct ethhdr)
+#define IP4_HLEN sizeof(struct iphdr)
+#define IP6_HLEN sizeof(struct ipv6hdr)
+#define TCP_HLEN sizeof(struct tcphdr)
+#define UDP_HLEN sizeof(struct udphdr)
 
 // Offsets from beginning of L4 (TCP/UDP) header
 #define TCP_OFFSET(field) offsetof(struct tcphdr, field)
 #define UDP_OFFSET(field) offsetof(struct udphdr, field)
 
-// Offsets from beginning of L3 (IPv4/IPv6) header
+// Offsets from beginning of L3 (IPv4) header
 #define IP4_OFFSET(field) offsetof(struct iphdr, field)
+#define IP4_TCP_OFFSET(field) (IP4_HLEN + TCP_OFFSET(field))
+#define IP4_UDP_OFFSET(field) (IP4_HLEN + UDP_OFFSET(field))
+
+// Offsets from beginning of L3 (IPv6) header
 #define IP6_OFFSET(field) offsetof(struct ipv6hdr, field)
+#define IP6_TCP_OFFSET(field) (IP6_HLEN + TCP_OFFSET(field))
+#define IP6_UDP_OFFSET(field) (IP6_HLEN + UDP_OFFSET(field))
+
+// Offsets from beginning of L2 (ie. Ethernet) header (which must be present)
+#define ETH_IP4_OFFSET(field) (ETH_HLEN + IP4_OFFSET(field))
+#define ETH_IP4_TCP_OFFSET(field) (ETH_HLEN + IP4_TCP_OFFSET(field))
+#define ETH_IP4_UDP_OFFSET(field) (ETH_HLEN + IP4_UDP_OFFSET(field))
+#define ETH_IP6_OFFSET(field) (ETH_HLEN + IP6_OFFSET(field))
+#define ETH_IP6_TCP_OFFSET(field) (ETH_HLEN + IP6_TCP_OFFSET(field))
+#define ETH_IP6_UDP_OFFSET(field) (ETH_HLEN + IP6_UDP_OFFSET(field))
 
 // this returns 0 iff skb->sk is NULL
 static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_cookie;
@@ -103,3 +154,10 @@
 struct updatetime_bool { bool updatetime; };
 #define NO_UPDATETIME ((struct updatetime_bool){ .updatetime = false })
 #define UPDATETIME ((struct updatetime_bool){ .updatetime = true })
+
+// Return value for xt_bpf (netfilter match extension) programs
+static const int XTBPF_NOMATCH = 0;
+static const int XTBPF_MATCH = 1;
+
+static const int BPF_DISALLOW = 0;
+static const int BPF_ALLOW = 1;
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index da6ccbf..2d4551e 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -14,44 +14,13 @@
  * limitations under the License.
  */
 
-#include <linux/bpf.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/pkt_cls.h>
-#include <linux/swab.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-// bionic kernel uapi linux/udp.h header is munged...
-#define __kernel_udphdr udphdr
-#include <linux/udp.h>
-
 // The resulting .o needs to load on Android T+
 #define BPFLOADER_MIN_VER BPFLOADER_MAINLINE_T_VERSION
 
-#include "bpf_helpers.h"
 #include "bpf_net_helpers.h"
 #include "clatd.h"
 #include "clat_mark.h"
 
-// IP flags. (from kernel's include/net/ip.h)
-#define IP_CE      0x8000  // Flag: "Congestion" (really reserved 'evil bit')
-#define IP_DF      0x4000  // Flag: "Don't Fragment"
-#define IP_MF      0x2000  // Flag: "More Fragments"
-#define IP_OFFSET  0x1FFF  // "Fragment Offset" part
-
-// from kernel's include/net/ipv6.h
-struct frag_hdr {
-    __u8   nexthdr;
-    __u8   reserved;        // always zero
-    __be16 frag_off;        // 13 bit offset, 2 bits zero, 1 bit "More Fragments"
-    __be32 identification;
-};
-
 DEFINE_BPF_MAP_GRW(clat_ingress6_map, HASH, ClatIngress6Key, ClatIngress6Value, 16, AID_SYSTEM)
 
 static inline __always_inline int nat64(struct __sk_buff* skb,
@@ -430,4 +399,3 @@
 
 LICENSE("Apache 2.0");
 CRITICAL("Connectivity");
-DISABLE_BTF_ON_USER_BUILDS();
diff --git a/bpf_progs/dscpPolicy.c b/bpf_progs/dscpPolicy.c
index ed114e4..93542ee 100644
--- a/bpf_progs/dscpPolicy.c
+++ b/bpf_progs/dscpPolicy.c
@@ -14,27 +14,13 @@
  * limitations under the License.
  */
 
-#include <linux/bpf.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/pkt_cls.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <netinet/in.h>
-#include <netinet/udp.h>
-#include <stdint.h>
-#include <string.h>
-
 // The resulting .o needs to load on Android T+
 #define BPFLOADER_MIN_VER BPFLOADER_MAINLINE_T_VERSION
 
-#include "bpf_helpers.h"
+#include "bpf_net_helpers.h"
 #include "dscpPolicy.h"
 
 #define ECN_MASK 3
-#define IP4_OFFSET(field, header) ((header) + offsetof(struct iphdr, field))
 #define UPDATE_TOS(dscp, tos) ((dscp) << 2) | ((tos) & ECN_MASK)
 
 DEFINE_BPF_MAP_GRW(socket_policy_cache_map, HASH, uint64_t, RuleEntry, CACHE_MAP_SIZE, AID_SYSTEM)
@@ -131,9 +117,9 @@
         if (existing_rule->dscp_val < 0) return;
         if (ipv4) {
             uint8_t newTos = UPDATE_TOS(existing_rule->dscp_val, tos);
-            bpf_l3_csum_replace(skb, IP4_OFFSET(check, l2_header_size), htons(tos), htons(newTos),
+            bpf_l3_csum_replace(skb, l2_header_size + IP4_OFFSET(check), htons(tos), htons(newTos),
                                 sizeof(uint16_t));
-            bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &newTos, sizeof(newTos), 0);
+            bpf_skb_store_bytes(skb, l2_header_size + IP4_OFFSET(tos), &newTos, sizeof(newTos), 0);
         } else {
             __be32 new_first_be32 =
                 htonl(ntohl(old_first_be32) & 0xF03FFFFF | (existing_rule->dscp_val << 22));
@@ -211,8 +197,8 @@
     // Need to store bytes after updating map or program will not load.
     if (ipv4) {
         uint8_t new_tos = UPDATE_TOS(new_dscp, tos);
-        bpf_l3_csum_replace(skb, IP4_OFFSET(check, l2_header_size), htons(tos), htons(new_tos), 2);
-        bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &new_tos, sizeof(new_tos), 0);
+        bpf_l3_csum_replace(skb, l2_header_size + IP4_OFFSET(check), htons(tos), htons(new_tos), 2);
+        bpf_skb_store_bytes(skb, l2_header_size + IP4_OFFSET(tos), &new_tos, sizeof(new_tos), 0);
     } else {
         __be32 new_first_be32 = htonl(ntohl(old_first_be32) & 0xF03FFFFF | (new_dscp << 22));
         bpf_skb_store_bytes(skb, l2_header_size, &new_first_be32, sizeof(__be32),
@@ -238,4 +224,3 @@
 
 LICENSE("Apache 2.0");
 CRITICAL("Connectivity");
-DISABLE_BTF_ON_USER_BUILDS();
diff --git a/bpf_progs/dscpPolicy.h b/bpf_progs/dscpPolicy.h
index e565966..ea84655 100644
--- a/bpf_progs/dscpPolicy.h
+++ b/bpf_progs/dscpPolicy.h
@@ -37,17 +37,6 @@
 // Returns 'a == b' as boolean
 #define v6_equal(a, b) (!v6_not_equal((a), (b)))
 
-// TODO: these are already defined in packages/modules/Connectivity/bpf_progs/bpf_net_helpers.h.
-// smove to common location in future.
-static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) =
-        (void*)BPF_FUNC_get_socket_cookie;
-static int (*bpf_skb_store_bytes)(struct __sk_buff* skb, __u32 offset, const void* from, __u32 len,
-                                  __u64 flags) = (void*)BPF_FUNC_skb_store_bytes;
-static int (*bpf_l3_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
-                                  __u64 flags) = (void*)BPF_FUNC_l3_csum_replace;
-static long (*bpf_skb_ecn_set_ce)(struct __sk_buff* skb) =
-        (void*)BPF_FUNC_skb_ecn_set_ce;
-
 typedef struct {
     struct in6_addr src_ip;
     struct in6_addr dst_ip;
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index f08b007..4248a46 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -17,19 +17,6 @@
 // The resulting .o needs to load on Android T+
 #define BPFLOADER_MIN_VER BPFLOADER_MAINLINE_T_VERSION
 
-#include <bpf_helpers.h>
-#include <linux/bpf.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/pkt_cls.h>
-#include <linux/tcp.h>
-#include <stdbool.h>
-#include <stdint.h>
 #include "bpf_net_helpers.h"
 #include "netd.h"
 
@@ -38,10 +25,6 @@
 static const int PASS = 1;
 static const int DROP_UNLESS_DNS = 2;  // internal to our program
 
-// This is used for xt_bpf program only.
-static const int BPF_NOMATCH = 0;
-static const int BPF_MATCH = 1;
-
 // Used for 'bool enable_tracing'
 static const bool TRACE_ON = true;
 static const bool TRACE_OFF = false;
@@ -579,12 +562,12 @@
     if (sock_uid == AID_SYSTEM) {
         uint64_t cookie = bpf_get_socket_cookie(skb);
         UidTagValue* utag = bpf_cookie_tag_map_lookup_elem(&cookie);
-        if (utag && utag->uid == AID_CLAT) return BPF_NOMATCH;
+        if (utag && utag->uid == AID_CLAT) return XTBPF_NOMATCH;
     }
 
     uint32_t key = skb->ifindex;
     update_iface_stats_map(skb, &key, EGRESS, KVER_NONE);
-    return BPF_MATCH;
+    return XTBPF_MATCH;
 }
 
 // WARNING: Android T's non-updatable netd depends on the name of this program.
@@ -597,7 +580,7 @@
 
     uint32_t key = skb->ifindex;
     update_iface_stats_map(skb, &key, INGRESS, KVER_NONE);
-    return BPF_MATCH;
+    return XTBPF_MATCH;
 }
 
 DEFINE_SYS_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN,
@@ -615,7 +598,7 @@
 DEFINE_XTBPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allowlist_prog)
 (struct __sk_buff* skb) {
     uint32_t sock_uid = bpf_get_socket_uid(skb);
-    if (is_system_uid(sock_uid)) return BPF_MATCH;
+    if (is_system_uid(sock_uid)) return XTBPF_MATCH;
 
     // kernel's DEFAULT_OVERFLOWUID is 65534, this is the overflow 'nobody' uid,
     // usually this being returned means that skb->sk is NULL during RX
@@ -623,11 +606,11 @@
     // packets to an unconnected udp socket.
     // But it can also happen for egress from a timewait socket.
     // Let's treat such cases as 'root' which is_system_uid()
-    if (sock_uid == 65534) return BPF_MATCH;
+    if (sock_uid == 65534) return XTBPF_MATCH;
 
     UidOwnerValue* allowlistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
-    if (allowlistMatch) return allowlistMatch->rule & HAPPY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
-    return BPF_NOMATCH;
+    if (allowlistMatch) return allowlistMatch->rule & HAPPY_BOX_MATCH ? XTBPF_MATCH : XTBPF_NOMATCH;
+    return XTBPF_NOMATCH;
 }
 
 // WARNING: Android T's non-updatable netd depends on the name of this program.
@@ -636,8 +619,8 @@
     uint32_t sock_uid = bpf_get_socket_uid(skb);
     UidOwnerValue* denylistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
     uint32_t penalty_box = PENALTY_BOX_USER_MATCH | PENALTY_BOX_ADMIN_MATCH;
-    if (denylistMatch) return denylistMatch->rule & penalty_box ? BPF_MATCH : BPF_NOMATCH;
-    return BPF_NOMATCH;
+    if (denylistMatch) return denylistMatch->rule & penalty_box ? XTBPF_MATCH : XTBPF_NOMATCH;
+    return XTBPF_NOMATCH;
 }
 
 static __always_inline inline uint8_t get_app_permissions() {
@@ -657,8 +640,7 @@
 DEFINE_NETD_BPF_PROG_KVER("cgroupsock/inet_create", AID_ROOT, AID_ROOT, inet_socket_create,
                           KVER_4_14)
 (__unused struct bpf_sock* sk) {
-    // A return value of 1 means allow, everything else means deny.
-    return (get_app_permissions() & BPF_PERMISSION_INTERNET) ? 1 : 0;
+    return (get_app_permissions() & BPF_PERMISSION_INTERNET) ? BPF_ALLOW : BPF_DISALLOW;
 }
 
 DEFINE_NETD_V_BPF_PROG_KVER("cgroupsockrelease/inet_release", AID_ROOT, AID_ROOT,
@@ -685,7 +667,7 @@
     //   __u32 msg_src_ip6[4];	// BE, R: 1,2,4,8-byte, W: 4,8-byte
     //   __bpf_md_ptr(struct bpf_sock *, sk);
     // };
-    return 1;
+    return BPF_ALLOW;
 }
 
 DEFINE_NETD_V_BPF_PROG_KVER("connect4/inet4_connect", AID_ROOT, AID_ROOT, inet4_connect, KVER_4_14)
@@ -723,7 +705,7 @@
     // 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)
     ctx->optlen = 0;
-    return 1; // ALLOW
+    return BPF_ALLOW;
 }
 
 DEFINE_NETD_V_BPF_PROG_KVER("setsockopt/prog", AID_ROOT, AID_ROOT, setsockopt_prog, KVER_5_4)
@@ -731,9 +713,8 @@
     // 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).
     ctx->optlen = 0;
-    return 1; // ALLOW
+    return BPF_ALLOW;
 }
 
 LICENSE("Apache 2.0");
 CRITICAL("Connectivity and netd");
-DISABLE_BTF_ON_USER_BUILDS();
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index 4d908d2..7e1184d 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -14,16 +14,6 @@
  * limitations under the License.
  */
 
-#include <linux/if.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/pkt_cls.h>
-#include <linux/tcp.h>
-
-// bionic kernel uapi linux/udp.h header is munged...
-#define __kernel_udphdr udphdr
-#include <linux/udp.h>
-
 #ifdef MAINLINE
 // BTF is incompatible with bpfloaders < v0.10, hence for S (v0.2) we must
 // ship a different file than for later versions, but we need bpfloader v0.25+
@@ -35,61 +25,16 @@
 #define BPFLOADER_MAX_VER BPFLOADER_T_VERSION
 #endif /* MAINLINE */
 
-// Warning: values other than AID_ROOT don't work for map uid on BpfLoader < v0.21
-#define TETHERING_UID AID_ROOT
-
-#define TETHERING_GID AID_NETWORK_STACK
-
-#include "bpf_helpers.h"
 #include "bpf_net_helpers.h"
 #include "offload.h"
 
-// From kernel:include/net/ip.h
-#define IP_DF 0x4000  // Flag: "Don't Fragment"
-
-// ----- Helper functions for offsets to fields -----
-
-// They all assume simple IP packets:
-//   - no VLAN ethernet tags
-//   - no IPv4 options (see IPV4_HLEN/TCP4_OFFSET/UDP4_OFFSET)
-//   - no IPv6 extension headers
-//   - no TCP options (see TCP_HLEN)
-
-//#define ETH_HLEN sizeof(struct ethhdr)
-#define IP4_HLEN sizeof(struct iphdr)
-#define IP6_HLEN sizeof(struct ipv6hdr)
-#define TCP_HLEN sizeof(struct tcphdr)
-#define UDP_HLEN sizeof(struct udphdr)
-
-// Offsets from beginning of L4 (TCP/UDP) header
-#define TCP_OFFSET(field) offsetof(struct tcphdr, field)
-#define UDP_OFFSET(field) offsetof(struct udphdr, field)
-
-// Offsets from beginning of L3 (IPv4) header
-#define IP4_OFFSET(field) offsetof(struct iphdr, field)
-#define IP4_TCP_OFFSET(field) (IP4_HLEN + TCP_OFFSET(field))
-#define IP4_UDP_OFFSET(field) (IP4_HLEN + UDP_OFFSET(field))
-
-// Offsets from beginning of L3 (IPv6) header
-#define IP6_OFFSET(field) offsetof(struct ipv6hdr, field)
-#define IP6_TCP_OFFSET(field) (IP6_HLEN + TCP_OFFSET(field))
-#define IP6_UDP_OFFSET(field) (IP6_HLEN + UDP_OFFSET(field))
-
-// Offsets from beginning of L2 (ie. Ethernet) header (which must be present)
-#define ETH_IP4_OFFSET(field) (ETH_HLEN + IP4_OFFSET(field))
-#define ETH_IP4_TCP_OFFSET(field) (ETH_HLEN + IP4_TCP_OFFSET(field))
-#define ETH_IP4_UDP_OFFSET(field) (ETH_HLEN + IP4_UDP_OFFSET(field))
-#define ETH_IP6_OFFSET(field) (ETH_HLEN + IP6_OFFSET(field))
-#define ETH_IP6_TCP_OFFSET(field) (ETH_HLEN + IP6_TCP_OFFSET(field))
-#define ETH_IP6_UDP_OFFSET(field) (ETH_HLEN + IP6_UDP_OFFSET(field))
-
 // ----- Tethering Error Counters -----
 
 // Note that pre-T devices with Mediatek chipsets may have a kernel bug (bad patch
 // "[ALPS05162612] bpf: fix ubsan error") making it impossible to write to non-zero
 // offset of bpf map ARRAYs.  This file (offload.o) loads on S+, but luckily this
 // array is only written by bpf code, and only read by userspace.
-DEFINE_BPF_MAP_RO(tether_error_map, ARRAY, uint32_t, uint32_t, BPF_TETHER_ERR__MAX, TETHERING_GID)
+DEFINE_BPF_MAP_RO(tether_error_map, ARRAY, uint32_t, uint32_t, BPF_TETHER_ERR__MAX, AID_NETWORK_STACK)
 
 #define COUNT_AND_RETURN(counter, ret) do {                     \
     uint32_t code = BPF_TETHER_ERR_ ## counter;                 \
@@ -107,22 +52,22 @@
 // ----- Tethering Data Stats and Limits -----
 
 // Tethering stats, indexed by upstream interface.
-DEFINE_BPF_MAP_GRW(tether_stats_map, HASH, TetherStatsKey, TetherStatsValue, 16, TETHERING_GID)
+DEFINE_BPF_MAP_GRW(tether_stats_map, HASH, TetherStatsKey, TetherStatsValue, 16, AID_NETWORK_STACK)
 
 // Tethering data limit, indexed by upstream interface.
 // (tethering allowed when stats[iif].rxBytes + stats[iif].txBytes < limit[iif])
-DEFINE_BPF_MAP_GRW(tether_limit_map, HASH, TetherLimitKey, TetherLimitValue, 16, TETHERING_GID)
+DEFINE_BPF_MAP_GRW(tether_limit_map, HASH, TetherLimitKey, TetherLimitValue, 16, AID_NETWORK_STACK)
 
 // ----- IPv6 Support -----
 
 DEFINE_BPF_MAP_GRW(tether_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 64,
-                   TETHERING_GID)
+                   AID_NETWORK_STACK)
 
 DEFINE_BPF_MAP_GRW(tether_downstream64_map, HASH, TetherDownstream64Key, TetherDownstream64Value,
-                   1024, TETHERING_GID)
+                   1024, AID_NETWORK_STACK)
 
 DEFINE_BPF_MAP_GRW(tether_upstream6_map, HASH, TetherUpstream6Key, Tether6Value, 64,
-                   TETHERING_GID)
+                   AID_NETWORK_STACK)
 
 static inline __always_inline int do_forward6(struct __sk_buff* skb,
                                               const struct rawip_bool rawip,
@@ -302,13 +247,13 @@
     return bpf_redirect(v->oif, 0 /* this is effectively BPF_F_EGRESS */);
 }
 
-DEFINE_BPF_PROG("schedcls/tether_downstream6_ether", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG("schedcls/tether_downstream6_ether", AID_ROOT, AID_NETWORK_STACK,
                 sched_cls_tether_downstream6_ether)
 (struct __sk_buff* skb) {
     return do_forward6(skb, ETHER, DOWNSTREAM, KVER_NONE);
 }
 
-DEFINE_BPF_PROG("schedcls/tether_upstream6_ether", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG("schedcls/tether_upstream6_ether", AID_ROOT, AID_NETWORK_STACK,
                 sched_cls_tether_upstream6_ether)
 (struct __sk_buff* skb) {
     return do_forward6(skb, ETHER, UPSTREAM, KVER_NONE);
@@ -328,26 +273,26 @@
 // and in system/netd/tests/binder_test.cpp NetdBinderTest TetherOffloadForwarding.
 //
 // Hence, these mandatory (must load successfully) implementations for 4.14+ kernels:
-DEFINE_BPF_PROG_KVER("schedcls/tether_downstream6_rawip$4_14", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream6_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
                      sched_cls_tether_downstream6_rawip_4_14, KVER_4_14)
 (struct __sk_buff* skb) {
     return do_forward6(skb, RAWIP, DOWNSTREAM, KVER_4_14);
 }
 
-DEFINE_BPF_PROG_KVER("schedcls/tether_upstream6_rawip$4_14", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream6_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
                      sched_cls_tether_upstream6_rawip_4_14, KVER_4_14)
 (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", TETHERING_UID, TETHERING_GID,
+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)
 (__unused struct __sk_buff* skb) {
     return TC_ACT_PIPE;
 }
 
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream6_rawip$stub", TETHERING_UID, TETHERING_GID,
+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)
 (__unused struct __sk_buff* skb) {
     return TC_ACT_PIPE;
@@ -355,9 +300,9 @@
 
 // ----- IPv4 Support -----
 
-DEFINE_BPF_MAP_GRW(tether_downstream4_map, HASH, Tether4Key, Tether4Value, 1024, TETHERING_GID)
+DEFINE_BPF_MAP_GRW(tether_downstream4_map, HASH, Tether4Key, Tether4Value, 1024, AID_NETWORK_STACK)
 
-DEFINE_BPF_MAP_GRW(tether_upstream4_map, HASH, Tether4Key, Tether4Value, 1024, TETHERING_GID)
+DEFINE_BPF_MAP_GRW(tether_upstream4_map, HASH, Tether4Key, Tether4Value, 1024, AID_NETWORK_STACK)
 
 static inline __always_inline int do_forward4_bottom(struct __sk_buff* skb,
         const int l2_header_size, void* data, const void* data_end,
@@ -656,25 +601,25 @@
 
 // Full featured (required) implementations for 5.8+ kernels (these are S+ by definition)
 
-DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_rawip$5_8", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_rawip$5_8", AID_ROOT, AID_NETWORK_STACK,
                      sched_cls_tether_downstream4_rawip_5_8, KVER_5_8)
 (struct __sk_buff* skb) {
     return do_forward4(skb, RAWIP, DOWNSTREAM, UPDATETIME, KVER_5_8);
 }
 
-DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_rawip$5_8", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_rawip$5_8", AID_ROOT, AID_NETWORK_STACK,
                      sched_cls_tether_upstream4_rawip_5_8, KVER_5_8)
 (struct __sk_buff* skb) {
     return do_forward4(skb, RAWIP, UPSTREAM, UPDATETIME, KVER_5_8);
 }
 
-DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_ether$5_8", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
                      sched_cls_tether_downstream4_ether_5_8, KVER_5_8)
 (struct __sk_buff* skb) {
     return do_forward4(skb, ETHER, DOWNSTREAM, UPDATETIME, KVER_5_8);
 }
 
-DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_ether$5_8", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
                      sched_cls_tether_upstream4_ether_5_8, KVER_5_8)
 (struct __sk_buff* skb) {
     return do_forward4(skb, ETHER, UPSTREAM, UPDATETIME, KVER_5_8);
@@ -684,7 +629,7 @@
 // (optional, because we need to be able to fallback for 4.14/4.19/5.4 pre-S kernels)
 
 DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$opt",
-                                    TETHERING_UID, TETHERING_GID,
+                                    AID_ROOT, AID_NETWORK_STACK,
                                     sched_cls_tether_downstream4_rawip_opt,
                                     KVER_4_14, KVER_5_8)
 (struct __sk_buff* skb) {
@@ -692,7 +637,7 @@
 }
 
 DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$opt",
-                                    TETHERING_UID, TETHERING_GID,
+                                    AID_ROOT, AID_NETWORK_STACK,
                                     sched_cls_tether_upstream4_rawip_opt,
                                     KVER_4_14, KVER_5_8)
 (struct __sk_buff* skb) {
@@ -700,7 +645,7 @@
 }
 
 DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$opt",
-                                    TETHERING_UID, TETHERING_GID,
+                                    AID_ROOT, AID_NETWORK_STACK,
                                     sched_cls_tether_downstream4_ether_opt,
                                     KVER_4_14, KVER_5_8)
 (struct __sk_buff* skb) {
@@ -708,7 +653,7 @@
 }
 
 DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$opt",
-                                    TETHERING_UID, TETHERING_GID,
+                                    AID_ROOT, AID_NETWORK_STACK,
                                     sched_cls_tether_upstream4_ether_opt,
                                     KVER_4_14, KVER_5_8)
 (struct __sk_buff* skb) {
@@ -729,13 +674,13 @@
 
 // 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", TETHERING_UID, TETHERING_GID,
+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_8)
 (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", TETHERING_UID, TETHERING_GID,
+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_8)
 (struct __sk_buff* skb) {
     return do_forward4(skb, RAWIP, UPSTREAM, NO_UPDATETIME, KVER_5_4);
@@ -745,7 +690,7 @@
 // [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",
-                                    TETHERING_UID, TETHERING_GID,
+                                    AID_ROOT, AID_NETWORK_STACK,
                                     sched_cls_tether_downstream4_rawip_4_14,
                                     KVER_4_14, KVER_5_4)
 (struct __sk_buff* skb) {
@@ -753,7 +698,7 @@
 }
 
 DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$4_14",
-                                    TETHERING_UID, TETHERING_GID,
+                                    AID_ROOT, AID_NETWORK_STACK,
                                     sched_cls_tether_upstream4_rawip_4_14,
                                     KVER_4_14, KVER_5_4)
 (struct __sk_buff* skb) {
@@ -762,13 +707,13 @@
 
 // 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", TETHERING_UID, TETHERING_GID,
+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_8)
 (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", TETHERING_UID, TETHERING_GID,
+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_8)
 (struct __sk_buff* skb) {
     return do_forward4(skb, ETHER, UPSTREAM, NO_UPDATETIME, KVER_4_14);
@@ -778,13 +723,13 @@
 
 // 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", TETHERING_UID, TETHERING_GID,
+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)
 (__unused struct __sk_buff* skb) {
     return TC_ACT_PIPE;
 }
 
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$stub", TETHERING_UID, TETHERING_GID,
+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)
 (__unused struct __sk_buff* skb) {
     return TC_ACT_PIPE;
@@ -792,13 +737,13 @@
 
 // ETHER: 4.9-P/Q kernel
 
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$stub", TETHERING_UID, TETHERING_GID,
+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)
 (__unused struct __sk_buff* skb) {
     return TC_ACT_PIPE;
 }
 
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$stub", TETHERING_UID, TETHERING_GID,
+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)
 (__unused struct __sk_buff* skb) {
     return TC_ACT_PIPE;
@@ -806,7 +751,7 @@
 
 // ----- XDP Support -----
 
-DEFINE_BPF_MAP_GRW(tether_dev_map, DEVMAP_HASH, uint32_t, uint32_t, 64, TETHERING_GID)
+DEFINE_BPF_MAP_GRW(tether_dev_map, DEVMAP_HASH, uint32_t, uint32_t, 64, AID_NETWORK_STACK)
 
 static inline __always_inline int do_xdp_forward6(__unused struct xdp_md *ctx,
         __unused const struct rawip_bool rawip, __unused const struct stream_bool stream) {
@@ -853,7 +798,7 @@
 }
 
 #define DEFINE_XDP_PROG(str, func) \
-    DEFINE_BPF_PROG_KVER(str, TETHERING_UID, TETHERING_GID, func, KVER_5_9)(struct xdp_md *ctx)
+    DEFINE_BPF_PROG_KVER(str, AID_ROOT, AID_NETWORK_STACK, func, KVER_5_9)(struct xdp_md *ctx)
 
 DEFINE_XDP_PROG("xdp/tether_downstream_ether",
                  xdp_tether_downstream_ether) {
@@ -877,4 +822,3 @@
 
 LICENSE("Apache 2.0");
 CRITICAL("Connectivity (Tethering)");
-DISABLE_BTF_ON_USER_BUILDS();
diff --git a/bpf_progs/test.c b/bpf_progs/test.c
index 6a4471c..bce402e 100644
--- a/bpf_progs/test.c
+++ b/bpf_progs/test.c
@@ -14,10 +14,6 @@
  * limitations under the License.
  */
 
-#include <linux/if_ether.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-
 #ifdef MAINLINE
 // BTF is incompatible with bpfloaders < v0.10, hence for S (v0.2) we must
 // ship a different file than for later versions, but we need bpfloader v0.25+
@@ -29,30 +25,24 @@
 #define BPFLOADER_MAX_VER BPFLOADER_T_VERSION
 #endif /* MAINLINE */
 
-// Warning: values other than AID_ROOT don't work for map uid on BpfLoader < v0.21
-#define TETHERING_UID AID_ROOT
-
-#define TETHERING_GID AID_NETWORK_STACK
-
 // This is non production code, only used for testing
 // Needed because the bitmap array definition is non-kosher for pre-T OS devices.
 #define THIS_BPF_PROGRAM_IS_FOR_TEST_PURPOSES_ONLY
 
-#include "bpf_helpers.h"
 #include "bpf_net_helpers.h"
 #include "offload.h"
 
 // Used only by TetheringPrivilegedTests, not by production code.
 DEFINE_BPF_MAP_GRW(tether_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 16,
-                   TETHERING_GID)
+                   AID_NETWORK_STACK)
 DEFINE_BPF_MAP_GRW(tether2_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 16,
-                   TETHERING_GID)
+                   AID_NETWORK_STACK)
 DEFINE_BPF_MAP_GRW(tether3_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 16,
-                   TETHERING_GID)
+                   AID_NETWORK_STACK)
 // Used only by BpfBitmapTest, not by production code.
-DEFINE_BPF_MAP_GRW(bitmap, ARRAY, int, uint64_t, 2, TETHERING_GID)
+DEFINE_BPF_MAP_GRW(bitmap, ARRAY, int, uint64_t, 2, AID_NETWORK_STACK)
 
-DEFINE_BPF_PROG_KVER("xdp/drop_ipv4_udp_ether", TETHERING_UID, TETHERING_GID,
+DEFINE_BPF_PROG_KVER("xdp/drop_ipv4_udp_ether", AID_ROOT, AID_NETWORK_STACK,
                       xdp_test, KVER_5_9)
 (struct xdp_md *ctx) {
     void *data = (void *)(long)ctx->data;
@@ -71,4 +61,3 @@
 }
 
 LICENSE("Apache 2.0");
-DISABLE_BTF_ON_USER_BUILDS();
diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
index 9069038..c94f1d8 100644
--- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -99,23 +99,19 @@
  *
  * If missing, bpfloader_{min/max}_ver default to 0/0x10000 ie. [v0.0, v1.0),
  * while size_of_bpf_{map/prog}_def default to 32/20 which are the v0.0 sizes.
- */
-#define LICENSE(NAME)                                                                           \
-    unsigned int _bpfloader_min_ver SECTION("bpfloader_min_ver") = BPFLOADER_MIN_VER;           \
-    unsigned int _bpfloader_max_ver SECTION("bpfloader_max_ver") = BPFLOADER_MAX_VER;           \
-    size_t _size_of_bpf_map_def SECTION("size_of_bpf_map_def") = sizeof(struct bpf_map_def);    \
-    size_t _size_of_bpf_prog_def SECTION("size_of_bpf_prog_def") = sizeof(struct bpf_prog_def); \
-    char _license[] SECTION("license") = (NAME)
-
-/* This macro disables loading BTF map debug information on Android <=U *and* all user builds.
  *
- * Note: Bpfloader v0.39+ honours 'btf_user_min_bpfloader_ver' on user builds,
- * and 'btf_min_bpfloader_ver' on non-user builds.
- * Older BTF capable versions unconditionally honour 'btf_min_bpfloader_ver'
+ * This macro also disables loading BTF map debug information, as versions
+ * of the platform bpfloader that support BTF require fork-exec of btfloader
+ * which causes a regression in boot time.
  */
-#define DISABLE_BTF_ON_USER_BUILDS() \
-    unsigned _btf_min_bpfloader_ver SECTION("btf_min_bpfloader_ver") = 39u; \
-    unsigned _btf_user_min_bpfloader_ver SECTION("btf_user_min_bpfloader_ver") = 0xFFFFFFFFu
+#define LICENSE(NAME)                                                                              \
+    unsigned int _bpfloader_min_ver SECTION("bpfloader_min_ver") = BPFLOADER_MIN_VER;              \
+    unsigned int _bpfloader_max_ver SECTION("bpfloader_max_ver") = BPFLOADER_MAX_VER;              \
+    size_t _size_of_bpf_map_def SECTION("size_of_bpf_map_def") = sizeof(struct bpf_map_def);       \
+    size_t _size_of_bpf_prog_def SECTION("size_of_bpf_prog_def") = sizeof(struct bpf_prog_def);    \
+    unsigned _btf_min_bpfloader_ver SECTION("btf_min_bpfloader_ver") = BPFLOADER_MAINLINE_VERSION; \
+    unsigned _btf_user_min_bpfloader_ver SECTION("btf_user_min_bpfloader_ver") = 0xFFFFFFFFu;      \
+    char _license[] SECTION("license") = (NAME)
 
 /* flag the resulting bpf .o file as critical to system functionality,
  * loading all kernel version appropriate programs in it must succeed