summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-21 23:25:36 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-21 23:25:36 +0000
commit8cc516c798b58cd5b72f3945c76b970f623a25ab (patch)
treea5f98ac5c92695fbaa9d98b708bc4419b68d3a35
parent22e5d6402d9484ef9260d1e27a724535cf08cce0 (diff)
parent5409851f438e90beee996d4f68a0d2408c7c4414 (diff)
downloadConnectivity-8cc516c798b58cd5b72f3945c76b970f623a25ab.tar.gz
Snap for 8750474 from 5409851f438e90beee996d4f68a0d2408c7c4414 to tm-release
Change-Id: Iebe985396981ea7a2fd0c06a569340588c5e5476
-rw-r--r--bpf_progs/Android.bp5
-rw-r--r--bpf_progs/block.c4
-rw-r--r--bpf_progs/bpf_shared.h4
-rw-r--r--bpf_progs/clat_mark.h33
-rw-r--r--bpf_progs/clatd.c11
-rw-r--r--bpf_progs/dscp_policy.c4
-rw-r--r--bpf_progs/netd.c91
-rw-r--r--bpf_progs/offload.c4
-rw-r--r--bpf_progs/test.c4
-rw-r--r--netd/BpfHandler.cpp3
-rw-r--r--netd/BpfHandler.h5
-rw-r--r--netd/BpfHandlerTest.cpp8
-rw-r--r--service-t/src/com/android/server/net/NetworkStatsService.java6
-rw-r--r--service/native/TrafficControllerTest.cpp6
-rw-r--r--service/native/include/Common.h3
-rw-r--r--tests/cts/net/native/src/BpfCompatTest.cpp9
-rw-r--r--tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java25
17 files changed, 150 insertions, 75 deletions
diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp
index 45cb7eb1fb..9e516bf933 100644
--- a/bpf_progs/Android.bp
+++ b/bpf_progs/Android.bp
@@ -116,11 +116,6 @@ bpf {
"-Wall",
"-Werror",
],
- // need //frameworks/libs/net/common/netd/libnetdutils/include/netdutils/UidConstants.h
- // MIN_SYSTEM_UID, MAX_SYSTEM_UID, PER_USER_RANGE
- include_dirs: [
- "frameworks/libs/net/common/netd/libnetdutils/include",
- ],
// WARNING: Android T's non-updatable netd depends on 'netd_shared' string for xt_bpf programs
sub_dir: "netd_shared",
}
diff --git a/bpf_progs/block.c b/bpf_progs/block.c
index 601b93281e..f2a3e62a05 100644
--- a/bpf_progs/block.c
+++ b/bpf_progs/block.c
@@ -19,8 +19,8 @@
#include <netinet/in.h>
#include <stdint.h>
-// The resulting .o needs to load on the Android T bpfloader v0.12+
-#define BPFLOADER_MIN_VER 12u
+// The resulting .o needs to load on the Android T beta 3 bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
#include "bpf_helpers.h"
diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h
index dd9fb07d53..fd449a3de4 100644
--- a/bpf_progs/bpf_shared.h
+++ b/bpf_progs/bpf_shared.h
@@ -190,9 +190,9 @@ typedef struct {
STRUCT_SIZE(UidOwnerValue, 2 * 4); // 8
// Entry in the configuration map that stores which UID rules are enabled.
-#define UID_RULES_CONFIGURATION_KEY 1
+#define UID_RULES_CONFIGURATION_KEY 0
// Entry in the configuration map that stores which stats map is currently in use.
-#define CURRENT_STATS_MAP_CONFIGURATION_KEY 2
+#define CURRENT_STATS_MAP_CONFIGURATION_KEY 1
typedef struct {
uint32_t iif; // The input interface index
diff --git a/bpf_progs/clat_mark.h b/bpf_progs/clat_mark.h
new file mode 100644
index 0000000000..874d6ae3c4
--- /dev/null
+++ b/bpf_progs/clat_mark.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/* -=-=-=-=-= WARNING -=-=-=-=-=-
+ *
+ * DO *NOT* *EVER* CHANGE THIS CONSTANT
+ *
+ * This is aidl::android::net::INetd::CLAT_MARK but we can't use that from
+ * pure C code (ie. the eBPF clat program).
+ *
+ * It must match the iptables rules setup by netd on Android T.
+ *
+ * This mark value is used by the eBPF clatd program to mark ingress non-offloaded clat
+ * packets for later dropping in ip6tables bw_raw_PREROUTING.
+ * They need to be dropped *after* the clat daemon (via receive on an AF_PACKET socket)
+ * sees them and thus cannot be dropped from the bpf program itself.
+ */
+static const uint32_t CLAT_MARK = 0xDEADC1A7;
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index 87795f58ad..66e9616904 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -30,22 +30,17 @@
#define __kernel_udphdr udphdr
#include <linux/udp.h>
-// The resulting .o needs to load on the Android T bpfloader v0.12+
-#define BPFLOADER_MIN_VER 12u
+// The resulting .o needs to load on the Android T beta 3 bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
#include "bpf_shared.h"
+#include "clat_mark.h"
// From kernel:include/net/ip.h
#define IP_DF 0x4000 // Flag: "Don't Fragment"
-// Used for iptables drops ingress clat packet. Beware of clat mark change may break the device
-// which is using the old clat mark in netd platform code. The reason is that the clat mark is a
-// mainline constant since T+ but netd iptable rules (ex: bandwidth control, firewall, and so on)
-// are set in stone.
-#define CLAT_MARK 0xdeadc1a7
-
DEFINE_BPF_MAP_GRW(clat_ingress6_map, HASH, ClatIngress6Key, ClatIngress6Value, 16, AID_SYSTEM)
static inline __always_inline int nat64(struct __sk_buff* skb, bool is_ethernet) {
diff --git a/bpf_progs/dscp_policy.c b/bpf_progs/dscp_policy.c
index 7211f2b866..538a9e4e6a 100644
--- a/bpf_progs/dscp_policy.c
+++ b/bpf_progs/dscp_policy.c
@@ -27,8 +27,8 @@
#include <netinet/udp.h>
#include <string.h>
-// The resulting .o needs to load on the Android T bpfloader v0.12+
-#define BPFLOADER_MIN_VER 12u
+// The resulting .o needs to load on the Android T beta 3 bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
#include "bpf_helpers.h"
#include "dscp_policy.h"
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index e0d67e914a..24b3fed583 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-// The resulting .o needs to load on the Android T Beta 3 bpfloader v0.13+
-#define BPFLOADER_MIN_VER 13u
+// The resulting .o needs to load on the Android T Beta 3 bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
#include <bpf_helpers.h>
#include <linux/bpf.h>
@@ -28,7 +28,6 @@
#include <linux/ipv6.h>
#include <linux/pkt_cls.h>
#include <linux/tcp.h>
-#include <netdutils/UidConstants.h>
#include <stdbool.h>
#include <stdint.h>
#include "bpf_net_helpers.h"
@@ -52,28 +51,57 @@
#define TCP_FLAG_OFF 13
#define RST_OFFSET 2
-DEFINE_BPF_MAP_GRW(cookie_tag_map, HASH, uint64_t, UidTagValue, COOKIE_UID_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(uid_counterset_map, HASH, uint32_t, uint8_t, UID_COUNTERSET_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(app_uid_stats_map, HASH, uint32_t, StatsValue, APP_STATS_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(stats_map_A, HASH, StatsKey, StatsValue, STATS_MAP_SIZE, AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(stats_map_B, HASH, StatsKey, StatsValue, STATS_MAP_SIZE, AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(iface_stats_map, HASH, uint32_t, StatsValue, IFACE_STATS_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(configuration_map, HASH, uint32_t, uint32_t, CONFIGURATION_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(uid_owner_map, HASH, uint32_t, UidOwnerValue, UID_OWNER_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRW(uid_permission_map, HASH, uint32_t, uint8_t, UID_OWNER_MAP_SIZE, AID_NET_BW_ACCT)
+// For maps netd does not need to access
+#define DEFINE_BPF_MAP_NO_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
+ DEFINE_BPF_MAP_EXT(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \
+ AID_ROOT, AID_NET_BW_ACCT, 0060, "fs_bpf_net_shared", "", false)
+
+// For maps netd only needs read only access to
+#define DEFINE_BPF_MAP_RO_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
+ DEFINE_BPF_MAP_EXT(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \
+ AID_ROOT, AID_NET_BW_ACCT, 0460, "fs_bpf_netd_readonly", "", false)
+
+// For maps netd needs to be able to read and write
+#define DEFINE_BPF_MAP_RW_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
+ DEFINE_BPF_MAP_UGM(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \
+ AID_ROOT, AID_NET_BW_ACCT, 0660)
+
+// Bpf map arrays on creation are preinitialized to 0 and do not support deletion of a key,
+// see: kernel/bpf/arraymap.c array_map_delete_elem() returns -EINVAL (from both syscall and ebpf)
+// Additionally on newer kernels the bpf jit can optimize out the lookups.
+// only valid indexes are [0..CONFIGURATION_MAP_SIZE-1]
+DEFINE_BPF_MAP_RO_NETD(configuration_map, ARRAY, uint32_t, uint32_t, CONFIGURATION_MAP_SIZE)
+
+DEFINE_BPF_MAP_RW_NETD(cookie_tag_map, HASH, uint64_t, UidTagValue, COOKIE_UID_MAP_SIZE)
+DEFINE_BPF_MAP_NO_NETD(uid_counterset_map, HASH, uint32_t, uint8_t, UID_COUNTERSET_MAP_SIZE)
+DEFINE_BPF_MAP_NO_NETD(app_uid_stats_map, HASH, uint32_t, StatsValue, APP_STATS_MAP_SIZE)
+DEFINE_BPF_MAP_RW_NETD(stats_map_A, HASH, StatsKey, StatsValue, STATS_MAP_SIZE)
+DEFINE_BPF_MAP_RO_NETD(stats_map_B, HASH, StatsKey, StatsValue, STATS_MAP_SIZE)
+DEFINE_BPF_MAP_NO_NETD(iface_stats_map, HASH, uint32_t, StatsValue, IFACE_STATS_MAP_SIZE)
+DEFINE_BPF_MAP_NO_NETD(uid_owner_map, HASH, uint32_t, UidOwnerValue, UID_OWNER_MAP_SIZE)
+DEFINE_BPF_MAP_RW_NETD(uid_permission_map, HASH, uint32_t, uint8_t, UID_OWNER_MAP_SIZE)
/* never actually used from ebpf */
-DEFINE_BPF_MAP_GRW(iface_index_name_map, HASH, uint32_t, IfaceValue, IFACE_INDEX_NAME_MAP_SIZE,
- AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_NO_NETD(iface_index_name_map, HASH, uint32_t, IfaceValue, IFACE_INDEX_NAME_MAP_SIZE)
+
+// iptables xt_bpf programs need to be usable by both netd and netutils_wrappers
+#define DEFINE_XTBPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+ DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog)
+
+// programs that need to be usable by netd, but not by netutils_wrappers
+#define DEFINE_NETD_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+ DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, \
+ KVER_NONE, KVER_INF, false, "fs_bpf_netd_readonly", "")
+
+// programs that only need to be usable by the system server
+#define DEFINE_SYS_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+ DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, \
+ KVER_NONE, KVER_INF, false, "fs_bpf_net_shared", "")
static __always_inline int is_system_uid(uint32_t uid) {
- return (uid <= MAX_SYSTEM_UID) && (uid >= MIN_SYSTEM_UID);
+ // MIN_SYSTEM_UID is AID_ROOT == 0, so uint32_t is *always* >= 0
+ // MAX_SYSTEM_UID is AID_NOBODY == 9999, while AID_APP_START == 10000
+ return (uid < AID_APP_START);
}
/*
@@ -316,18 +344,18 @@ static __always_inline inline int bpf_traffic_account(struct __sk_buff* skb, int
return match;
}
-DEFINE_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_ingress)
+DEFINE_NETD_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_ingress)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, BPF_INGRESS);
}
-DEFINE_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_egress)
+DEFINE_NETD_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_egress)
(struct __sk_buff* skb) {
return bpf_traffic_account(skb, BPF_EGRESS);
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_prog)
+DEFINE_XTBPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_prog)
(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,
@@ -347,7 +375,7 @@ DEFINE_BPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingress_prog)
+DEFINE_XTBPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingress_prog)
(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).
@@ -359,7 +387,8 @@ DEFINE_BPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingres
return BPF_MATCH;
}
-DEFINE_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN, tc_bpf_ingress_account_prog)
+DEFINE_SYS_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN,
+ tc_bpf_ingress_account_prog)
(struct __sk_buff* skb) {
if (is_received_skb(skb)) {
// Account for ingress traffic before tc drops it.
@@ -370,7 +399,7 @@ DEFINE_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN, tc_bpf_ingr
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allowlist_prog)
+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;
@@ -388,7 +417,7 @@ DEFINE_BPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allo
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denylist_prog)
+DEFINE_XTBPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denylist_prog)
(struct __sk_buff* skb) {
uint32_t sock_uid = bpf_get_socket_uid(skb);
UidOwnerValue* denylistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
@@ -396,8 +425,8 @@ DEFINE_BPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denyl
return BPF_NOMATCH;
}
-DEFINE_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create,
- KVER(4, 14, 0))
+DEFINE_BPF_PROG_EXT("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create,
+ KVER(4, 14, 0), KVER_INF, false, "fs_bpf_netd_readonly", "")
(struct bpf_sock* sk) {
uint64_t gid_uid = bpf_get_current_uid_gid();
/*
@@ -406,7 +435,7 @@ DEFINE_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_c
* user at install time so we only check the appId part of a request uid at
* run time. See UserHandle#isSameApp for detail.
*/
- uint32_t appId = (gid_uid & 0xffffffff) % PER_USER_RANGE;
+ uint32_t appId = (gid_uid & 0xffffffff) % AID_USER_OFFSET; // == PER_USER_RANGE == 100000
uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&appId);
if (!permissions) {
// UID not in map. Default to just INTERNET permission.
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index 896bc09a32..2ec0792172 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -24,8 +24,8 @@
#define __kernel_udphdr udphdr
#include <linux/udp.h>
-// The resulting .o needs to load on the Android S bpfloader v0.2
-#define BPFLOADER_MIN_VER 2u
+// The resulting .o needs to load on the Android S bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_S_VERSION
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
diff --git a/bpf_progs/test.c b/bpf_progs/test.c
index c9c73f15c9..f2fcc8c86f 100644
--- a/bpf_progs/test.c
+++ b/bpf_progs/test.c
@@ -18,8 +18,8 @@
#include <linux/in.h>
#include <linux/ip.h>
-// The resulting .o needs to load on the Android S bpfloader v0.2
-#define BPFLOADER_MIN_VER 2u
+// The resulting .o needs to load on the Android S bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_S_VERSION
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index f3dfb57cde..6ae26c38f1 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -110,8 +110,6 @@ Status BpfHandler::initMaps() {
RETURN_IF_NOT_OK(mStatsMapA.init(STATS_MAP_A_PATH));
RETURN_IF_NOT_OK(mStatsMapB.init(STATS_MAP_B_PATH));
RETURN_IF_NOT_OK(mConfigurationMap.init(CONFIGURATION_MAP_PATH));
- RETURN_IF_NOT_OK(mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY, SELECT_MAP_A,
- BPF_ANY));
RETURN_IF_NOT_OK(mUidPermissionMap.init(UID_PERMISSION_MAP_PATH));
return netdutils::status::ok;
@@ -207,6 +205,7 @@ int BpfHandler::tagSocket(int sockFd, uint32_t tag, uid_t chargeUid, uid_t realU
BpfMap<StatsKey, StatsValue>& currentMap =
(configuration.value() == SELECT_MAP_A) ? mStatsMapA : mStatsMapB;
+ // HACK: mStatsMapB becomes RW BpfMap here, but countUidStatsEntries doesn't modify so it works
base::Result<void> res = currentMap.iterate(countUidStatsEntries);
if (!res.ok()) {
ALOGE("Failed to count the stats entry in map %d: %s", currentMap.getMap().get(),
diff --git a/netd/BpfHandler.h b/netd/BpfHandler.h
index 05b9ebc81d..5ee04d1a53 100644
--- a/netd/BpfHandler.h
+++ b/netd/BpfHandler.h
@@ -23,6 +23,7 @@
#include "bpf_shared.h"
using android::bpf::BpfMap;
+using android::bpf::BpfMapRO;
namespace android {
namespace net {
@@ -61,8 +62,8 @@ class BpfHandler {
BpfMap<uint64_t, UidTagValue> mCookieTagMap;
BpfMap<StatsKey, StatsValue> mStatsMapA;
- BpfMap<StatsKey, StatsValue> mStatsMapB;
- BpfMap<uint32_t, uint32_t> mConfigurationMap;
+ BpfMapRO<StatsKey, StatsValue> mStatsMapB;
+ BpfMapRO<uint32_t, uint32_t> mConfigurationMap;
BpfMap<uint32_t, uint8_t> mUidPermissionMap;
std::mutex mMutex;
diff --git a/netd/BpfHandlerTest.cpp b/netd/BpfHandlerTest.cpp
index 1bd222dfce..a031dbb9e6 100644
--- a/netd/BpfHandlerTest.cpp
+++ b/netd/BpfHandlerTest.cpp
@@ -49,7 +49,7 @@ class BpfHandlerTest : public ::testing::Test {
BpfHandler mBh;
BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
BpfMap<StatsKey, StatsValue> mFakeStatsMapA;
- BpfMap<uint32_t, uint32_t> mFakeConfigurationMap;
+ BpfMapRO<uint32_t, uint32_t> mFakeConfigurationMap;
BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;
void SetUp() {
@@ -62,7 +62,7 @@ class BpfHandlerTest : public ::testing::Test {
mFakeStatsMapA.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_VALID(mFakeStatsMapA);
- mFakeConfigurationMap.resetMap(BPF_MAP_TYPE_HASH, 1);
+ mFakeConfigurationMap.resetMap(BPF_MAP_TYPE_ARRAY, CONFIGURATION_MAP_SIZE);
ASSERT_VALID(mFakeConfigurationMap);
mFakeUidPermissionMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
@@ -75,8 +75,8 @@ class BpfHandlerTest : public ::testing::Test {
mBh.mConfigurationMap = mFakeConfigurationMap;
ASSERT_VALID(mBh.mConfigurationMap);
// Always write to stats map A by default.
- ASSERT_RESULT_OK(mBh.mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY,
- SELECT_MAP_A, BPF_ANY));
+ static_assert(SELECT_MAP_A == 0, "bpf map arrays are zero-initialized");
+
mBh.mUidPermissionMap = mFakeUidPermissionMap;
ASSERT_VALID(mBh.mUidPermissionMap);
}
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index b955db9f02..4f0f3411a5 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -1126,9 +1126,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} catch (Resources.NotFoundException e) {
// Overlay value is not defined.
}
- // TODO(b/233752318): For now it is always true to collect signal from beta users.
- // Should change to the default behavior (true if debuggable builds) before formal release.
- return (overlayValue != null ? overlayValue : mDeps.isDebuggable()) || true;
+ return overlayValue != null ? overlayValue : mDeps.isDebuggable();
}
/**
@@ -1154,10 +1152,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
if (error != null) {
Log.wtf(TAG, "Unexpected comparison result for recorder "
+ legacyRecorder.getCookie() + ": " + error);
+ return false;
}
} catch (Throwable e) {
Log.wtf(TAG, "Failed to compare migrated stats with legacy stats for recorder "
+ legacyRecorder.getCookie(), e);
+ return false;
}
return true;
}
diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp
index c920398078..9e53f11d0d 100644
--- a/service/native/TrafficControllerTest.cpp
+++ b/service/native/TrafficControllerTest.cpp
@@ -83,7 +83,7 @@ class TrafficControllerTest : public ::testing::Test {
mFakeStatsMapA.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_VALID(mFakeStatsMapA);
- mFakeConfigurationMap.resetMap(BPF_MAP_TYPE_HASH, 1);
+ mFakeConfigurationMap.resetMap(BPF_MAP_TYPE_ARRAY, CONFIGURATION_MAP_SIZE);
ASSERT_VALID(mFakeConfigurationMap);
mFakeUidOwnerMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
@@ -101,8 +101,8 @@ class TrafficControllerTest : public ::testing::Test {
ASSERT_VALID(mTc.mConfigurationMap);
// Always write to stats map A by default.
- ASSERT_RESULT_OK(mTc.mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY,
- SELECT_MAP_A, BPF_ANY));
+ static_assert(SELECT_MAP_A == 0);
+
mTc.mUidOwnerMap = mFakeUidOwnerMap;
ASSERT_VALID(mTc.mUidOwnerMap);
mTc.mUidPermissionMap = mFakeUidPermissionMap;
diff --git a/service/native/include/Common.h b/service/native/include/Common.h
index 2427aa906c..c9653adafe 100644
--- a/service/native/include/Common.h
+++ b/service/native/include/Common.h
@@ -17,9 +17,12 @@
#pragma once
// TODO: deduplicate with the constants in NetdConstants.h.
#include <aidl/android/net/INetd.h>
+#include "clat_mark.h"
using aidl::android::net::INetd;
+static_assert(INetd::CLAT_MARK == CLAT_MARK, "must be 0xDEADC1A7");
+
enum FirewallRule { ALLOW = INetd::FIREWALL_RULE_ALLOW, DENY = INetd::FIREWALL_RULE_DENY };
// ALLOWLIST means the firewall denies all by default, uids must be explicitly ALLOWed
diff --git a/tests/cts/net/native/src/BpfCompatTest.cpp b/tests/cts/net/native/src/BpfCompatTest.cpp
index 97ecb9e217..e52533b51f 100644
--- a/tests/cts/net/native/src/BpfCompatTest.cpp
+++ b/tests/cts/net/native/src/BpfCompatTest.cpp
@@ -31,8 +31,13 @@ void doBpfStructSizeTest(const char *elfPath) {
std::ifstream elfFile(elfPath, std::ios::in | std::ios::binary);
ASSERT_TRUE(elfFile.is_open());
- EXPECT_EQ(48, readSectionUint("size_of_bpf_map_def", elfFile, 0));
- EXPECT_EQ(28, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+ if (android::modules::sdklevel::IsAtLeastT()) {
+ EXPECT_EQ(116, readSectionUint("size_of_bpf_map_def", elfFile, 0));
+ EXPECT_EQ(92, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+ } else {
+ EXPECT_EQ(48, readSectionUint("size_of_bpf_map_def", elfFile, 0));
+ EXPECT_EQ(28, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+ }
}
TEST(BpfTest, bpfStructSizeTestPreT) {
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index a7c5877f31..e03b4fe194 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -2000,15 +2000,30 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
@Test
public void testShouldRunComparison() {
- // TODO(b/233752318): For now it should always true to collect signal from beta users.
- // Should change to the default behavior (true if userdebug rom) before formal release.
- for (int testValue : Set.of(-1, 0, 1, 2)) {
- doReturn(testValue).when(mResources)
+ for (Boolean isDebuggable : Set.of(Boolean.TRUE, Boolean.FALSE)) {
+ mIsDebuggable = isDebuggable;
+ // Verify return false regardless of the device is debuggable.
+ doReturn(0).when(mResources)
.getInteger(R.integer.config_netstats_validate_import);
- assertEquals(true, mService.shouldRunComparison());
+ assertShouldRunComparison(false, isDebuggable);
+ // Verify return true regardless of the device is debuggable.
+ doReturn(1).when(mResources)
+ .getInteger(R.integer.config_netstats_validate_import);
+ assertShouldRunComparison(true, isDebuggable);
+ // Verify return true iff the device is debuggable.
+ for (int testValue : Set.of(-1, 2)) {
+ doReturn(testValue).when(mResources)
+ .getInteger(R.integer.config_netstats_validate_import);
+ assertShouldRunComparison(isDebuggable, isDebuggable);
+ }
}
}
+ private void assertShouldRunComparison(boolean expected, boolean isDebuggable) {
+ assertEquals("shouldRunComparison (debuggable=" + isDebuggable + "): ",
+ expected, mService.shouldRunComparison());
+ }
+
private NetworkStatsRecorder makeTestRecorder(File directory, String prefix, Config config,
boolean includeTags, boolean wipeOnError) {
final NetworkStats.NonMonotonicObserver observer =