Merge "Add mainline module controller for tethering" into main
diff --git a/bpf/headers/include/bpf_helpers.h b/bpf/headers/include/bpf_helpers.h
index c94f1d8..ca0ca76 100644
--- a/bpf/headers/include/bpf_helpers.h
+++ b/bpf/headers/include/bpf_helpers.h
@@ -383,13 +383,17 @@
static int (*bpf_probe_read_user_str)(void* dst, int size, const void* unsafe_ptr) = (void*) BPF_FUNC_probe_read_user_str;
static unsigned long long (*bpf_ktime_get_ns)(void) = (void*) BPF_FUNC_ktime_get_ns;
static unsigned long long (*bpf_ktime_get_boot_ns)(void) = (void*)BPF_FUNC_ktime_get_boot_ns;
-static int (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BPF_FUNC_trace_printk;
static unsigned long long (*bpf_get_current_pid_tgid)(void) = (void*) BPF_FUNC_get_current_pid_tgid;
static unsigned long long (*bpf_get_current_uid_gid)(void) = (void*) BPF_FUNC_get_current_uid_gid;
static unsigned long long (*bpf_get_smp_processor_id)(void) = (void*) BPF_FUNC_get_smp_processor_id;
static long (*bpf_get_stackid)(void* ctx, void* map, uint64_t flags) = (void*) BPF_FUNC_get_stackid;
static long (*bpf_get_current_comm)(void* buf, uint32_t buf_size) = (void*) BPF_FUNC_get_current_comm;
+static int (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BPF_FUNC_trace_printk;
+#define bpf_printf(s, n...) bpf_trace_printk(s, sizeof(s), ## n)
+// Note: bpf only supports up to 3 arguments, log via: bpf_printf("msg %d %d %d", 1, 2, 3);
+// and read via the blocking: sudo cat /sys/kernel/debug/tracing/trace_pipe
+
#define DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
min_loader, max_loader, opt, selinux, pindir, ignore_eng, \
ignore_user, ignore_userdebug) \
diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp
index 59712b1..c058433 100644
--- a/bpf/loader/NetBpfLoad.cpp
+++ b/bpf/loader/NetBpfLoad.cpp
@@ -604,6 +604,9 @@
if (type == BPF_MAP_TYPE_DEVMAP || type == BPF_MAP_TYPE_DEVMAP_HASH)
desired_map_flags |= BPF_F_RDONLY_PROG;
+ if (type == BPF_MAP_TYPE_LPM_TRIE)
+ desired_map_flags |= BPF_F_NO_PREALLOC;
+
// The .h file enforces that this is a power of two, and page size will
// also always be a power of two, so this logic is actually enough to
// force it to be a multiple of the page size, as required by the kernel.
@@ -779,13 +782,17 @@
.key_size = md[i].key_size,
.value_size = md[i].value_size,
.max_entries = max_entries,
- .map_flags = md[i].map_flags,
+ .map_flags = md[i].map_flags | (type == BPF_MAP_TYPE_LPM_TRIE ? BPF_F_NO_PREALLOC : 0),
};
if (isAtLeastKernelVersion(4, 15, 0))
strlcpy(req.map_name, mapNames[i].c_str(), sizeof(req.map_name));
fd.reset(bpf(BPF_MAP_CREATE, req));
saved_errno = errno;
- ALOGD("bpf_create_map name %s, ret: %d", mapNames[i].c_str(), fd.get());
+ if (fd.ok()) {
+ ALOGD("bpf_create_map[%s] -> %d", mapNames[i].c_str(), fd.get());
+ } else {
+ ALOGE("bpf_create_map[%s] -> %d errno:%d", mapNames[i].c_str(), fd.get(), saved_errno);
+ }
}
if (!fd.ok()) return -saved_errno;
@@ -839,7 +846,8 @@
int mapId = bpfGetFdMapId(fd);
if (mapId == -1) {
- ALOGE("bpfGetFdMapId failed, ret: %d [%d]", mapId, errno);
+ if (isAtLeastKernelVersion(4, 14, 0))
+ ALOGE("bpfGetFdMapId failed, ret: %d [%d]", mapId, errno);
} else {
ALOGI("map %s id %d", mapPinLoc.c_str(), mapId);
}
@@ -1007,17 +1015,20 @@
cs[i].name.c_str(), fd.get(), (!fd.ok() ? std::strerror(errno) : "no error"));
if (!fd.ok()) {
- vector<string> lines = android::base::Split(log_buf.data(), "\n");
+ if (log_buf.size()) {
+ vector<string> lines = android::base::Split(log_buf.data(), "\n");
- ALOGW("BPF_PROG_LOAD - BEGIN log_buf contents:");
- for (const auto& line : lines) ALOGW("%s", line.c_str());
- ALOGW("BPF_PROG_LOAD - END log_buf contents.");
+ ALOGW("BPF_PROG_LOAD - BEGIN log_buf contents:");
+ for (const auto& line : lines) ALOGW("%s", line.c_str());
+ ALOGW("BPF_PROG_LOAD - END log_buf contents.");
+ }
if (cs[i].prog_def->optional) {
- ALOGW("failed program is marked optional - continuing...");
+ ALOGW("failed program %s is marked optional - continuing...",
+ cs[i].name.c_str());
continue;
}
- ALOGE("non-optional program failed to load.");
+ ALOGE("non-optional program %s failed to load.", cs[i].name.c_str());
}
}
diff --git a/bpf/loader/initrc-doc/bpfloader-sdk34-14-U-QPR3.rc b/bpf/loader/initrc-doc/bpfloader-sdk34-14-U-QPR3.rc
new file mode 100644
index 0000000..8f3f462
--- /dev/null
+++ b/bpf/loader/initrc-doc/bpfloader-sdk34-14-U-QPR3.rc
@@ -0,0 +1,11 @@
+on load_bpf_programs
+ exec_start bpfloader
+
+service bpfloader /system/bin/netbpfload
+ capabilities CHOWN SYS_ADMIN NET_ADMIN
+ group root graphics network_stack net_admin net_bw_acct net_bw_stats net_raw system
+ user root
+ rlimit memlock 1073741824 1073741824
+ oneshot
+ reboot_on_failure reboot,bpfloader-failed
+ updatable
diff --git a/bpf/loader/initrc-doc/bpfloader-sdk35-15-V.rc b/bpf/loader/initrc-doc/bpfloader-sdk35-15-V.rc
new file mode 100644
index 0000000..066cfc8
--- /dev/null
+++ b/bpf/loader/initrc-doc/bpfloader-sdk35-15-V.rc
@@ -0,0 +1,8 @@
+on load_bpf_programs
+ exec_start bpfloader
+
+service bpfloader /system/bin/false
+ user root
+ oneshot
+ reboot_on_failure reboot,netbpfload-missing
+ updatable
diff --git a/netd/Android.bp b/bpf/netd/Android.bp
similarity index 100%
rename from netd/Android.bp
rename to bpf/netd/Android.bp
diff --git a/netd/BpfBaseTest.cpp b/bpf/netd/BpfBaseTest.cpp
similarity index 100%
rename from netd/BpfBaseTest.cpp
rename to bpf/netd/BpfBaseTest.cpp
diff --git a/netd/BpfHandler.cpp b/bpf/netd/BpfHandler.cpp
similarity index 100%
rename from netd/BpfHandler.cpp
rename to bpf/netd/BpfHandler.cpp
diff --git a/netd/BpfHandler.h b/bpf/netd/BpfHandler.h
similarity index 100%
rename from netd/BpfHandler.h
rename to bpf/netd/BpfHandler.h
diff --git a/netd/BpfHandlerTest.cpp b/bpf/netd/BpfHandlerTest.cpp
similarity index 100%
rename from netd/BpfHandlerTest.cpp
rename to bpf/netd/BpfHandlerTest.cpp
diff --git a/netd/NetdUpdatable.cpp b/bpf/netd/NetdUpdatable.cpp
similarity index 100%
rename from netd/NetdUpdatable.cpp
rename to bpf/netd/NetdUpdatable.cpp
diff --git a/netd/include/NetdUpdatablePublic.h b/bpf/netd/include/NetdUpdatablePublic.h
similarity index 100%
rename from netd/include/NetdUpdatablePublic.h
rename to bpf/netd/include/NetdUpdatablePublic.h
diff --git a/netd/libnetd_updatable.map.txt b/bpf/netd/libnetd_updatable.map.txt
similarity index 100%
rename from netd/libnetd_updatable.map.txt
rename to bpf/netd/libnetd_updatable.map.txt
diff --git a/bpf/progs/Android.bp b/bpf/progs/Android.bp
index f6717c5..dc1f56d 100644
--- a/bpf/progs/Android.bp
+++ b/bpf/progs/Android.bp
@@ -47,8 +47,8 @@
"com.android.tethering",
],
visibility: [
+ "//packages/modules/Connectivity/bpf/netd",
"//packages/modules/Connectivity/DnsResolver",
- "//packages/modules/Connectivity/netd",
"//packages/modules/Connectivity/service",
"//packages/modules/Connectivity/service/native/libs/libclat",
"//packages/modules/Connectivity/Tethering",
diff --git a/bpf/progs/dscpPolicy.c b/bpf/progs/dscpPolicy.c
index baabb02..39f2961 100644
--- a/bpf/progs/dscpPolicy.c
+++ b/bpf/progs/dscpPolicy.c
@@ -23,7 +23,10 @@
#define ECN_MASK 3
#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)
+// The cache is never read nor written by userspace and is indexed by socket cookie % CACHE_MAP_SIZE
+#define CACHE_MAP_SIZE 32 // should be a power of two so we can % cheaply
+DEFINE_BPF_MAP_GRO(socket_policy_cache_map, PERCPU_ARRAY, uint32_t, RuleEntry, CACHE_MAP_SIZE,
+ AID_SYSTEM)
DEFINE_BPF_MAP_GRW(ipv4_dscp_policies_map, ARRAY, uint32_t, DscpPolicy, MAX_POLICIES, AID_SYSTEM)
DEFINE_BPF_MAP_GRW(ipv6_dscp_policies_map, ARRAY, uint32_t, DscpPolicy, MAX_POLICIES, AID_SYSTEM)
@@ -43,6 +46,8 @@
uint64_t cookie = bpf_get_socket_cookie(skb);
if (!cookie) return;
+ uint32_t cacheid = cookie % CACHE_MAP_SIZE;
+
__be16 sport = 0;
uint16_t dport = 0;
uint8_t protocol = 0; // TODO: Use are reserved value? Or int (-1) and cast to uint below?
@@ -105,7 +110,8 @@
return;
}
- RuleEntry* existing_rule = bpf_socket_policy_cache_map_lookup_elem(&cookie);
+ // this array lookup cannot actually fail
+ RuleEntry* existing_rule = bpf_socket_policy_cache_map_lookup_elem(&cacheid);
if (existing_rule &&
v6_equal(src_ip, existing_rule->src_ip) &&
@@ -192,7 +198,7 @@
};
// Update cache with found policy.
- bpf_socket_policy_cache_map_update_elem(&cookie, &value, BPF_ANY);
+ bpf_socket_policy_cache_map_update_elem(&cacheid, &value, BPF_ANY);
if (new_dscp < 0) return;
diff --git a/bpf/progs/dscpPolicy.h b/bpf/progs/dscpPolicy.h
index dc431a7..6a6b711 100644
--- a/bpf/progs/dscpPolicy.h
+++ b/bpf/progs/dscpPolicy.h
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#define CACHE_MAP_SIZE 1024
#define MAX_POLICIES 16
#define STRUCT_SIZE(name, size) _Static_assert(sizeof(name) == (size), "Incorrect struct size.")
diff --git a/common/flags.aconfig b/common/flags.aconfig
index 45cbb78..4c6d8ba 100644
--- a/common/flags.aconfig
+++ b/common/flags.aconfig
@@ -147,3 +147,12 @@
bug: "335680025"
is_fixed_read_only: true
}
+
+flag {
+ name: "tethering_active_sessions_metrics"
+ is_exported: true
+ namespace: "android_core_networking"
+ description: "Flag for collecting tethering active sessions metrics"
+ bug: "354619988"
+ is_fixed_read_only: true
+}
diff --git a/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp b/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp
index 450f380..241d5fa 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp
@@ -39,7 +39,7 @@
uint32_t poll_ms) {
// Always schedule another run of ourselves to recursively poll periodically.
// The task runner is sequential so these can't run on top of each other.
- runner->PostDelayedTask([=]() { PollAndSchedule(runner, poll_ms); }, poll_ms);
+ runner->PostDelayedTask([=, this]() { PollAndSchedule(runner, poll_ms); }, poll_ms);
if (mMutex.try_lock()) {
ConsumeAllLocked();
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 53b1eb2..9af250b 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -4439,9 +4439,8 @@
pw.println();
pw.println("Multicast routing supported: " +
(mMulticastRoutingCoordinatorService != null));
-
- pw.println();
pw.println("Background firewall chain enabled: " + mBackgroundFirewallChainEnabled);
+ pw.println("IngressToVpnAddressFiltering: " + mIngressToVpnAddressFiltering);
}
private void dumpNetworks(IndentingPrintWriter pw) {
diff --git a/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java b/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java
index 0426ace..04ce2fa 100644
--- a/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java
+++ b/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java
@@ -22,6 +22,7 @@
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
import static com.android.net.module.util.FeatureVersions.CONNECTIVITY_MODULE_ID;
+import static com.android.net.module.util.FeatureVersions.DNS_RESOLVER_MODULE_ID;
import static com.android.net.module.util.FeatureVersions.MODULE_MASK;
import static com.android.net.module.util.FeatureVersions.NETWORK_STACK_MODULE_ID;
import static com.android.net.module.util.FeatureVersions.VERSION_MASK;
@@ -68,7 +69,8 @@
@VisibleForTesting
public static void resetPackageVersionCacheForTest() {
sPackageVersion = -1;
- sModuleVersion = -1;
+ sTetheringModuleVersion = -1;
+ sResolvModuleVersion = -1;
sNetworkStackModuleVersion = -1;
}
@@ -243,23 +245,23 @@
}
}
- // Guess the tethering module name based on the package prefix of the connectivity resources
- // Take the resource package name, cut it before "connectivity" and append "tethering".
+ // Guess an APEX module name based on the package prefix of the connectivity resources
+ // Take the resource package name, cut it before "connectivity" and append the module name.
// Then resolve that package version number with packageManager.
- // If that fails retry by appending "go.tethering" instead
- private static long resolveTetheringModuleVersion(@NonNull Context context)
+ // If that fails retry by appending "go.<moduleName>" instead.
+ private static long resolveApexModuleVersion(@NonNull Context context, String moduleName)
throws PackageManager.NameNotFoundException {
final String pkgPrefix = resolvePkgPrefix(context);
final PackageManager packageManager = context.getPackageManager();
try {
- return packageManager.getPackageInfo(pkgPrefix + "tethering",
+ return packageManager.getPackageInfo(pkgPrefix + moduleName,
PackageManager.MATCH_APEX).getLongVersionCode();
} catch (PackageManager.NameNotFoundException e) {
Log.d(TAG, "Device is using go modules");
// fall through
}
- return packageManager.getPackageInfo(pkgPrefix + "go.tethering",
+ return packageManager.getPackageInfo(pkgPrefix + "go." + moduleName,
PackageManager.MATCH_APEX).getLongVersionCode();
}
@@ -274,19 +276,35 @@
return connResourcesPackage.substring(0, pkgPrefixLen);
}
- private static volatile long sModuleVersion = -1;
+ private static volatile long sTetheringModuleVersion = -1;
+
private static long getTetheringModuleVersion(@NonNull Context context) {
- if (sModuleVersion >= 0) return sModuleVersion;
+ if (sTetheringModuleVersion >= 0) return sTetheringModuleVersion;
try {
- sModuleVersion = resolveTetheringModuleVersion(context);
+ sTetheringModuleVersion = resolveApexModuleVersion(context, "tethering");
} catch (PackageManager.NameNotFoundException e) {
// It's expected to fail tethering module version resolution on the devices with
// flattened apex
Log.e(TAG, "Failed to resolve tethering module version: " + e);
return DEFAULT_PACKAGE_VERSION;
}
- return sModuleVersion;
+ return sTetheringModuleVersion;
+ }
+
+ private static volatile long sResolvModuleVersion = -1;
+ private static long getResolvModuleVersion(@NonNull Context context) {
+ if (sResolvModuleVersion >= 0) return sResolvModuleVersion;
+
+ try {
+ sResolvModuleVersion = resolveApexModuleVersion(context, "resolv");
+ } catch (PackageManager.NameNotFoundException e) {
+ // It's expected to fail resolv module version resolution on the devices with
+ // flattened apex
+ Log.e(TAG, "Failed to resolve resolv module version: " + e);
+ return DEFAULT_PACKAGE_VERSION;
+ }
+ return sResolvModuleVersion;
}
private static volatile long sNetworkStackModuleVersion = -1;
@@ -342,6 +360,8 @@
moduleVersion = getTetheringModuleVersion(context);
} else if (moduleId == NETWORK_STACK_MODULE_ID) {
moduleVersion = getNetworkStackModuleVersion(context);
+ } else if (moduleId == DNS_RESOLVER_MODULE_ID) {
+ moduleVersion = getResolvModuleVersion(context);
} else {
throw new IllegalArgumentException("Unknown module " + moduleId);
}
diff --git a/staticlibs/device/com/android/net/module/util/FeatureVersions.java b/staticlibs/device/com/android/net/module/util/FeatureVersions.java
index d5f8124..d0cf3fd 100644
--- a/staticlibs/device/com/android/net/module/util/FeatureVersions.java
+++ b/staticlibs/device/com/android/net/module/util/FeatureVersions.java
@@ -37,6 +37,7 @@
public static final long VERSION_MASK = 0x00F_FFFF_FFFFL;
public static final long CONNECTIVITY_MODULE_ID = 0x01L << MODULE_SHIFT;
public static final long NETWORK_STACK_MODULE_ID = 0x02L << MODULE_SHIFT;
+ public static final long DNS_RESOLVER_MODULE_ID = 0x03L << MODULE_SHIFT;
// CLAT_ADDRESS_TRANSLATE is a feature of the network stack, which doesn't throw when system
// try to add a NAT-T keepalive packet filter with v6 address, introduced in version
// M-2023-Sept on July 3rd, 2023.
@@ -48,4 +49,11 @@
// by BPF for the given uid and conditions, introduced in version M-2024-Feb on Nov 6, 2023.
public static final long FEATURE_IS_UID_NETWORKING_BLOCKED =
CONNECTIVITY_MODULE_ID + 34_14_00_000L;
+
+ // DDR is a feature implemented across NetworkStack, ConnectivityService and DnsResolver.
+ // The flag that enables this feature is in NetworkStack.
+ public static final long FEATURE_DDR_IN_CONNECTIVITY =
+ CONNECTIVITY_MODULE_ID + 35_11_00_000L;
+ public static final long FEATURE_DDR_IN_DNSRESOLVER =
+ DNS_RESOLVER_MODULE_ID + 35_11_00_000L;
}
diff --git a/staticlibs/framework/com/android/net/module/util/LocationPermissionChecker.java b/staticlibs/framework/com/android/net/module/util/LocationPermissionChecker.java
index f6bee69..28c33f3 100644
--- a/staticlibs/framework/com/android/net/module/util/LocationPermissionChecker.java
+++ b/staticlibs/framework/com/android/net/module/util/LocationPermissionChecker.java
@@ -16,6 +16,8 @@
package com.android.net.module.util;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.Nullable;
@@ -112,47 +114,9 @@
*
* @return {@link LocationPermissionCheckStatus} the result of the location permission check.
*/
- public @LocationPermissionCheckStatus int checkLocationPermissionWithDetailInfo(
+ @VisibleForTesting(visibility = PRIVATE)
+ public @LocationPermissionCheckStatus int checkLocationPermissionInternal(
String pkgName, @Nullable String featureId, int uid, @Nullable String message) {
- final int result = checkLocationPermissionInternal(pkgName, featureId, uid, message);
- switch (result) {
- case ERROR_LOCATION_MODE_OFF:
- Log.e(TAG, "Location mode is disabled for the device");
- break;
- case ERROR_LOCATION_PERMISSION_MISSING:
- Log.e(TAG, "UID " + uid + " has no location permission");
- break;
- }
- return result;
- }
-
- /**
- * Enforce the caller has location permission.
- *
- * This API determines if the location mode enabled for the caller and the caller has
- * ACCESS_COARSE_LOCATION permission is targetSDK<29, otherwise, has ACCESS_FINE_LOCATION.
- * SecurityException is thrown if the caller has no permission or the location mode is disabled.
- *
- * @param pkgName package name of the application requesting access
- * @param featureId The feature in the package
- * @param uid The uid of the package
- * @param message A message describing why the permission was checked. Only needed if this is
- * not inside of a two-way binder call from the data receiver
- */
- public void enforceLocationPermission(String pkgName, @Nullable String featureId, int uid,
- @Nullable String message) throws SecurityException {
- final int result = checkLocationPermissionInternal(pkgName, featureId, uid, message);
-
- switch (result) {
- case ERROR_LOCATION_MODE_OFF:
- throw new SecurityException("Location mode is disabled for the device");
- case ERROR_LOCATION_PERMISSION_MISSING:
- throw new SecurityException("UID " + uid + " has no location permission");
- }
- }
-
- private int checkLocationPermissionInternal(String pkgName, @Nullable String featureId,
- int uid, @Nullable String message) {
checkPackage(uid, pkgName);
// Apps with NETWORK_SETTINGS, NETWORK_SETUP_WIZARD, NETWORK_STACK & MAINLINE_NETWORK_STACK
@@ -221,7 +185,7 @@
/**
* Retrieves a handle to LocationManager (if not already done) and check if location is enabled.
*/
- public boolean isLocationModeEnabled() {
+ private boolean isLocationModeEnabled() {
final LocationManager LocationManager = mContext.getSystemService(LocationManager.class);
try {
return LocationManager.isLocationEnabledForUser(UserHandle.of(
@@ -278,7 +242,7 @@
/**
* Returns true if the |uid| holds NETWORK_SETTINGS permission.
*/
- public boolean checkNetworkSettingsPermission(int uid) {
+ private boolean checkNetworkSettingsPermission(int uid) {
return getUidPermission(android.Manifest.permission.NETWORK_SETTINGS, uid)
== PackageManager.PERMISSION_GRANTED;
}
@@ -286,7 +250,7 @@
/**
* Returns true if the |uid| holds NETWORK_SETUP_WIZARD permission.
*/
- public boolean checkNetworkSetupWizardPermission(int uid) {
+ private boolean checkNetworkSetupWizardPermission(int uid) {
return getUidPermission(android.Manifest.permission.NETWORK_SETUP_WIZARD, uid)
== PackageManager.PERMISSION_GRANTED;
}
@@ -294,7 +258,7 @@
/**
* Returns true if the |uid| holds NETWORK_STACK permission.
*/
- public boolean checkNetworkStackPermission(int uid) {
+ private boolean checkNetworkStackPermission(int uid) {
return getUidPermission(android.Manifest.permission.NETWORK_STACK, uid)
== PackageManager.PERMISSION_GRANTED;
}
@@ -302,7 +266,7 @@
/**
* Returns true if the |uid| holds MAINLINE_NETWORK_STACK permission.
*/
- public boolean checkMainlineNetworkStackPermission(int uid) {
+ private boolean checkMainlineNetworkStackPermission(int uid) {
return getUidPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, uid)
== PackageManager.PERMISSION_GRANTED;
}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java
index 9fb61d9..a5af09b 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java
@@ -24,6 +24,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.net.module.util.FeatureVersions.CONNECTIVITY_MODULE_ID;
+import static com.android.net.module.util.FeatureVersions.DNS_RESOLVER_MODULE_ID;
import static com.android.net.module.util.FeatureVersions.NETWORK_STACK_MODULE_ID;
import static org.junit.Assert.assertEquals;
@@ -77,7 +78,9 @@
private static final int TEST_DEFAULT_FLAG_VALUE = 0;
private static final int TEST_MAX_FLAG_VALUE = 1000;
private static final int TEST_MIN_FLAG_VALUE = 100;
- private static final long TEST_PACKAGE_VERSION = 290000000;
+ private static final long TEST_PACKAGE_VERSION = 290500000;
+ private static final long TEST_GO_PACKAGE_VERSION = 290000000; // Not updated
+ private static final long TEST_RESOLV_PACKAGE_VERSION = 290300000; // Updated, but older.
private static final String TEST_PACKAGE_NAME = "test.package.name";
// The APEX name is the name of the APEX module, as in android.content.pm.ModuleInfo, and is
// used for its mount point in /apex. APEX packages are actually APKs with a different
@@ -85,14 +88,18 @@
// that manifest, and is reflected in android.content.pm.ApplicationInfo. Contrary to the APEX
// (module) name, different package names are typically used to identify the organization that
// built and signed the APEX modules.
- private static final String TEST_APEX_PACKAGE_NAME = "com.prefix.android.tethering";
- private static final String TEST_GO_APEX_PACKAGE_NAME = "com.prefix.android.go.tethering";
+ private static final String TEST_TETHERING_PACKAGE_NAME = "com.prefix.android.tethering";
+ private static final String TEST_GO_TETHERING_PACKAGE_NAME = "com.prefix.android.go.tethering";
+ private static final String TEST_RESOLV_PACKAGE_NAME = "com.prefix.android.resolv";
+ private static final String TEST_GO_RESOLV_PACKAGE_NAME = "com.prefix.android.go.resolv";
private static final String TEST_CONNRES_PACKAGE_NAME =
"com.prefix.android.connectivity.resources";
private static final String TEST_NETWORKSTACK_NAME = "com.prefix.android.networkstack";
private static final String TEST_GO_NETWORKSTACK_NAME = "com.prefix.android.go.networkstack";
private final PackageInfo mPackageInfo = new PackageInfo();
- private final PackageInfo mApexPackageInfo = new PackageInfo();
+ private final PackageInfo mGoApexPackageInfo = new PackageInfo();
+ private final PackageInfo mTetheringApexPackageInfo = new PackageInfo();
+ private final PackageInfo mResolvApexPackageInfo = new PackageInfo();
private MockitoSession mSession;
@Mock private Context mContext;
@@ -105,13 +112,22 @@
mSession = mockitoSession().spyStatic(DeviceConfig.class).startMocking();
mPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION);
- mApexPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION);
+ mTetheringApexPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION);
+ mGoApexPackageInfo.setLongVersionCode(TEST_GO_PACKAGE_VERSION);
+ mResolvApexPackageInfo.setLongVersionCode(TEST_RESOLV_PACKAGE_VERSION);
doReturn(mPm).when(mContext).getPackageManager();
doReturn(TEST_PACKAGE_NAME).when(mContext).getPackageName();
doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(anyString(), anyInt());
doReturn(mPackageInfo).when(mPm).getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt());
- doReturn(mApexPackageInfo).when(mPm).getPackageInfo(eq(TEST_APEX_PACKAGE_NAME), anyInt());
+ doReturn(mTetheringApexPackageInfo).when(mPm).getPackageInfo(
+ eq(TEST_TETHERING_PACKAGE_NAME), anyInt());
+ doReturn(mResolvApexPackageInfo).when(mPm).getPackageInfo(eq(TEST_RESOLV_PACKAGE_NAME),
+ anyInt());
+ doReturn(mGoApexPackageInfo).when(mPm).getPackageInfo(eq(TEST_GO_TETHERING_PACKAGE_NAME),
+ anyInt());
+ doReturn(mGoApexPackageInfo).when(mPm).getPackageInfo(eq(TEST_GO_RESOLV_PACKAGE_NAME),
+ anyInt());
doReturn(mResources).when(mContext).getResources();
@@ -342,9 +358,9 @@
@Test
public void testFeatureIsEnabledOnGo() throws Exception {
doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(
- eq(TEST_APEX_PACKAGE_NAME), anyInt());
- doReturn(mApexPackageInfo).when(mPm).getPackageInfo(
- eq(TEST_GO_APEX_PACKAGE_NAME), anyInt());
+ eq(TEST_TETHERING_PACKAGE_NAME), anyInt());
+ doReturn(mTetheringApexPackageInfo).when(mPm).getPackageInfo(
+ eq(TEST_GO_TETHERING_PACKAGE_NAME), anyInt());
doReturn("0").when(() -> DeviceConfig.getProperty(
NAMESPACE_CONNECTIVITY, TEST_EXPERIMENT_FLAG));
doReturn("0").when(() -> DeviceConfig.getProperty(
@@ -483,6 +499,31 @@
mContext, 889900000L + CONNECTIVITY_MODULE_ID));
}
+
+ @Test
+ public void testIsFeatureSupported_resolvFeature() throws Exception {
+ assertTrue(DeviceConfigUtils.isFeatureSupported(
+ mContext, TEST_RESOLV_PACKAGE_VERSION + DNS_RESOLVER_MODULE_ID));
+ // Return false because feature requires a future version.
+ assertFalse(DeviceConfigUtils.isFeatureSupported(
+ mContext, 889900000L + DNS_RESOLVER_MODULE_ID));
+ }
+
+ @Test
+ public void testIsFeatureSupported_goResolvFeature() throws Exception {
+ doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(eq(TEST_RESOLV_PACKAGE_NAME),
+ anyInt());
+ doReturn(mGoApexPackageInfo).when(mPm).getPackageInfo(eq(TEST_GO_RESOLV_PACKAGE_NAME),
+ anyInt());
+ assertFalse(DeviceConfigUtils.isFeatureSupported(
+ mContext, TEST_RESOLV_PACKAGE_VERSION + DNS_RESOLVER_MODULE_ID));
+ assertTrue(DeviceConfigUtils.isFeatureSupported(
+ mContext, TEST_GO_PACKAGE_VERSION + DNS_RESOLVER_MODULE_ID));
+ // Return false because feature requires a future version.
+ assertFalse(DeviceConfigUtils.isFeatureSupported(
+ mContext, 889900000L + DNS_RESOLVER_MODULE_ID));
+ }
+
@Test
public void testIsFeatureSupported_illegalModule() throws Exception {
assertThrows(IllegalArgumentException.class,
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java
index 3239244..c8f8656 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java
@@ -211,7 +211,7 @@
setupTestCase();
final int result =
- mChecker.checkLocationPermissionWithDetailInfo(
+ mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
assertEquals(LocationPermissionChecker.SUCCEEDED, result);
}
@@ -228,7 +228,7 @@
setupTestCase();
final int result =
- mChecker.checkLocationPermissionWithDetailInfo(
+ mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
assertEquals(LocationPermissionChecker.SUCCEEDED, result);
}
@@ -243,7 +243,7 @@
setupTestCase();
assertThrows(SecurityException.class,
- () -> mChecker.checkLocationPermissionWithDetailInfo(
+ () -> mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null));
}
@@ -254,7 +254,7 @@
setupTestCase();
final int result =
- mChecker.checkLocationPermissionWithDetailInfo(
+ mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
assertEquals(LocationPermissionChecker.ERROR_LOCATION_PERMISSION_MISSING, result);
}
@@ -270,7 +270,7 @@
setupTestCase();
final int result =
- mChecker.checkLocationPermissionWithDetailInfo(
+ mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
assertEquals(LocationPermissionChecker.ERROR_LOCATION_PERMISSION_MISSING, result);
verify(mMockAppOps, never()).noteOp(anyInt(), anyInt(), anyString());
@@ -287,7 +287,7 @@
setupTestCase();
final int result =
- mChecker.checkLocationPermissionWithDetailInfo(
+ mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
assertEquals(LocationPermissionChecker.ERROR_LOCATION_MODE_OFF, result);
}
@@ -301,7 +301,7 @@
setupTestCase();
final int result =
- mChecker.checkLocationPermissionWithDetailInfo(
+ mChecker.checkLocationPermissionInternal(
TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
assertEquals(LocationPermissionChecker.SUCCEEDED, result);
}
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
index 61fa5d0..93b2f70 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
@@ -125,6 +125,7 @@
import com.android.server.thread.openthread.IOtDaemon;
import com.android.server.thread.openthread.IOtDaemonCallback;
import com.android.server.thread.openthread.IOtStatusReceiver;
+import com.android.server.thread.openthread.InfraLinkState;
import com.android.server.thread.openthread.Ipv6AddressInfo;
import com.android.server.thread.openthread.MeshcopTxtAttributes;
import com.android.server.thread.openthread.OnMeshPrefixConfig;
@@ -214,6 +215,7 @@
private boolean mForceStopOtDaemonEnabled;
private OtDaemonConfiguration mOtDaemonConfig;
+ private InfraLinkState mInfraLinkState;
@VisibleForTesting
ThreadNetworkControllerService(
@@ -238,11 +240,8 @@
mInfraIfController = infraIfController;
mUpstreamNetworkRequest = newUpstreamNetworkRequest();
mNetworkToInterface = new HashMap<Network, String>();
- mOtDaemonConfig =
- new OtDaemonConfiguration.Builder()
- .setIsBorderRoutingEnabled(true)
- .setInfraInterfaceName(null)
- .build();
+ mOtDaemonConfig = new OtDaemonConfiguration.Builder().build();
+ mInfraLinkState = new InfraLinkState.Builder().build();
mPersistentSettings = persistentSettings;
mNsdPublisher = nsdPublisher;
mUserManager = userManager;
@@ -571,6 +570,7 @@
}
}
}
+ // TODO: set the configuration at ot-daemon
}
@Override
@@ -1232,51 +1232,45 @@
}
}
- private void configureBorderRouter(OtDaemonConfiguration otDaemonConfig) {
- if (mOtDaemonConfig.equals(otDaemonConfig)) {
+ private void setInfraLinkState(InfraLinkState infraLinkState) {
+ if (mInfraLinkState.equals(infraLinkState)) {
return;
}
- Log.i(TAG, "Configuring Border Router: " + mOtDaemonConfig + " -> " + otDaemonConfig);
- mOtDaemonConfig = otDaemonConfig;
+ Log.i(TAG, "Infra link state changed: " + mInfraLinkState + " -> " + infraLinkState);
+ mInfraLinkState = infraLinkState;
ParcelFileDescriptor infraIcmp6Socket = null;
- if (mOtDaemonConfig.infraInterfaceName != null) {
+ if (mInfraLinkState.interfaceName != null) {
try {
infraIcmp6Socket =
- mInfraIfController.createIcmp6Socket(mOtDaemonConfig.infraInterfaceName);
+ mInfraIfController.createIcmp6Socket(mInfraLinkState.interfaceName);
} catch (IOException e) {
Log.i(TAG, "Failed to create ICMPv6 socket on infra network interface", e);
}
}
try {
getOtDaemon()
- .setConfiguration(
- mOtDaemonConfig,
+ .setInfraLinkState(
+ mInfraLinkState,
infraIcmp6Socket,
- new ConfigureBorderRouterStatusReceiver());
+ new setInfraLinkStateStatusReceiver());
} catch (RemoteException | ThreadNetworkException e) {
Log.w(TAG, "Failed to configure border router " + mOtDaemonConfig, e);
}
}
private void enableBorderRouting(String infraIfName) {
- OtDaemonConfiguration otDaemonConfig =
- newOtDaemonConfigBuilder(mOtDaemonConfig)
- .setIsBorderRoutingEnabled(true)
- .setInfraInterfaceName(infraIfName)
- .build();
+ InfraLinkState infraLinkState =
+ newInfraLinkStateBuilder(mInfraLinkState).setInterfaceName(infraIfName).build();
Log.i(TAG, "Enable border routing on AIL: " + infraIfName);
- configureBorderRouter(otDaemonConfig);
+ setInfraLinkState(infraLinkState);
}
private void disableBorderRouting() {
mUpstreamNetwork = null;
- OtDaemonConfiguration otDaemonConfig =
- newOtDaemonConfigBuilder(mOtDaemonConfig)
- .setIsBorderRoutingEnabled(false)
- .setInfraInterfaceName(null)
- .build();
+ InfraLinkState infraLinkState =
+ newInfraLinkStateBuilder(mInfraLinkState).setInterfaceName(null).build();
Log.i(TAG, "Disabling border routing");
- configureBorderRouter(otDaemonConfig);
+ setInfraLinkState(infraLinkState);
}
private void handleThreadInterfaceStateChanged(boolean isUp) {
@@ -1378,10 +1372,12 @@
}
private static OtDaemonConfiguration.Builder newOtDaemonConfigBuilder(
- OtDaemonConfiguration brConfig) {
- return new OtDaemonConfiguration.Builder()
- .setIsBorderRoutingEnabled(brConfig.isBorderRoutingEnabled)
- .setInfraInterfaceName(brConfig.infraInterfaceName);
+ OtDaemonConfiguration config) {
+ return new OtDaemonConfiguration.Builder();
+ }
+
+ private static InfraLinkState.Builder newInfraLinkStateBuilder(InfraLinkState infraLinkState) {
+ return new InfraLinkState.Builder().setInterfaceName(infraLinkState.interfaceName);
}
private static final class CallbackMetadata {
@@ -1405,8 +1401,9 @@
}
}
- private static final class ConfigureBorderRouterStatusReceiver extends IOtStatusReceiver.Stub {
- public ConfigureBorderRouterStatusReceiver() {}
+ private static final class setOtDaemonConfigurationStatusReceiver
+ extends IOtStatusReceiver.Stub {
+ public setOtDaemonConfigurationStatusReceiver() {}
@Override
public void onSuccess() {
@@ -1415,7 +1412,21 @@
@Override
public void onError(int i, String s) {
- Log.w(TAG, String.format("Failed to configure border router: %d %s", i, s));
+ Log.w(TAG, String.format("Failed to set configurations: %d %s", i, s));
+ }
+ }
+
+ private static final class setInfraLinkStateStatusReceiver extends IOtStatusReceiver.Stub {
+ public setInfraLinkStateStatusReceiver() {}
+
+ @Override
+ public void onSuccess() {
+ Log.i(TAG, "Set the infra link state successfully");
+ }
+
+ @Override
+ public void onError(int i, String s) {
+ Log.w(TAG, String.format("Failed to set the infra link state: %d %s", i, s));
}
}