Android 16.0.0 release 4

-----BEGIN PGP SIGNATURE-----
 
 iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCaS5huQAKCRDorT+BmrEO
 eIsnAJ9kJ9OjiHpwigt9XwjTrGcbD1hQ0QCfSw2VHyS9TLyzt7DZsQ3AYU+WVVA=
 =/SH/
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN SSH SIGNATURE-----
 U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgPpdpjxPACTIhnlvYz0GM4BR7FJ
 +rYv3jMbfxNKD3JvcAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
 AAAAQHUBff/oLA1TO7KbbZDsBJZmFVcXgFmG+2K3aaKq9F0tiaT1kiNeHdjXpaLI07p344
 TExz9CBvFVft81pJyRBwY=
 -----END SSH SIGNATURE-----

Merge tag 'android-16.0.0_r4' into staging/lineage-23.2_merge-android-16.0.0_r4

Android 16.0.0 release 4

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCaS5huQAKCRDorT+BmrEO
# eIsnAJ9kJ9OjiHpwigt9XwjTrGcbD1hQ0QCfSw2VHyS9TLyzt7DZsQ3AYU+WVVA=
# =/SH/
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Dec  2 05:49:13 2025 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]

# By Yan Yan (203) and others
# Via Automerger Merge Worker (1173) and others
* tag 'android-16.0.0_r4': (1057 commits)
  Use string for CREATE_APP_SPECIFIC_NETWORK permission
  bpf: move MSS calculation under CE check to avoid overhead
  BpfNetworkStats: use `atomic` for ifindex cache when possible
  NetBpfLoad: remove pointless 0 write.
  bpf: remove obsolete isAtLeastR/Sv2/25Q3
  NetBpfLoad: use global `api_level_full` directly in NetBpfLoad
  Log validated underlying network count that's available for VCN underlying network selection
  BpfUtils: fix sdk level detection logic for 25Q3+
  Add RTMGRP_IPV6_IFINFO
  bpf: remove BPFLOADER_MAINLINE_U_QPR3_VERSION
  bpf: move BPFLOADER_MAINLINE_S_VERSION into bpf_map_def.h
  Reduce log level for BluetoothSocket errors
  Bump the min sdk of Tethering
  BpfNetworkStats: apparently RiscV isn't actually a 64-bit architecture.
  KernelUtils.h: isAtLeastKernelVersion(x,y,z) - default 'z' to 0
  bpf_existence_test - update for tcp acc ecn
  bpf: tcpAccECN: eliminate header file and move more fully into netd
  BpfMap: shorten error strings to enable SSO (on 64-bit)
  BpfNetworkStats: enforce that IfaceValue access is lock-free
  NetBpfLoad: use libbpf based on mainline beta flag, part 2
  ...

 Conflicts:
	bpf/headers/include/bpf/KernelUtils.h
	bpf/progs/netd.h

Change-Id: I76a7aadc1405c6621e17f3d1b6b87640d84f5794
This commit is contained in:
Michael Bestas 2025-12-09 06:40:14 +02:00
commit 42374b293f
554 changed files with 53416 additions and 6658 deletions

View file

@ -11,4 +11,4 @@ xiaom@google.com
yuyanghuang@google.com
martinwu@google.com #{LAST_RESORT_SUGGESTION}
satk@google.com #{LAST_RESORT_SUGGESTION}
larsberg@google.com #{LAST_RESORT_SUGGESTION}

View file

@ -1,5 +1,5 @@
lorenzo@google.com
satk@google.com #{LAST_RESORT_SUGGESTION}
larsberg@google.com #{LAST_RESORT_SUGGESTION}
# For cherry-picks of CLs that are already merged in aosp/master, flaky test
# fixes, or no-op refactors.

View file

@ -15,6 +15,3 @@ ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py --disabled-rules comment-w
hidden_api_txt_checksorted_hook = ${REPO_ROOT}/tools/platform-compat/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
python_hook = ${REPO_ROOT}/packages/modules/Connectivity/preupload_hook_script.py ${PREUPLOAD_FILES}
# go/alint for details
alint_hook = ${REPO_ROOT}/vendor/google/tools/alint

View file

@ -83,6 +83,14 @@
"exclude-annotation": "com.android.testutils.NetworkStackModuleTest"
}
]
},
{
"name": "CtsHostsideNetworkTests",
"options": [
{
"exclude-annotation": "androidx.test.filters.RequiresDevice"
}
]
}
],
"captiveportal-networkstack-mainline-presubmit": [
@ -319,14 +327,6 @@
}
]
},
{
"name": "CtsHostsideNetworkTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
"options": [
{
"exclude-annotation": "androidx.test.filters.RequiresDevice"
}
]
},
// Test with APK modules only, in cases where APEX is not supported, or the other modules
// were simply not updated
{
@ -435,12 +435,23 @@
"name": "CtsNetTestCasesUpdateStatsPermission"
}
],
"tv-presubmit": [
"hsum-presubmit": [
{
"name": "CtsNetTestCases"
},
{
"name": "CtsNativeNetTestCases"
"name": "CtsNativeNetDnsTestCases"
},
{
"name": "CtsNetTestCasesInternetPermission"
},
{
"name": "CtsNetTestCasesUpdateStatsPermission"
}
],
"tv-presubmit": [
{
"name": "CtsNetTestCases"
},
{
"name": "CtsNativeNetDnsTestCases"
@ -471,5 +482,18 @@
{
"path": "vendor/xts/gts-tests/hostsidetests/networkstack"
}
],
"wear-cts-presubmit": [
{
"name": "CtsNetTestCases",
"options": [
{
"exclude-filter": "android.net.cts.NetworkValidationTest#testCapportApiCallbacks"
}
]
},
{
"name": "CtsNetTestCasesUpdateStatsPermission"
}
]
}

View file

@ -22,7 +22,10 @@ package {
java_defaults {
name: "TetheringApiLevel",
sdk_version: "module_current",
min_sdk_version: "30",
min_sdk_version: select(release_flag("RELEASE_DEPRECATE_MAINLINE_R_SUPPORT"), {
true: "31",
default: "30",
}),
}
java_defaults {
@ -65,6 +68,8 @@ java_defaults {
"androidx.annotation_annotation",
"connectivity-net-module-utils-bpf",
"com.android.net.flags-aconfig-java",
"com.android.tethering.beta.test.flags-aconfig-java",
"com.android.tethering.mainline.beta.flags-aconfig-java",
"modules-utils-build",
"modules-utils-statemachine",
"networkstack-client",

View file

@ -67,6 +67,7 @@ apex {
"libservice-connectivity",
"libservice-thread-jni",
"libandroid_net_connectivity_com_android_net_module_util_jni",
"libandroid_net_connectivity_com_android_net_module_util_jni_CommonConnectivityJni",
],
native_shared_libs: [
"libcom.android.tethering.dns_helper",

View file

@ -33,20 +33,17 @@ import androidx.annotation.Nullable;
import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.IBpfMap.ThrowingBiConsumer;
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.Struct.S64;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
import com.android.net.module.util.bpf.TetherStatsValue;
import com.android.networkstack.tethering.BpfCoordinator.Dependencies;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6DownstreamRule;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6UpstreamRule;
import com.android.networkstack.tethering.BpfUtils;
import com.android.networkstack.tethering.Tether6Value;
import com.android.networkstack.tethering.TetherDevKey;
import com.android.networkstack.tethering.TetherDevValue;
import com.android.networkstack.tethering.TetherDownstream6Key;
import com.android.networkstack.tethering.TetherLimitKey;
import com.android.networkstack.tethering.TetherLimitValue;
import com.android.networkstack.tethering.TetherUpstream6Key;
import java.io.FileDescriptor;
@ -85,15 +82,15 @@ public class BpfCoordinatorShimImpl
// BPF map of tethering statistics of the upstream interface since tethering startup.
@Nullable
private final IBpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
private final IBpfMap<S32, TetherStatsValue> mBpfStatsMap;
// BPF map of per-interface quota for tethering offload.
@Nullable
private final IBpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
private final IBpfMap<S32, S64> mBpfLimitMap;
// BPF map of interface index mapping for XDP.
@Nullable
private final IBpfMap<TetherDevKey, TetherDevValue> mBpfDevMap;
private final IBpfMap<S32, S32> mBpfDevMap;
// Tracking IPv4 rule count while any rule is using the given upstream interfaces. Used for
// reducing the BPF map iteration query. The count is increased or decreased when the rule is
@ -252,7 +249,7 @@ public class BpfCoordinatorShimImpl
try {
// The reported tether stats are total data usage for all currently-active upstream
// interfaces since tethering start.
mBpfStatsMap.forEach((key, value) -> tetherStatsList.put((int) key.ifindex, value));
mBpfStatsMap.forEach((key, value) -> tetherStatsList.put((int) key.val, value));
} catch (ErrnoException e) {
mLog.e("Fail to fetch tethering stats from BPF map: ", e);
return null;
@ -269,7 +266,7 @@ public class BpfCoordinatorShimImpl
TetherStatsValue statsValue = null;
try {
statsValue = mBpfStatsMap.getValue(new TetherStatsKey(ifIndex));
statsValue = mBpfStatsMap.getValue(new S32(ifIndex));
} catch (ErrnoException e) {
// The BpfMap#getValue doesn't throw an errno ENOENT exception. Catch other error
// while trying to get stats entry.
@ -287,7 +284,7 @@ public class BpfCoordinatorShimImpl
// This function is the *only* thing that can create entries.
// BpfMap#insertEntry use BPF_NOEXIST to create the entry. The entry is created
// if and only if it doesn't exist.
mBpfStatsMap.insertEntry(new TetherStatsKey(ifIndex), new TetherStatsValue(
mBpfStatsMap.insertEntry(new S32(ifIndex), new TetherStatsValue(
0 /* rxPackets */, 0 /* rxBytes */, 0 /* rxErrors */, 0 /* txPackets */,
0 /* txBytes */, 0 /* txErrors */));
} catch (ErrnoException | IllegalArgumentException e) {
@ -305,7 +302,7 @@ public class BpfCoordinatorShimImpl
if (newLimit < rxBytes + txBytes) newLimit = QUOTA_UNLIMITED;
try {
mBpfLimitMap.updateEntry(new TetherLimitKey(ifIndex), new TetherLimitValue(newLimit));
mBpfLimitMap.updateEntry(new S32(ifIndex), new S64(newLimit));
} catch (ErrnoException e) {
mLog.e("Fail to set quota " + quotaBytes + " for interface index " + ifIndex + ": ", e);
return false;
@ -331,7 +328,7 @@ public class BpfCoordinatorShimImpl
TetherStatsValue statsValue = null;
try {
statsValue = mBpfStatsMap.getValue(new TetherStatsKey(ifIndex));
statsValue = mBpfStatsMap.getValue(new S32(ifIndex));
} catch (ErrnoException e) {
mLog.e("Could not get stats entry for interface index " + ifIndex + ": ", e);
return null;
@ -343,14 +340,14 @@ public class BpfCoordinatorShimImpl
}
try {
mBpfStatsMap.deleteEntry(new TetherStatsKey(ifIndex));
mBpfStatsMap.deleteEntry(new S32(ifIndex));
} catch (ErrnoException e) {
mLog.e("Could not delete stats entry for interface index " + ifIndex + ": ", e);
return null;
}
try {
mBpfLimitMap.deleteEntry(new TetherLimitKey(ifIndex));
mBpfLimitMap.deleteEntry(new S32(ifIndex));
} catch (ErrnoException e) {
mLog.e("Could not delete limit for interface index " + ifIndex + ": ", e);
return null;
@ -470,7 +467,7 @@ public class BpfCoordinatorShimImpl
@Override
public boolean addDevMap(int ifIndex) {
try {
mBpfDevMap.updateEntry(new TetherDevKey(ifIndex), new TetherDevValue(ifIndex));
mBpfDevMap.updateEntry(new S32(ifIndex), new S32(ifIndex));
} catch (ErrnoException e) {
mLog.e("Could not add interface " + ifIndex + ": " + e);
return false;
@ -481,7 +478,7 @@ public class BpfCoordinatorShimImpl
@Override
public boolean removeDevMap(int ifIndex) {
try {
mBpfDevMap.deleteEntry(new TetherDevKey(ifIndex));
mBpfDevMap.deleteEntry(new S32(ifIndex));
} catch (ErrnoException e) {
mLog.e("Could not delete interface " + ifIndex + ": " + e);
return false;

View file

@ -34,8 +34,9 @@ java_sdk_library {
// Using for test only
"//cts/tests/netlegacy22.api",
// TODO: b/374174952 Remove it when VCN CTS is moved to Connectivity/
// TODO: b/374174952 Clean up VCN paths when the code location is finalized
"//cts/tests/tests/vcn",
"//packages/modules/Connectivity/Vcn/tests:__subpackages__",
"//external/sl4a:__subpackages__",
"//frameworks/base/core/tests/bandwidthtests",

View file

@ -18,7 +18,7 @@ package android.net;
/**
* Listener interface allowing objects to listen to various module event.
* {@hide}
* @hide
*/
oneway interface IIntResultListener {
void onResult(int resultCode);

View file

@ -20,7 +20,7 @@ import android.net.TetheringInterface;
/**
* Status details for tethering downstream interfaces.
* {@hide}
* @hide
*/
parcelable TetherStatesParcel {
TetheringInterface[] availableList;

View file

@ -381,7 +381,7 @@ public class TetheringManager {
* @param context Context for the manager.
* @param connectorSupplier Supplier for the manager connector; may return null while the
* service is not connected.
* {@hide}
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
public TetheringManager(@NonNull final Context context,
@ -574,7 +574,7 @@ public class TetheringManager {
* already released.
* 2. This is not synchronous, so it's not useful to use try-with-resources.
*
* {@hide}
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
@SuppressLint("NotCloseable")
@ -588,7 +588,7 @@ public class TetheringManager {
/**
* Callback for requestTetheredInterface.
*
* {@hide}
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
public interface TetheredInterfaceCallback {
@ -694,7 +694,7 @@ public class TetheringManager {
* @param iface the interface name to tether.
* @return error a {@code TETHER_ERROR} value indicating success or failure type
*
* {@hide}
* @hide
*/
@Deprecated
@SystemApi(client = MODULE_LIBRARIES)
@ -729,7 +729,7 @@ public class TetheringManager {
* On SDK versions after {@link Build.VERSION_CODES.VANILLA_ICE_CREAM}, this will
* throw an UnsupportedOperationException.
*
* {@hide}
* @hide
*/
@Deprecated
@SystemApi(client = MODULE_LIBRARIES)
@ -758,7 +758,7 @@ public class TetheringManager {
* used and an entitlement check is needed, downstream USB tethering will be enabled but will
* not have any upstream.
*
* {@hide}
* @hide
*/
@Deprecated
@SystemApi(client = MODULE_LIBRARIES)
@ -1553,7 +1553,7 @@ public class TetheringManager {
* Helper function of #requestLatestTetheringEntitlementResult to remain backwards compatible
* with ConnectivityManager#getLatestTetheringEntitlementResult
*
* {@hide}
* @hide
*/
// TODO: improve the usage of ResultReceiver, b/145096122
@SystemApi(client = MODULE_LIBRARIES)

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2025 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.
*/
#define LOG_TAG "com_android_networkstack_tethering_util_CommonConnectivityJni"
#include <android/log.h>
#include <nativehelper/JNIHelp.h>
namespace android {
int register_CommonConnectivityJni(JNIEnv *env, char const *class_name);
extern "C" jint JNI_OnLoad(JavaVM *vm, void *) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) !=
JNI_OK) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
return JNI_ERR;
}
if (register_CommonConnectivityJni(env,
"com/android/networkstack/tethering/util/CommonConnectivityJni") < 0) return JNI_ERR;
return JNI_VERSION_1_6;
}
}; // namespace android

View file

@ -23,6 +23,7 @@
namespace android {
int register_com_android_net_module_util_BpfMap(JNIEnv* env, char const* class_name);
int register_com_android_net_module_util_BpfBitmap(JNIEnv* env, char const* class_name);
int register_com_android_net_module_util_TcUtils(JNIEnv* env, char const* class_name);
int register_com_android_networkstack_tethering_BpfCoordinator(JNIEnv* env);
int register_com_android_networkstack_tethering_util_TetheringUtils(JNIEnv* env);
@ -39,6 +40,9 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
if (register_com_android_net_module_util_BpfMap(env,
"com/android/networkstack/tethering/util/BpfMap") < 0) return JNI_ERR;
if (register_com_android_net_module_util_BpfBitmap(env,
"com/android/networkstack/tethering/util/BpfBitmap") < 0) return JNI_ERR;
if (register_com_android_net_module_util_TcUtils(env,
"com/android/networkstack/tethering/util/TcUtils") < 0) return JNI_ERR;

View file

@ -39,11 +39,11 @@ import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.util.NetworkConstants.asByte;
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
import static com.android.net.module.util.ConnectivityCommonFlags.USE_ROUTE_PARCEL_IPCS;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
import static com.android.networkstack.tethering.TetheringConfiguration.USE_SYNC_SM;
import static com.android.networkstack.tethering.TetheringFeatureFlags.TETHERING_LOCAL_NETWORK_AGENT;
import static com.android.networkstack.tethering.TetheringFeatureFlags.WIFIP2PGO_LOCAL_NETWORK_AGENT;
import static com.android.networkstack.tethering.TetheringFeatureFlags.TETHERING_AND_P2P_GO_LOCAL_AGENT;
import static com.android.networkstack.tethering.util.PrefixUtils.asIpPrefix;
import static com.android.networkstack.tethering.util.TetheringMessageBase.BASE_IPSERVER;
import static com.android.networkstack.tethering.util.TetheringUtils.getTransportTypeForTetherableType;
@ -91,6 +91,7 @@ import com.android.net.module.util.IIpv4PrefixRequest;
import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.RoutingCoordinatorManager;
import com.android.net.module.util.SdkUtil;
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.SyncStateMachine.StateInfo;
import com.android.net.module.util.ip.InterfaceController;
@ -100,6 +101,7 @@ import com.android.networkstack.tethering.metrics.TetheringMetrics;
import com.android.networkstack.tethering.util.InterfaceSet;
import com.android.networkstack.tethering.util.PrefixUtils;
import com.android.networkstack.tethering.util.StateMachineShim;
import com.android.tethering.mainline.beta.Flags;
import java.net.Inet4Address;
import java.net.Inet6Address;
@ -218,10 +220,24 @@ public class IpServer extends StateMachineShim {
DhcpServerCallbacks cb);
/**
* @see DeviceConfigUtils#isTetheringFeatureEnabled
* Get whether a tethering feature flag is enabled via chickened out.
* @param name the name of the feature.
*/
public boolean isFeatureEnabled(Context context, String name) {
return DeviceConfigUtils.isTetheringFeatureEnabled(context, name);
public boolean isTetheringFeatureNotChickenedOut(@NonNull Context context,
@NonNull String name) {
return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, name);
}
/** Get whether tethering and P2P GO local agent flag is enabled via beta flags. */
public boolean isTetheringAndP2pGoLocalAgentBetaFlagEnabled() {
return Flags.tetheringAndP2pGoLocalAgent();
}
/**
* @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut
*/
public boolean isFeatureNotChickenedOut(Context context, String name) {
return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, name);
}
/** Create a NetworkAgent instance to be used by IpServer. */
@ -288,6 +304,7 @@ public class IpServer extends StateMachineShim {
private final boolean mUsingLegacyDhcp;
private final int mP2pLeasesSubnetPrefixLength;
private final boolean mIsWifiP2pDedicatedIpEnabled;
private final boolean mUseRouteParcel;
private final Dependencies mDeps;
@ -335,8 +352,8 @@ public class IpServer extends StateMachineShim {
private final Handler mHandler;
private final Context mContext;
private final boolean mSupportTetheringLocalAgent;
private final boolean mSupportWifiP2pGroupOwnerLocalAgent;
// Whether to enable tethering and Wi-Fi P2p Group Owner mode local network agent.
private final boolean mSupportTetheringAndP2pGoLocalAgent;
// This will be null if the TetheredState is not entered or feature not supported.
// This will be only accessed from the IpServer handler thread.
@ -381,11 +398,21 @@ public class IpServer extends StateMachineShim {
mLastError = TETHER_ERROR_NO_ERROR;
mServingMode = STATE_AVAILABLE;
// Tethering network agent is supported on V+, and will be rolled out gradually.
mSupportTetheringLocalAgent = SdkLevel.isAtLeastV()
&& mDeps.isFeatureEnabled(mContext, TETHERING_LOCAL_NETWORK_AGENT);
mSupportWifiP2pGroupOwnerLocalAgent = mSupportTetheringLocalAgent
&& mDeps.isFeatureEnabled(mContext, WIFIP2PGO_LOCAL_NETWORK_AGENT);
// Determines support for the Tethering/P2P GO local network agent. This feature is
// gated on Android V+ because it requires NET_CAPABILITY_LOCAL_NETWORK.
// For 25Q4+, it is enabled by default with a kill switch to prevent impacting
// existing devices if issues arise. For older V+ devices, rollout is controlled
// by a mainline beta flag.
mSupportTetheringAndP2pGoLocalAgent = SdkLevel.isAtLeastV()
&& (SdkUtil.isAtLeast25Q4()
? mDeps.isTetheringFeatureNotChickenedOut(mContext,
TETHERING_AND_P2P_GO_LOCAL_AGENT)
: mDeps.isTetheringAndP2pGoLocalAgentBetaFlagEnabled());
// For post 25Q2 releases always use *RouteParcel methods. For 25Q2 or lower, decide based
// on kill-switch
mUseRouteParcel = SdkUtil.isAtLeast25Q4()
|| mDeps.isFeatureNotChickenedOut(mContext, USE_ROUTE_PARCEL_IPCS);
mInitialState = new InitialState();
mLocalHotspotState = new LocalHotspotState();
@ -848,6 +875,7 @@ public class IpServer extends StateMachineShim {
String upstreamIface = null;
InterfaceParams upstreamIfaceParams = null;
int upstreamIfIndex = NO_UPSTREAM;
int pmtu6 = 1400; // default 'safe-ish' value
if (v6only != null) {
upstreamIface = v6only.getInterfaceName();
@ -856,7 +884,14 @@ public class IpServer extends StateMachineShim {
upstreamIfIndex = upstreamIfaceParams.index;
}
params = new RaParams();
params.mtu = v6only.getMtu();
pmtu6 = v6only.getMtu();
if (pmtu6 < 1280) pmtu6 = 1400; // we simply don't know what it is, 1400 is safe-ish
for (RouteInfo route : v6only.getRoutes()) {
if (route.getMtu() >= 1280) pmtu6 = Math.min(pmtu6, route.getMtu());
}
// Clamp v6 MTU to 1280-1500 range.
if (pmtu6 > 1500) pmtu6 = 1500;
params.mtu = pmtu6;
params.hasDefaultRoute = v6only.hasIpv6DefaultRoute();
if (params.hasDefaultRoute) params.hopLimit = getHopLimit(upstreamIface, ttlAdjustment);
@ -874,6 +909,8 @@ public class IpServer extends StateMachineShim {
// CMD_TETHER_CONNECTION_CHANGED. Adding the mapping update here to the avoid potential
// timing issue. It prevents that the IPv6 capability is updated later than
// CMD_TETHER_CONNECTION_CHANGED.
//
// TODO: I believe we need to push v6mtu into this call.
mBpfCoordinator.maybeAddUpstreamToLookupTable(upstreamIfIndex, upstreamIface);
// If v6only is null, we pass in null to setRaParams(), which handles
@ -886,7 +923,7 @@ public class IpServer extends StateMachineShim {
// mLastIPv6UpstreamIfindex and mLastIPv6UpstreamPrefixes because BpfCoordinator will call
// IpServer#getIpv6UpstreamIfindex and IpServer#getIpv6UpstreamPrefixes to retrieve current
// upstream interface index and prefixes when handling upstream changes.
mBpfCoordinator.updateIpv6UpstreamInterface(this, upstreamIfIndex, upstreamPrefixes);
mBpfCoordinator.updateIpv6UpstreamInterface(this, upstreamIfIndex, upstreamPrefixes, pmtu6);
mLastIPv6LinkProperties = v6only;
mLastIPv6UpstreamIfindex = upstreamIfIndex;
mLastIPv6UpstreamPrefixes = upstreamPrefixes;
@ -896,7 +933,8 @@ public class IpServer extends StateMachineShim {
}
private void removeRoutesFromNetwork(int netId, @NonNull final List<RouteInfo> toBeRemoved) {
final int removalFailures = NetdUtils.removeRoutesFromNetwork(mNetd, netId, toBeRemoved);
final int removalFailures = NetdUtils.removeRoutesFromNetwork(mNetd, netId, toBeRemoved,
mUseRouteParcel);
if (removalFailures > 0) {
mLog.e("Failed to remove " + removalFailures
+ " IPv6 routes from network " + netId + ".");
@ -927,15 +965,14 @@ public class IpServer extends StateMachineShim {
}
}
private void addRoutesToNetwork(int netId,
@NonNull final List<RouteInfo> toBeAdded) {
private void addRoutesToNetwork(int netId, @NonNull final List<RouteInfo> toBeAdded) {
// It's safe to call addInterfaceToNetwork() even if
// the interface is already in the network.
addInterfaceToNetwork(netId, mIfaceName);
try {
// Add routes from local network. Note that adding routes that
// already exist does not cause an error (EEXIST is silently ignored).
NetdUtils.addRoutesToNetwork(mNetd, netId, mIfaceName, toBeAdded);
NetdUtils.addRoutesToNetwork(mNetd, netId, mIfaceName, toBeAdded, mUseRouteParcel);
} catch (IllegalStateException e) {
mLog.e("Failed to add IPv4/v6 routes to local table: " + e);
return;
@ -949,6 +986,7 @@ public class IpServer extends StateMachineShim {
final List<RouteInfo> routesToBeRemoved =
getLocalRoutesFor(mIfaceName, deprecatedPrefixes);
if (mTetheringAgent == null) {
// Routes for local network are not considered local routes.
removeRoutesFromNetwork(LOCAL_NET_ID, routesToBeRemoved);
}
for (RouteInfo route : routesToBeRemoved) mLinkProperties.removeRoute(route);
@ -1166,8 +1204,7 @@ public class IpServer extends StateMachineShim {
@SuppressLint("NewApi")
private void startServingInterface() {
if (mSupportTetheringLocalAgent && (mSupportWifiP2pGroupOwnerLocalAgent
|| getScope() != CONNECTIVITY_SCOPE_LOCAL)) {
if (mSupportTetheringAndP2pGoLocalAgent) {
try {
mTetheringAgent = mDeps.makeNetworkAgent(mContext, Looper.myLooper(), TAG,
mInterfaceType, mLinkProperties);
@ -1197,10 +1234,11 @@ public class IpServer extends StateMachineShim {
20 /* maxAttempts */, 50 /* pollingIntervalMs */);
// Activate a route to dest and IPv6 link local.
NetdUtils.modifyRoute(mNetd, NetdUtils.ModifyOperation.ADD, LOCAL_NET_ID,
new RouteInfo(asIpPrefix(mIpv4Address), null, mIfaceName, RTN_UNICAST));
new RouteInfo(asIpPrefix(mIpv4Address), null, mIfaceName,
RTN_UNICAST), mUseRouteParcel);
NetdUtils.modifyRoute(mNetd, NetdUtils.ModifyOperation.ADD, LOCAL_NET_ID,
new RouteInfo(new IpPrefix("fe80::/64"), null, mIfaceName,
RTN_UNICAST));
RTN_UNICAST), mUseRouteParcel);
}
} catch (RemoteException | ServiceSpecificException | IllegalStateException e) {
mLog.e("Error Tethering", e);
@ -1330,6 +1368,7 @@ public class IpServer extends StateMachineShim {
final List<RouteInfo> routesToBeRemoved =
List.of(getDirectConnectedRoute(deprecatedLinkAddress));
if (mTetheringAgent == null) {
// Routes for local network are not considered local routes.
removeRoutesFromNetwork(LOCAL_NET_ID, routesToBeRemoved);
}
for (RouteInfo route : routesToBeRemoved) mLinkProperties.removeRoute(route);
@ -1440,7 +1479,7 @@ public class IpServer extends StateMachineShim {
for (String ifname : mUpstreamIfaceSet.ifnames) cleanupUpstreamInterface(ifname);
mUpstreamIfaceSet = null;
mBpfCoordinator.updateIpv6UpstreamInterface(IpServer.this, NO_UPSTREAM,
Collections.emptySet());
Collections.emptySet(), 1400);
}
private void cleanupUpstreamInterface(String upstreamIface) {

View file

@ -74,9 +74,9 @@ import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.Struct.S64;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
import com.android.net.module.util.bpf.TetherStatsValue;
import com.android.net.module.util.ip.ConntrackMonitor;
import com.android.net.module.util.ip.ConntrackMonitor.ConntrackEventConsumer;
@ -448,11 +448,11 @@ public class BpfCoordinator {
}
/** Get stats BPF map. */
@Nullable public IBpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
@Nullable public IBpfMap<S32, TetherStatsValue> getBpfStatsMap() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_STATS_MAP_PATH,
TetherStatsKey.class, TetherStatsValue.class);
S32.class, TetherStatsValue.class);
} catch (ErrnoException e) {
Log.e(TAG, "Cannot create stats map: " + e);
return null;
@ -460,11 +460,11 @@ public class BpfCoordinator {
}
/** Get limit BPF map. */
@Nullable public IBpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
@Nullable public IBpfMap<S32, S64> getBpfLimitMap() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_LIMIT_MAP_PATH,
TetherLimitKey.class, TetherLimitValue.class);
S32.class, S64.class);
} catch (ErrnoException e) {
Log.e(TAG, "Cannot create limit map: " + e);
return null;
@ -472,11 +472,11 @@ public class BpfCoordinator {
}
/** Get dev BPF map. */
@Nullable public IBpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
@Nullable public IBpfMap<S32, S32> getBpfDevMap() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_DEV_MAP_PATH,
TetherDevKey.class, TetherDevValue.class);
S32.class, S32.class);
} catch (ErrnoException e) {
Log.e(TAG, "Cannot create dev map: " + e);
return null;
@ -501,6 +501,12 @@ public class BpfCoordinator {
lastMaxSessionCount);
}
/** Send a BpfCoordinatorShimInitError event. */
public void sendBpfCoordinatorShimInitError() {
ConnectivityStatsLog.write(ConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
ConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_BPF_COORDINATOR_SHIM_INIT_ERROR);
}
/**
* @see DeviceConfigUtils#isTetheringFeatureEnabled
*/
@ -542,6 +548,7 @@ public class BpfCoordinator {
mBpfCoordinatorShim = BpfCoordinatorShim.getBpfCoordinatorShim(deps);
if (!mBpfCoordinatorShim.isInitialized()) {
mLog.e("Bpf shim not initialized");
mDeps.sendBpfCoordinatorShimInitError();
}
// BPF IPv4 forwarding only supports on S+.
@ -790,7 +797,7 @@ public class BpfCoordinator {
*/
private void updateAllIpv6Rules(@NonNull final IpServer ipServer,
final InterfaceParams interfaceParams, int newUpstreamIfindex,
@NonNull final Set<IpPrefix> newUpstreamPrefixes) {
@NonNull final Set<IpPrefix> newUpstreamPrefixes, int pmtu) {
if (!isUsingBpf()) return;
// Remove IPv6 downstream rules. Remove the old ones before adding the new rules, otherwise
@ -816,7 +823,7 @@ public class BpfCoordinator {
for (final IpPrefix ipPrefix : newUpstreamPrefixes) {
addIpv6UpstreamRule(ipServer, new Ipv6UpstreamRule(
newUpstreamIfindex, interfaceParams.index, ipPrefix,
interfaceParams.macAddr, NULL_MAC_ADDRESS, NULL_MAC_ADDRESS));
interfaceParams.macAddr, NULL_MAC_ADDRESS, NULL_MAC_ADDRESS, pmtu));
}
}
@ -958,7 +965,7 @@ public class BpfCoordinator {
* Note that this can be only called on handler thread.
*/
public void updateIpv6UpstreamInterface(@NonNull final IpServer ipServer, int upstreamIfindex,
@NonNull Set<IpPrefix> upstreamPrefixes) {
@NonNull Set<IpPrefix> upstreamPrefixes, int pmtu) {
if (!isUsingBpf()) return;
// If the upstream interface has changed, remove all rules and re-add them with the new
@ -971,7 +978,7 @@ public class BpfCoordinator {
final boolean upstreamSupportsBpf = checkUpstreamSupportsBpf(upstreamIfindex);
updateAllIpv6Rules(ipServer, interfaceParams,
getInterfaceIndexForRule(upstreamIfindex, upstreamSupportsBpf),
upstreamPrefixes);
upstreamPrefixes, pmtu);
}
}
@ -1059,12 +1066,12 @@ public class BpfCoordinator {
// Find the rules which are related with the given client.
mBpfCoordinatorShim.tetherOffloadRuleForEach(UPSTREAM, (k, v) -> {
if (Arrays.equals(k.src4, clientAddr.getAddress())) {
if (Objects.equals(k.src4, clientAddr)) {
deleteUpstreamRuleKeys.add(k);
}
});
mBpfCoordinatorShim.tetherOffloadRuleForEach(DOWNSTREAM, (k, v) -> {
if (Arrays.equals(v.dst46, toIpv4MappedAddressBytes(clientAddr))) {
if (Objects.equals(v.dst46, clientAddr)) {
deleteDownstreamRuleKeys.add(k);
upstreamIndiceSet.add((int) k.iif);
}
@ -1370,7 +1377,7 @@ public class BpfCoordinator {
}
}
private void dumpBpfStats(@NonNull IndentingPrintWriter pw) {
try (IBpfMap<TetherStatsKey, TetherStatsValue> map = mDeps.getBpfStatsMap()) {
try (IBpfMap<S32, TetherStatsValue> map = mDeps.getBpfStatsMap()) {
if (map == null) {
pw.println("No BPF stats map");
return;
@ -1439,9 +1446,10 @@ public class BpfCoordinator {
}
private String ipv6UpstreamRuleToString(TetherUpstream6Key key, Tether6Value value) {
return String.format("%d(%s) [%s] [%s] -> %d(%s) %04x [%s] [%s]",
return String.format("%d(%s) [%s] [%s] -> %d(%s) %04x [%s] [%s] %d",
key.iif, getIfName(key.iif), key.dstMac, bytesToPrefix(key.src64), value.oif,
getIfName(value.oif), value.ethProto, value.ethSrcMac, value.ethDstMac);
getIfName(value.oif), value.ethProto, value.ethSrcMac, value.ethDstMac,
value.pmtu);
}
private void dumpIpv6UpstreamRules(IndentingPrintWriter pw) {
@ -1467,9 +1475,9 @@ public class BpfCoordinator {
} catch (UnknownHostException impossible) {
throw new AssertionError("IP address array not valid IPv6 address!");
}
return String.format("%d(%s) [%s] %s -> %d(%s) %04x [%s] [%s]",
return String.format("%d(%s) [%s] %s -> %d(%s) %04x [%s] [%s] %d",
key.iif, getIfName(key.iif), key.dstMac, neigh6, value.oif, getIfName(value.oif),
value.ethProto, value.ethSrcMac, value.ethDstMac);
value.ethProto, value.ethSrcMac, value.ethDstMac, value.pmtu);
}
private void dumpIpv6DownstreamRules(IndentingPrintWriter pw) {
@ -1492,13 +1500,13 @@ public class BpfCoordinator {
// duplicate bpf map dump code.
private void dumpBpfForwardingRulesIpv6(IndentingPrintWriter pw) {
pw.println("IPv6 Upstream: iif(iface) [inDstMac] [sourcePrefix] -> oif(iface) etherType "
+ "[outSrcMac] [outDstMac]");
+ "[outSrcMac] [outDstMac] pmtu");
pw.increaseIndent();
dumpIpv6UpstreamRules(pw);
pw.decreaseIndent();
pw.println("IPv6 Downstream: iif(iface) [inDstMac] neigh6 -> oif(iface) etherType "
+ "[outSrcMac] [outDstMac]");
+ "[outSrcMac] [outDstMac] pmtu");
pw.increaseIndent();
dumpIpv6DownstreamRules(pw);
pw.decreaseIndent();
@ -1522,7 +1530,7 @@ public class BpfCoordinator {
// expected argument order.
// TODO: dump downstream4 map.
if (CollectionUtils.contains(args, DUMPSYS_RAWMAP_ARG_STATS)) {
try (IBpfMap<TetherStatsKey, TetherStatsValue> statsMap = mDeps.getBpfStatsMap()) {
try (IBpfMap<S32, TetherStatsValue> statsMap = mDeps.getBpfStatsMap()) {
BpfDump.dumpRawMap(statsMap, pw);
} catch (IOException e) {
pw.println("Error dumping stats map: " + e);
@ -1552,20 +1560,15 @@ public class BpfCoordinator {
Tether4Key key, Tether4Value value) {
final String src4, public4, dst4;
final int publicPort;
try {
src4 = InetAddress.getByAddress(key.src4).getHostAddress();
if (downstream) {
public4 = InetAddress.getByAddress(key.dst4).getHostAddress();
publicPort = key.dstPort;
} else {
public4 = InetAddress.getByAddress(value.src46).getHostAddress();
publicPort = value.srcPort;
}
dst4 = InetAddress.getByAddress(value.dst46).getHostAddress();
} catch (UnknownHostException impossible) {
throw new AssertionError("IP address array not valid IPv4 address!");
src4 = key.src4.getHostAddress();
if (downstream) {
public4 = key.dst4.getHostAddress();
publicPort = key.dstPort;
} else {
public4 = value.src46.getHostAddress();
publicPort = value.srcPort;
}
dst4 = value.dst46.getHostAddress();
final String ageStr = (value.lastUsed == 0) ? "-"
: String.format("%dms", (now - value.lastUsed) / 1_000_000);
return String.format("%s [%s] %d(%s) %s:%d -> %d(%s) %s:%d -> %s:%d [%s] %d %s",
@ -1636,7 +1639,7 @@ public class BpfCoordinator {
}
private void dumpDevmap(@NonNull IndentingPrintWriter pw) {
try (IBpfMap<TetherDevKey, TetherDevValue> map = mDeps.getBpfDevMap()) {
try (IBpfMap<S32, S32> map = mDeps.getBpfDevMap()) {
if (map == null) {
pw.println("No devmap support");
return;
@ -1651,8 +1654,8 @@ public class BpfCoordinator {
// Only get upstream interface name. Just do the best to make the index readable.
// TODO: get downstream interface name because the index is either upstream or
// downstream interface in dev map.
pw.println(String.format("%d (%s) -> %d (%s)", k.ifIndex, getIfName(k.ifIndex),
v.ifIndex, getIfName(v.ifIndex)));
pw.println(String.format("%d (%s) -> %d (%s)", k.val, getIfName(k.val),
v.val, getIfName(v.val)));
});
} catch (ErrnoException | IOException e) {
pw.println("Error dumping dev map: " + e);
@ -1692,7 +1695,7 @@ public class BpfCoordinator {
// |field |oif |ethDst|ethSrc|ethPro|pmtu |
// | | |mac |mac |to | |
// +------+------+------+------+------+------+
// |value |upstre|-- |-- |ETH_P_|1500 |
// |value |upstre|-- |-- |ETH_P_|pmtu |
// | |am | | |IP | |
// +------+------+------+------+------+------+
//
@ -1706,16 +1709,19 @@ public class BpfCoordinator {
public final MacAddress outSrcMac;
@NonNull
public final MacAddress outDstMac;
public final int pmtu;
public Ipv6UpstreamRule(int upstreamIfindex, int downstreamIfindex,
@NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
@NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac) {
@NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac,
int pmtu) {
this.upstreamIfindex = upstreamIfindex;
this.downstreamIfindex = downstreamIfindex;
this.sourcePrefix = sourcePrefix;
this.inDstMac = inDstMac;
this.outSrcMac = outSrcMac;
this.outDstMac = outDstMac;
this.pmtu = pmtu;
}
/**
@ -1732,8 +1738,7 @@ public class BpfCoordinator {
*/
@NonNull
public Tether6Value makeTether6Value() {
return new Tether6Value(upstreamIfindex, outDstMac, outSrcMac, ETH_P_IPV6,
NetworkStackConstants.ETHER_MTU);
return new Tether6Value(upstreamIfindex, outDstMac, outSrcMac, ETH_P_IPV6, pmtu);
}
@Override
@ -2032,20 +2037,6 @@ public class BpfCoordinator {
return null;
}
@NonNull
@VisibleForTesting
static byte[] toIpv4MappedAddressBytes(Inet4Address ia4) {
final byte[] addr4 = ia4.getAddress();
final byte[] addr6 = new byte[16];
addr6[10] = (byte) 0xff;
addr6[11] = (byte) 0xff;
addr6[12] = addr4[0];
addr6[13] = addr4[1];
addr6[14] = addr4[2];
addr6[15] = addr4[3];
return addr6;
}
// TODO: parse CTA_PROTOINFO of conntrack event in ConntrackMonitor. For TCP, only add rules
// while TCP status is established.
@VisibleForTesting
@ -2111,16 +2102,16 @@ public class BpfCoordinator {
private Tether4Key makeTetherUpstream4Key(
@NonNull ConntrackEvent e, @NonNull ClientInfo c) {
return new Tether4Key(c.downstreamIfindex, c.downstreamMac,
e.tupleOrig.protoNum, e.tupleOrig.srcIp.getAddress(),
e.tupleOrig.dstIp.getAddress(), e.tupleOrig.srcPort, e.tupleOrig.dstPort);
e.tupleOrig.protoNum, e.tupleOrig.srcIp, e.tupleOrig.dstIp,
e.tupleOrig.srcPort, e.tupleOrig.dstPort);
}
@NonNull
private Tether4Key makeTetherDownstream4Key(
@NonNull ConntrackEvent e, @NonNull ClientInfo c, int upstreamIndex) {
return new Tether4Key(upstreamIndex, NULL_MAC_ADDRESS /* dstMac (rawip) */,
e.tupleReply.protoNum, e.tupleReply.srcIp.getAddress(),
e.tupleReply.dstIp.getAddress(), e.tupleReply.srcPort, e.tupleReply.dstPort);
e.tupleReply.protoNum, e.tupleReply.srcIp, e.tupleReply.dstIp,
e.tupleReply.srcPort, e.tupleReply.dstPort);
}
@NonNull
@ -2129,8 +2120,7 @@ public class BpfCoordinator {
return new Tether4Value(upstreamInfo.ifIndex,
NULL_MAC_ADDRESS /* ethDstMac (rawip) */,
NULL_MAC_ADDRESS /* ethSrcMac (rawip) */, ETH_P_IP,
upstreamInfo.mtu, toIpv4MappedAddressBytes(e.tupleReply.dstIp),
toIpv4MappedAddressBytes(e.tupleReply.srcIp), e.tupleReply.dstPort,
upstreamInfo.mtu, e.tupleReply.dstIp, e.tupleReply.srcIp, e.tupleReply.dstPort,
e.tupleReply.srcPort, 0 /* lastUsed, filled by bpf prog only */);
}
@ -2139,8 +2129,7 @@ public class BpfCoordinator {
@NonNull ClientInfo c, @NonNull UpstreamInfo upstreamInfo) {
return new Tether4Value(c.downstreamIfindex,
c.clientMac, c.downstreamMac, ETH_P_IP, upstreamInfo.mtu,
toIpv4MappedAddressBytes(e.tupleOrig.dstIp),
toIpv4MappedAddressBytes(e.tupleOrig.srcIp),
e.tupleOrig.dstIp, e.tupleOrig.srcIp,
e.tupleOrig.dstPort, e.tupleOrig.srcPort,
0 /* lastUsed, filled by bpf prog only */);
}
@ -2465,17 +2454,6 @@ public class BpfCoordinator {
return Math.max(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, configInterval);
}
@Nullable
private Inet4Address parseIPv4Address(byte[] addrBytes) {
try {
final InetAddress ia = Inet4Address.getByAddress(addrBytes);
if (ia instanceof Inet4Address) return (Inet4Address) ia;
} catch (UnknownHostException e) {
mLog.e("Failed to parse IPv4 address: " + e);
}
return null;
}
// Update CTA_TUPLE_ORIG timeout for a given conntrack entry. Note that there will also be
// coming a conntrack event to notify updated timeout.
private void updateConntrackTimeout(byte proto, Inet4Address src4, short srcPort,
@ -2532,9 +2510,8 @@ public class BpfCoordinator {
// both directions for TCP.
mBpfCoordinatorShim.tetherOffloadRuleForEach(UPSTREAM, (k, v) -> {
if ((now - v.lastUsed) / 1_000_000 < CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS) {
updateConntrackTimeout((byte) k.l4proto,
parseIPv4Address(k.src4), (short) k.srcPort,
parseIPv4Address(k.dst4), (short) k.dstPort);
updateConntrackTimeout((byte) k.l4proto, k.src4, (short) k.srcPort, k.dst4,
(short) k.dstPort);
}
});
@ -2543,9 +2520,8 @@ public class BpfCoordinator {
// which is opposite direction for downstream map value.
mBpfCoordinatorShim.tetherOffloadRuleForEach(DOWNSTREAM, (k, v) -> {
if ((now - v.lastUsed) / 1_000_000 < CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS) {
updateConntrackTimeout((byte) k.l4proto,
parseIPv4Address(v.dst46), (short) v.dstPort,
parseIPv4Address(v.src46), (short) v.srcPort);
updateConntrackTimeout((byte) k.l4proto, (Inet4Address) v.dst46, (short) v.dstPort,
(Inet4Address) v.src46, (short) v.srcPort);
}
});
}

View file

@ -30,7 +30,7 @@ import java.io.IOException;
/**
* The classes and the methods for BPF utilization.
*
* {@hide}
* @hide
*/
public class BpfUtils {
static {

View file

@ -32,6 +32,7 @@ import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import static com.android.networkstack.apishim.ConstantsShim.ACTION_TETHER_UNSUPPORTED_CARRIER_UI;
@ -448,7 +449,8 @@ public class EntitlementManager {
return TETHERING_PROVISIONING_CARRIER_UNSUPPORT;
}
if (!config.isCarrierConfigAffirmsEntitlementCheckRequired) {
if (!config.isCarrierConfigAffirmsEntitlementCheckRequired
|| INVALID_SUBSCRIPTION_ID == config.activeDataSubId) {
return TETHERING_PROVISIONING_NOT_REQUIRED;
}
return (config.provisioningApp.length == 2)

View file

@ -1,35 +0,0 @@
/*
* Copyright (C) 2020 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.
*/
package com.android.networkstack.tethering;
import com.android.net.module.util.Struct;
import com.android.net.module.util.Struct.Field;
import com.android.net.module.util.Struct.Type;
/** The value of BpfMap which is used for tethering per-interface limit. */
public class TetherLimitValue extends Struct {
// Use the signed long variable to store the int64 limit on limit BPF map.
// S64 is enough for each interface limit even at 5Gbps for ~468 years.
// 2^63 / (5 * 1000 * 1000 * 1000) * 8 / 86400 / 365 = 468.
// Note that QUOTA_UNLIMITED (-1) indicates there is no limit.
@Field(order = 0, type = Type.S64)
public final long limit;
public TetherLimitValue(final long limit) {
this.limit = limit;
}
}

View file

@ -138,9 +138,8 @@ public abstract class TetheringDependencies {
IBinder binder;
if (!SdkLevel.isAtLeastS()) {
final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
binder =
new RoutingCoordinatorService(
getINetd(context, log), cm::getAllNetworks, context);
binder = new RoutingCoordinatorService(getINetd(context, log), cm::getAllNetworks,
context, false /* bluetoothTetheringUseRandomAddress */);
} else {
binder = ConnectivityInternalApiUtil.getRoutingCoordinator(context);
}

View file

@ -61,15 +61,8 @@ public class TetheringFeatureFlags {
public static final String TETHER_ACTIVE_SESSIONS_METRICS = "tether_active_sessions_metrics";
/**
* A feature flag to control whether the tethering local network agent should be enabled.
* Disabled by default.
* A kill switch to control whether the TETHERING_AND_P2P_GO_LOCAL_AGENT is enabled.
*/
public static final String TETHERING_LOCAL_NETWORK_AGENT = "tethering_local_network_agent";
/**
* A feature flag to control whether the Wifi P2P Group Owner local network agent
* should be enabled. Disabled by default. This depends on TETHERING_LOCAL_AGENT
* and will not be enabled if that flag is off.
*/
public static final String WIFIP2PGO_LOCAL_NETWORK_AGENT = "wifip2pgo_local_network_agent";
public static final String TETHERING_AND_P2P_GO_LOCAL_AGENT =
"tethering_and_p2p_go_local_agent";
}

Some files were not shown because too many files have changed in this diff Show more