Merge changes from topic "revert-1551943-vpn-impl-FKOLCXTDDT"
* changes:
Revert "Add VpnServiceBuilderShim for VpnService.Builder"
Revert "Suppress NewApi warnings for @SystemApi -> public APIs"
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp
index fd7bfc9..3c97dc2 100644
--- a/common/networkstackclient/Android.bp
+++ b/common/networkstackclient/Android.bp
@@ -35,7 +35,6 @@
apex_available: [
"//apex_available:platform",
"com.android.wifi",
- "com.android.bluetooth.updatable",
"com.android.tethering",
],
// this is part of updatable modules(NetworkStack) which targets 29(Q)
@@ -109,7 +108,6 @@
java: {
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth.updatable",
"com.android.wifi",
"com.android.tethering",
],
diff --git a/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java b/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
index d3e6cb7..7cf46f5 100644
--- a/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
+++ b/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
@@ -141,5 +141,9 @@
*
* @param lossInfo the specific neighbor reachability loss information.
*/
- public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {}
+ public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
+ // If the client does not implement this method, call the older
+ // onReachabilityLost method.
+ onReachabilityLost(lossInfo.message);
+ }
}
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
index d20e769..704ca7d 100644
--- a/src/android/net/dhcp/DhcpClient.java
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -251,6 +251,7 @@
public static final int DHCP_SUCCESS = 1;
public static final int DHCP_FAILURE = 2;
public static final int DHCP_IPV6_ONLY = 3;
+ public static final int DHCP_REFRESH_FAILURE = 4;
// Internal messages.
private static final int PRIVATE_BASE = IpClient.DHCPCLIENT_CMD_BASE + 100;
@@ -391,6 +392,7 @@
private State mIpAddressConflictDetectingState = new IpAddressConflictDetectingState();
private State mDhcpDecliningState = new DhcpDecliningState();
private State mIpv6OnlyWaitState = new Ipv6OnlyWaitState();
+ private State mDhcpRefreshingAddressState = new DhcpRefreshingAddressState();
private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
@@ -499,6 +501,7 @@
addState(mDhcpRenewingState, mDhcpHaveLeaseState);
addState(mDhcpRebindingState, mDhcpHaveLeaseState);
addState(mDhcpDecliningState, mDhcpHaveLeaseState);
+ addState(mDhcpRefreshingAddressState, mDhcpHaveLeaseState);
addState(mDhcpInitRebootState, mDhcpState);
addState(mDhcpRebootingState, mDhcpState);
// CHECKSTYLE:ON IndentationCheck
@@ -849,11 +852,11 @@
CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
}
- private void notifyFailure() {
+ private void notifyFailure(int arg) {
if (isDhcpLeaseCacheEnabled()) {
setLeaseExpiredToIpMemoryStore();
}
- mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
+ mController.sendMessage(CMD_POST_DHCP_ACTION, arg, 0, null);
}
private void acceptDhcpResults(DhcpResults results, String msg) {
@@ -1049,7 +1052,7 @@
if (mDhcpPacketHandler.start()) return;
Log.e(TAG, "Fail to start DHCP Packet Handler");
}
- notifyFailure();
+ notifyFailure(DHCP_FAILURE);
// We cannot call transitionTo because a transition is still in progress.
// Instead, ensure that we process CMD_STOP_DHCP as soon as the transition is complete.
deferMessage(obtainMessage(CMD_STOP_DHCP));
@@ -1454,7 +1457,7 @@
switch (message.what) {
case CMD_EXPIRE_DHCP:
Log.d(TAG, "Lease expired!");
- notifyFailure();
+ notifyFailure(DHCP_FAILURE);
transitionTo(mStoppedState);
return HANDLED;
default:
@@ -1766,7 +1769,7 @@
// return an IPv4 address from another interface, or even return "0.0.0.0".
//
// TODO: Consider deleting this check, following testing on several kernels.
- notifyFailure();
+ notifyFailure(DHCP_FAILURE);
transitionTo(mStoppedState);
}
@@ -1788,7 +1791,7 @@
preDhcpTransitionTo(mWaitBeforeRenewalState, mDhcpRenewingState);
return HANDLED;
case CMD_REFRESH_LINKADDRESS:
- transitionTo(mDhcpRebindingState);
+ transitionTo(mDhcpRefreshingAddressState);
return HANDLED;
default:
return NOT_HANDLED;
@@ -1816,6 +1819,10 @@
protected abstract Inet4Address packetDestination();
+ // Check whether DhcpClient should notify provisioning failure when receiving DHCPNAK
+ // in renew/rebind state or just restart reconfiguration from StoppedState.
+ protected abstract boolean shouldRestartOnNak();
+
protected boolean sendPacket() {
return sendRequestPacket(
(Inet4Address) mDhcpLease.ipAddress.getAddress(), // ciaddr
@@ -1834,7 +1841,7 @@
if (results != null) {
if (!mDhcpLease.ipAddress.equals(results.ipAddress)) {
Log.d(TAG, "Renewed lease not for our current IP address!");
- notifyFailure();
+ notifyFailure(DHCP_FAILURE);
transitionTo(mStoppedState);
return;
}
@@ -1850,7 +1857,7 @@
}
} else if (packet instanceof DhcpNakPacket) {
Log.d(TAG, "Received NAK, returning to StoppedState");
- notifyFailure();
+ notifyFailure(shouldRestartOnNak() ? DHCP_REFRESH_FAILURE : DHCP_FAILURE);
transitionTo(mStoppedState);
}
}
@@ -1883,6 +1890,11 @@
return (mDhcpLease.serverAddress != null) ?
mDhcpLease.serverAddress : INADDR_BROADCAST;
}
+
+ @Override
+ protected boolean shouldRestartOnNak() {
+ return false;
+ }
}
class DhcpRebindingState extends DhcpReacquiringState {
@@ -1907,6 +1919,22 @@
protected Inet4Address packetDestination() {
return INADDR_BROADCAST;
}
+
+ @Override
+ protected boolean shouldRestartOnNak() {
+ return false;
+ }
+ }
+
+ class DhcpRefreshingAddressState extends DhcpRebindingState {
+ DhcpRefreshingAddressState() {
+ mLeaseMsg = "Refreshing address";
+ }
+
+ @Override
+ protected boolean shouldRestartOnNak() {
+ return true;
+ }
}
class DhcpInitRebootState extends DhcpRequestingState {
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index a81ab5c..00aa599 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -21,6 +21,8 @@
import static android.net.ip.IIpClient.PROV_IPV4_DISABLED;
import static android.net.ip.IIpClient.PROV_IPV6_DISABLED;
import static android.net.ip.IIpClient.PROV_IPV6_LINKLOCAL;
+import static android.net.ip.IpReachabilityMonitor.INVALID_REACHABILITY_LOSS_TYPE;
+import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
import static android.net.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION;
import static android.net.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION;
import static android.net.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION;
@@ -63,6 +65,8 @@
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpManagerEvent;
import android.net.networkstack.aidl.dhcp.DhcpOption;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
+import android.net.networkstack.aidl.ip.ReachabilityLossReason;
import android.net.shared.InitialConfiguration;
import android.net.shared.Layer2Information;
import android.net.shared.ProvisioningConfiguration;
@@ -81,6 +85,7 @@
import android.os.SystemClock;
import android.stats.connectivity.DisconnectCode;
import android.stats.connectivity.NetworkQuirkEvent;
+import android.stats.connectivity.NudEventType;
import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
@@ -316,6 +321,11 @@
/**
* Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of
* required neighbors (e.g. on-link default gw or dns servers) due to NUD_FAILED.
+ *
+ * Note this method is only supported on networkstack-aidl-interfaces-v12 or below.
+ * For above aidl versions, the caller should call {@link onReachabilityFailure} instead.
+ * For callbacks extending IpClientCallbacks, this method will be called iff the callback
+ * does not implement onReachabilityFailure.
*/
public void onReachabilityLost(String logMsg) {
log("onReachabilityLost(" + logMsg + ")");
@@ -402,6 +412,20 @@
}
/**
+ * Called when Neighbor Unreachability Detection fails, that might be caused by the organic
+ * probe or probeAll from IpReachabilityMonitor (if enabled).
+ */
+ public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
+ log("onReachabilityFailure(" + lossInfo.message + ", loss reason: "
+ + reachabilityLossReasonToString(lossInfo.reason) + ")");
+ try {
+ mCallback.onReachabilityFailure(lossInfo);
+ } catch (RemoteException e) {
+ log("Failed to call onReachabilityFailure", e);
+ }
+ }
+
+ /**
* Get the version of the IIpClientCallbacks AIDL interface.
*/
public int getInterfaceVersion() {
@@ -478,6 +502,10 @@
private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
+ // onReachabilityFailure callback is added since networkstack-aidl-interfaces-v13.
+ @VisibleForTesting
+ static final int VERSION_ADDED_REACHABILITY_FAILURE = 13;
+
// Specific vendor OUI(3 bytes)/vendor specific type(1 byte) pattern for upstream hotspot
// device detection. Add new byte array pattern below in turn.
private static final List<byte[]> METERED_IE_PATTERN_LIST = Collections.unmodifiableList(
@@ -1250,6 +1278,20 @@
transitionTo(mStoppingState);
}
+ // Convert reachability loss reason enum to a string.
+ private static String reachabilityLossReasonToString(int reason) {
+ switch (reason) {
+ case ReachabilityLossReason.ROAM:
+ return "reachability_loss_after_roam";
+ case ReachabilityLossReason.CONFIRM:
+ return "reachability_loss_after_confirm";
+ case ReachabilityLossReason.ORGANIC:
+ return "reachability_loss_organic";
+ default:
+ return "unknown";
+ }
+ }
+
private static boolean hasIpv6LinkLocalInterfaceRoute(final LinkProperties lp) {
for (RouteInfo r : lp.getRoutes()) {
if (r.getDestination().equals(new IpPrefix("fe80::/64"))
@@ -1859,8 +1901,17 @@
mLog,
new IpReachabilityMonitor.Callback() {
@Override
- public void notifyLost(InetAddress ip, String logMsg) {
- mCallback.onReachabilityLost(logMsg);
+ public void notifyLost(InetAddress ip, String logMsg, NudEventType type) {
+ final int version = mCallback.getInterfaceVersion();
+ if (version >= VERSION_ADDED_REACHABILITY_FAILURE) {
+ final int reason = nudEventTypeToInt(type);
+ if (reason == INVALID_REACHABILITY_LOSS_TYPE) return;
+ final ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable(logMsg, reason);
+ mCallback.onReachabilityFailure(lossInfo);
+ } else {
+ mCallback.onReachabilityLost(logMsg);
+ }
}
},
mConfiguration.mUsingMultinetworkPolicyTracker,
@@ -1938,18 +1989,18 @@
// If the BSSID has not changed, there is nothing to do.
if (info.bssid.equals(mCurrentBssid)) return;
- // Before trigger probing to the interesting neighbors, send Gratuitous ARP
+ // Before trigger probing to the critical neighbors, send Gratuitous ARP
// and Neighbor Advertisment in advance to propgate host's IPv4/v6 addresses.
if (isGratuitousArpNaRoamingEnabled()) {
maybeSendGratuitousARP(mLinkProperties);
maybeSendGratuitousNAs(mLinkProperties, true /* isGratuitousNaAfterRoaming */);
}
- if (mIpReachabilityMonitor != null) {
- mIpReachabilityMonitor.probeAll(true /* dueToRoam */);
- }
-
- // Check whether to refresh previous IP lease on L2 roaming happened.
+ // Check whether attempting to refresh previous IP lease on specific networks or need to
+ // probe the critical neighbors proactively on L2 roaming happened. The NUD probe on the
+ // specific networks is cancelled because otherwise the probe will happen in parallel with
+ // DHCP refresh, it will be difficult to understand what happened exactly and error-prone
+ // to introduce race condition.
final String ssid = removeDoubleQuotes(mConfiguration.mDisplayName);
if (DHCP_ROAMING_SSID_SET.contains(ssid) && mDhcpClient != null) {
if (DBG) {
@@ -1959,6 +2010,8 @@
+ " , starting refresh leased IP address");
}
mDhcpClient.sendMessage(DhcpClient.CMD_REFRESH_LINKADDRESS);
+ } else if (mIpReachabilityMonitor != null) {
+ mIpReachabilityMonitor.probeAll(true /* dueToRoam */);
}
mCurrentBssid = info.bssid;
}
@@ -2549,6 +2602,20 @@
break;
case DhcpClient.DHCP_IPV6_ONLY:
break;
+ case DhcpClient.DHCP_REFRESH_FAILURE:
+ // This case should only happen on the receipt of DHCPNAK when
+ // refreshing IP address post L2 roaming on some specific networks.
+ // WiFi should try to restart a new provisioning immediately without
+ // disconnecting L2 when it receives DHCP roaming failure event. IPv4
+ // link address still will be cleared when DhcpClient transits to
+ // StoppedState from RefreshingAddress State, although it will result
+ // in a following onProvisioningFailure then, WiFi should ignore this
+ // failure and start a new DHCP reconfiguration from INIT state.
+ final ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable("DHCP refresh failure",
+ ReachabilityLossReason.ROAM);
+ mCallback.onReachabilityFailure(lossInfo);
+ break;
default:
logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
}
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java
index 6b883f3..c716fdf 100644
--- a/src/android/net/ip/IpReachabilityMonitor.java
+++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -32,6 +32,7 @@
import android.net.ip.IpNeighborMonitor.NeighborEventConsumer;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpReachabilityEvent;
+import android.net.networkstack.aidl.ip.ReachabilityLossReason;
import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.ConditionVariable;
@@ -157,6 +158,7 @@
private static final int INVALID_NUD_MCAST_RESOLICIT_NUM = -1;
private static final int INVALID_LEGACY_NUD_FAILURE_TYPE = -1;
+ public static final int INVALID_REACHABILITY_LOSS_TYPE = -1;
public interface Callback {
/**
@@ -165,7 +167,7 @@
*
* TODO: refactor to something like notifyProvisioningLost(String msg).
*/
- void notifyLost(InetAddress ip, String logMsg);
+ void notifyLost(InetAddress ip, String logMsg, NudEventType type);
}
/**
@@ -408,10 +410,11 @@
final String logMsg = "ALERT neighbor: " + event.ip
+ " MAC address changed from: " + prev.macAddr
+ " to: " + event.macAddr;
+ final NudEventType type =
+ getMacAddressChangedEventType(isFromProbe(), isNudFailureDueToRoam());
mLog.w(logMsg);
- mCallback.notifyLost(event.ip, logMsg);
- logNudFailed(event,
- getMacAddressChangedEventType(isFromProbe(), isNudFailureDueToRoam()));
+ mCallback.notifyLost(event.ip, logMsg, type);
+ logNudFailed(event, type);
return;
}
maybeRestoreNeighborParameters();
@@ -458,7 +461,7 @@
Log.w(TAG, logMsg);
// TODO: remove |ip| when the callback signature no longer has
// an InetAddress argument.
- mCallback.notifyLost(ip, logMsg);
+ mCallback.notifyLost(ip, logMsg, type);
}
logNudFailed(event, type);
}
@@ -520,7 +523,9 @@
private long getProbeWakeLockDuration() {
final long gracePeriodMs = 500;
- return (long) (mNumSolicits * mInterSolicitIntervalMs) + gracePeriodMs;
+ final int numSolicits =
+ mNumSolicits + (isMulticastResolicitEnabled() ? NUD_MCAST_RESOLICIT_NUM : 0);
+ return (long) (numSolicits * mInterSolicitIntervalMs) + gracePeriodMs;
}
private void setNeighbourParametersPostRoaming() {
@@ -571,7 +576,7 @@
}
}
- mNumSolicits = isMulticastResolicitEnabled() ? (numSolicits + numResolicits) : numSolicits;
+ mNumSolicits = numSolicits;
mInterSolicitIntervalMs = interSolicitIntervalMs;
}
@@ -691,4 +696,24 @@
return INVALID_LEGACY_NUD_FAILURE_TYPE;
}
}
+
+ /**
+ * Convert the NUD critical failure event type to a int constant defined in IIpClientCallbacks.
+ */
+ public static int nudEventTypeToInt(final NudEventType type) {
+ switch (type) {
+ case NUD_POST_ROAMING_FAILED_CRITICAL:
+ case NUD_POST_ROAMING_MAC_ADDRESS_CHANGED:
+ return ReachabilityLossReason.ROAM;
+ case NUD_CONFIRM_FAILED_CRITICAL:
+ case NUD_CONFIRM_MAC_ADDRESS_CHANGED:
+ return ReachabilityLossReason.CONFIRM;
+ case NUD_ORGANIC_FAILED_CRITICAL:
+ case NUD_ORGANIC_MAC_ADDRESS_CHANGED:
+ return ReachabilityLossReason.ORGANIC;
+ // For other NudEventType which won't trigger notifyLost, just ignore these events.
+ default:
+ return INVALID_REACHABILITY_LOSS_TYPE;
+ }
+ }
}
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
index 748ee5a..fa379d3 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
@@ -21,8 +21,6 @@
import android.net.ipmemorystore.Status
import android.net.ipmemorystore.Status.SUCCESS
import android.util.ArrayMap
-import java.net.Inet6Address
-import kotlin.test.assertEquals
import org.mockito.Mockito.any
import org.mockito.Mockito.doAnswer
import org.mockito.ArgumentCaptor
@@ -63,17 +61,6 @@
verify(mIpMemoryStore, never()).storeNetworkAttributes(eq(l2Key), any(), any())
}
- override fun assertNotifyNeighborLost(targetIp: Inet6Address) {
- val target = ArgumentCaptor.forClass(Inet6Address::class.java)
-
- verify(mCallback, timeout(TEST_TIMEOUT_MS)).notifyLost(target.capture(), any())
- assertEquals(targetIp, target.getValue())
- }
-
- override fun assertNeverNotifyNeighborLost() {
- verify(mCallback, never()).notifyLost(any(), any())
- }
-
override fun storeNetworkAttributes(l2Key: String, na: NetworkAttributes) {
doAnswer { inv ->
val listener = inv.getArgument<OnNetworkAttributesRetrievedListener>(1)
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index afe0990..22a4844 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -29,8 +29,8 @@
import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable;
import static android.net.ip.IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM;
import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM;
+import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
import static android.net.ipmemorystore.Status.SUCCESS;
-import static android.net.shared.ProvisioningConfiguration.VERSION_ADDED_PROVISIONING_ENUM;
import static android.system.OsConstants.ETH_P_IPV6;
import static android.system.OsConstants.IFA_F_TEMPORARY;
import static android.system.OsConstants.IPPROTO_ICMPV6;
@@ -125,6 +125,8 @@
import android.net.ipmemorystore.Status;
import android.net.networkstack.TestNetworkStackServiceClient;
import android.net.networkstack.aidl.dhcp.DhcpOption;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
+import android.net.networkstack.aidl.ip.ReachabilityLossReason;
import android.net.shared.Layer2Information;
import android.net.shared.ProvisioningConfiguration;
import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
@@ -141,6 +143,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.stats.connectivity.NetworkQuirkEvent;
+import android.stats.connectivity.NudEventType;
import android.system.ErrnoException;
import android.system.Os;
@@ -156,6 +159,7 @@
import com.android.net.module.util.structs.LlaOption;
import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.net.module.util.structs.RdnssOption;
+import com.android.networkstack.R;
import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.common.ShimUtils;
@@ -291,7 +295,6 @@
@Mock protected NetworkStackIpMemoryStore mIpMemoryStore;
@Mock private NetworkQuirkMetrics.Dependencies mNetworkQuirkMetricsDeps;
@Mock private IpReachabilityMonitorMetrics mIpReachabilityMonitorMetrics;
- @Mock protected IpReachabilityMonitor.Callback mCallback;
@Spy private INetd mNetd;
private NetworkObserverRegistry mNetworkObserverRegistry;
@@ -437,7 +440,7 @@
InterfaceParams ifParams, Handler h, SharedLog log,
IpReachabilityMonitor.Callback callback, boolean usingMultinetworkPolicyTracker,
IpReachabilityMonitor.Dependencies deps, final INetd netd) {
- return new IpReachabilityMonitor(context, ifParams, h, log, mCallback,
+ return new IpReachabilityMonitor(context, ifParams, h, log, callback,
usingMultinetworkPolicyTracker, deps, netd);
}
@@ -541,10 +544,6 @@
protected abstract void assertIpMemoryNeverStoreNetworkAttributes(String l2Key, long timeout);
- protected abstract void assertNotifyNeighborLost(Inet6Address targetIp);
-
- protected abstract void assertNeverNotifyNeighborLost();
-
protected final boolean testSkipped() {
// TODO: split out a test suite for root tests, and fail hard instead of skipping the test
// if it is run on devices where TestNetworkStackServiceClient is not supported
@@ -607,10 +606,17 @@
when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm);
when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getInteger(eq(R.integer.config_nud_postroaming_solicit_num))).thenReturn(5);
+ when(mResources.getInteger(eq(R.integer.config_nud_postroaming_solicit_interval)))
+ .thenReturn(750);
+ when(mResources.getInteger(eq(R.integer.config_nud_steadystate_solicit_num)))
+ .thenReturn(10);
+ when(mResources.getInteger(eq(R.integer.config_nud_steadystate_solicit_interval)))
+ .thenReturn(750);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mNetworkStackServiceManager.getIpMemoryStoreService())
.thenReturn(mIpMemoryStoreService);
- when(mCb.getInterfaceVersion()).thenReturn(VERSION_ADDED_PROVISIONING_ENUM);
+ when(mCb.getInterfaceVersion()).thenReturn(IpClient.VERSION_ADDED_REACHABILITY_FAILURE);
mDependencies.setDeviceConfigProperty(IpClient.CONFIG_MIN_RDNSS_LIFETIME, 67);
mDependencies.setDeviceConfigProperty(DhcpClient.DHCP_RESTART_CONFIG_DELAY, 10);
@@ -2546,12 +2552,23 @@
mPacketReader.sendResponse(packetBuffer);
HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
- if (shouldReplyNakOnRoam || hasMismatchedIpAddress) {
- // notifyFailure
- ArgumentCaptor<DhcpResultsParcelable> captor =
+ if (shouldReplyNakOnRoam) {
+ ArgumentCaptor<ReachabilityLossInfoParcelable> lossInfoCaptor =
+ ArgumentCaptor.forClass(ReachabilityLossInfoParcelable.class);
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityFailure(lossInfoCaptor.capture());
+ assertEquals(ReachabilityLossReason.ROAM, lossInfoCaptor.getValue().reason);
+
+ // IPv4 address will be still deleted when DhcpClient state machine exits from
+ // DhcpHaveLeaseState, a following onProvisioningFailure will be thrown then.
+ // Also check DhcpClient won't send any DHCPDISCOVER packet.
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(any());
+ assertNull(getNextDhcpPacket(TEST_TIMEOUT_MS));
+ verify(mCb, never()).onNewDhcpResults(any());
+ } else if (hasMismatchedIpAddress) {
+ ArgumentCaptor<DhcpResultsParcelable> resultsCaptor =
ArgumentCaptor.forClass(DhcpResultsParcelable.class);
- verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(captor.capture());
- DhcpResults lease = fromStableParcelable(captor.getValue());
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(resultsCaptor.capture());
+ DhcpResults lease = fromStableParcelable(resultsCaptor.getValue());
assertNull(lease);
// DhcpClient rolls back to StoppedState instead of INIT state after calling
@@ -3459,6 +3476,38 @@
prepareIpReachabilityMonitorTest(false /* isMulticastResolicitEnabled */);
}
+ private void assertNotifyNeighborLost(Inet6Address targetIp, NudEventType eventType)
+ throws Exception {
+ // For root test suite, rely on the IIpClient aidl interface version constant defined in
+ // {@link IpClientRootTest.BinderCbWrapper}; for privileged integration test suite that
+ // requires signature permission, use the mocked aidl version defined in {@link setUpMocks},
+ // which results in only new callbacks are verified. And add separate test cases to test the
+ // legacy callbacks explicitly as well.
+ assertNeighborReachabilityLoss(targetIp, eventType,
+ useNetworkStackSignature()
+ ? IpClient.VERSION_ADDED_REACHABILITY_FAILURE
+ : mIIpClient.getInterfaceVersion());
+ }
+
+ private void assertNeighborReachabilityLoss(Inet6Address targetIp, NudEventType eventType,
+ int targetAidlVersion) throws Exception {
+ if (targetAidlVersion >= IpClient.VERSION_ADDED_REACHABILITY_FAILURE) {
+ final ArgumentCaptor<ReachabilityLossInfoParcelable> lossInfoCaptor =
+ ArgumentCaptor.forClass(ReachabilityLossInfoParcelable.class);
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityFailure(lossInfoCaptor.capture());
+ assertEquals(nudEventTypeToInt(eventType), lossInfoCaptor.getValue().reason);
+ verify(mCb, never()).onReachabilityLost(any());
+ } else {
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any());
+ verify(mCb, never()).onReachabilityFailure(any());
+ }
+ }
+
+ private void assertNeverNotifyNeighborLost() throws Exception {
+ verify(mCb, never()).onReachabilityFailure(any());
+ verify(mCb, never()).onReachabilityLost(any());
+ }
+
private void prepareIpReachabilityMonitorTest(boolean isMulticastResolicitEnabled)
throws Exception {
final ScanResultInfo info = makeScanResultInfo(TEST_DEFAULT_SSID, TEST_DEFAULT_BSSID);
@@ -3479,8 +3528,7 @@
forceLayer2Roaming();
}
- @Test
- public void testIpReachabilityMonitor_probeFailed() throws Exception {
+ private void runIpReachabilityMonitorProbeFailedTest() throws Exception {
prepareIpReachabilityMonitorTest();
final List<NeighborSolicitation> nsList = waitForMultipleNeighborSolicitations();
@@ -3489,7 +3537,22 @@
assertUnicastNeighborSolicitation(ns, ROUTER_MAC /* dstMac */,
ROUTER_LINK_LOCAL /* dstIp */, ROUTER_LINK_LOCAL /* targetIp */);
}
- assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
+ }
+
+ @Test
+ public void testIpReachabilityMonitor_probeFailed() throws Exception {
+ runIpReachabilityMonitorProbeFailedTest();
+ assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */,
+ NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL);
+ }
+
+ @Test @SignatureRequiredTest(reason = "requires mock callback object")
+ public void testIpReachabilityMonitor_probeFailed_legacyCallback() throws Exception {
+ when(mCb.getInterfaceVersion()).thenReturn(12 /* assign an older interface aidl version */);
+
+ runIpReachabilityMonitorProbeFailedTest();
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any());
+ verify(mCb, never()).onReachabilityFailure(any());
}
@Test
@@ -3508,8 +3571,7 @@
assertNeverNotifyNeighborLost();
}
- @Test
- public void testIpReachabilityMonitor_mcastResoclicitProbeFailed() throws Exception {
+ private void runIpReachabilityMonitorMcastResolicitProbeFailedTest() throws Exception {
prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */);
final List<NeighborSolicitation> nsList = waitForMultipleNeighborSolicitations();
@@ -3522,11 +3584,27 @@
for (NeighborSolicitation ns : nsList.subList(MIN_NUD_SOLICIT_NUM, nsList.size())) {
assertMulticastNeighborSolicitation(ns, ROUTER_LINK_LOCAL /* targetIp */);
}
- assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
}
@Test
- public void testIpReachabilityMonitor_mcastResoclicitProbeReachableWithSameLinkLayerAddress()
+ public void testIpReachabilityMonitor_mcastResolicitProbeFailed() throws Exception {
+ runIpReachabilityMonitorMcastResolicitProbeFailedTest();
+ assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */,
+ NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL);
+ }
+
+ @Test @SignatureRequiredTest(reason = "requires mock callback object")
+ public void testIpReachabilityMonitor_mcastResolicitProbeFailed_legacyCallback()
+ throws Exception {
+ when(mCb.getInterfaceVersion()).thenReturn(12 /* assign an older interface aidl version */);
+
+ runIpReachabilityMonitorMcastResolicitProbeFailedTest();
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any());
+ verify(mCb, never()).onReachabilityFailure(any());
+ }
+
+ @Test
+ public void testIpReachabilityMonitor_mcastResolicitProbeReachableWithSameLinkLayerAddress()
throws Exception {
prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */);
@@ -3543,7 +3621,7 @@
}
@Test
- public void testIpReachabilityMonitor_mcastResoclicitProbeReachableWithDiffLinkLayerAddress()
+ public void testIpReachabilityMonitor_mcastResolicitProbeReachableWithDiffLinkLayerAddress()
throws Exception {
prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */);
@@ -3562,7 +3640,8 @@
ns.ethHdr.srcMac /* dstMac */, ROUTER_LINK_LOCAL /* srcIp */,
ns.ipv6Hdr.srcIp /* dstIp */, flag, ROUTER_LINK_LOCAL /* target */);
mPacketReader.sendResponse(na);
- assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
+ assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */,
+ NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED);
}
@Test
diff --git a/tests/integration/src/android/net/ip/IpClientRootTest.kt b/tests/integration/src/android/net/ip/IpClientRootTest.kt
index d861639..7359e05 100644
--- a/tests/integration/src/android/net/ip/IpClientRootTest.kt
+++ b/tests/integration/src/android/net/ip/IpClientRootTest.kt
@@ -33,7 +33,6 @@
import androidx.test.platform.app.InstrumentationRegistry
import com.android.net.module.util.DeviceConfigUtils
import java.lang.System.currentTimeMillis
-import java.net.Inet6Address
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
@@ -46,8 +45,6 @@
import org.junit.AfterClass
import org.junit.BeforeClass
import org.mockito.ArgumentCaptor
-import org.mockito.Mockito.anyString
-import org.mockito.Mockito.never
import org.mockito.Mockito.timeout
import org.mockito.Mockito.verify
@@ -265,14 +262,6 @@
assertNull(listener.getBlockingNetworkAttributes(timeout))
}
- override fun assertNotifyNeighborLost(targetIp: Inet6Address) {
- verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(anyString())
- }
-
- override fun assertNeverNotifyNeighborLost() {
- verify(mCb, never()).onReachabilityLost(anyString())
- }
-
override fun storeNetworkAttributes(l2Key: String, na: NetworkAttributes) {
mStore.storeNetworkAttributes(l2Key, na, null /* listener */)
}
diff --git a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
index 5245cc3..246f000 100644
--- a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
+++ b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
@@ -287,10 +287,15 @@
reachabilityMonitor.updateLinkProperties(TEST_LINK_PROPERTIES)
neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_FAILED))
- verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString())
+ verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString(),
+ eq(NUD_ORGANIC_FAILED_CRITICAL))
}
- private fun runLoseProvisioningTest(newLp: LinkProperties, lostNeighbor: InetAddress) {
+ private fun runLoseProvisioningTest(
+ newLp: LinkProperties,
+ lostNeighbor: InetAddress,
+ eventType: NudEventType
+ ) {
reachabilityMonitor.updateLinkProperties(newLp)
neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_STALE))
@@ -299,7 +304,8 @@
neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_STALE))
neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
- verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString())
+ verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString(),
+ eq(eventType))
}
private fun verifyNudFailureMetrics(
@@ -327,7 +333,7 @@
neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
handlerThread.waitForIdle(TEST_TIMEOUT_MS)
- verify(callback, never()).notifyLost(any(), anyString())
+ verify(callback, never()).notifyLost(any(), anyString(), any(NudEventType::class.java))
verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
}
@@ -343,27 +349,30 @@
neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
"001122334455" /* oldMac */))
handlerThread.waitForIdle(TEST_TIMEOUT_MS)
- verify(callback, never()).notifyLost(eq(neighbor), anyString())
+ verify(callback, never()).notifyLost(eq(neighbor), anyString(),
+ any(NudEventType::class.java))
}
@Test
fun testLoseProvisioning_Ipv4DnsLost() {
- runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS)
+ runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS, NUD_ORGANIC_FAILED_CRITICAL)
}
@Test
fun testLoseProvisioning_Ipv6DnsLost() {
- runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS)
+ runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS, NUD_ORGANIC_FAILED_CRITICAL)
}
@Test
fun testLoseProvisioning_Ipv4GatewayLost() {
- runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY)
+ runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY,
+ NUD_ORGANIC_FAILED_CRITICAL)
}
@Test
fun testLoseProvisioning_Ipv6GatewayLost() {
- runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+ runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
+ NUD_ORGANIC_FAILED_CRITICAL)
}
private fun runNudProbeFailureMetricsTest(
@@ -373,7 +382,7 @@
ipType: IpType,
lostNeighborType: NudNeighborType
) {
- runLoseProvisioningTest(lp, lostNeighbor)
+ runLoseProvisioningTest(lp, lostNeighbor, eventType)
verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
}
@@ -526,7 +535,8 @@
handlerThread.waitForIdle(TEST_TIMEOUT_MS)
Thread.sleep(2)
reachabilityMonitor.probeAll(false /* dueToRoam */)
- runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+ runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
+ NUD_POST_ROAMING_FAILED_CRITICAL)
verifyNudFailureMetrics(NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
}
@@ -537,7 +547,8 @@
handlerThread.waitForIdle(TEST_TIMEOUT_MS)
Thread.sleep(2)
reachabilityMonitor.probeAll(true /* dueToRoam */)
- runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+ runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
+ NUD_CONFIRM_FAILED_CRITICAL)
verifyNudFailureMetrics(NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
}
@@ -549,7 +560,8 @@
) {
neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
"1122334455aa" /* newMac */))
- verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString())
+ verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString(),
+ eq(eventType))
verifyNudFailureMetrics(eventType, ipType, NUD_NEIGHBOR_GATEWAY)
}