Snap for 6417465 from ad89080ba2dd7bf789abb8e538a2ac6c8b5adec2 to mainline-release

Change-Id: Ie94a81b8cea99a2f626daa5598d92a998de3399d
This commit is contained in:
android-build-team Robot
2020-04-22 07:09:26 +00:00
5 changed files with 293 additions and 35 deletions

View File

@@ -5889,6 +5889,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) { private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
lp.ensureDirectlyConnectedRoutes(); lp.ensureDirectlyConnectedRoutes();
nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
} }
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp, private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,

View File

@@ -81,15 +81,23 @@ public class Nat464Xlat extends BaseNetworkObserver {
RUNNING, // start() called, and the stacked iface is known to be up. RUNNING, // start() called, and the stacked iface is known to be up.
} }
/** NAT64 prefix currently in use. Only valid in STARTING or RUNNING states. */ /**
* NAT64 prefix currently in use. Only valid in STARTING or RUNNING states.
* Used, among other things, to avoid updates when switching from a prefix learned from one
* source (e.g., RA) to the same prefix learned from another source (e.g., RA).
*/
private IpPrefix mNat64PrefixInUse; private IpPrefix mNat64PrefixInUse;
/** NAT64 prefix (if any) discovered from DNS via RFC 7050. */ /** NAT64 prefix (if any) discovered from DNS via RFC 7050. */
private IpPrefix mNat64PrefixFromDns; private IpPrefix mNat64PrefixFromDns;
/** NAT64 prefix (if any) learned from the network via RA. */
private IpPrefix mNat64PrefixFromRa;
private String mBaseIface; private String mBaseIface;
private String mIface; private String mIface;
private Inet6Address mIPv6Address; private Inet6Address mIPv6Address;
private State mState = State.IDLE; private State mState = State.IDLE;
private boolean mPrefixDiscoveryRunning;
public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver, public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
INetworkManagementService nmService) { INetworkManagementService nmService) {
mDnsResolver = dnsResolver; mDnsResolver = dnsResolver;
@@ -138,15 +146,6 @@ public class Nat464Xlat extends BaseNetworkObserver {
return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null; return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null;
} }
/**
* @return true if we have started prefix discovery and not yet stopped it (regardless of
* whether it is still running or has succeeded).
* A true result corresponds to internal states DISCOVERING, STARTING and RUNNING.
*/
public boolean isPrefixDiscoveryStarted() {
return mState == State.DISCOVERING || isStarted();
}
/** /**
* @return true if clatd has been started and has not yet stopped. * @return true if clatd has been started and has not yet stopped.
* A true result corresponds to internal states STARTING and RUNNING. * A true result corresponds to internal states STARTING and RUNNING.
@@ -181,7 +180,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
return; return;
} }
mNat64PrefixInUse = getNat64Prefix(); mNat64PrefixInUse = selectNat64Prefix();
String addrStr = null; String addrStr = null;
try { try {
addrStr = mNetd.clatdStart(baseIface, mNat64PrefixInUse.toString()); addrStr = mNetd.clatdStart(baseIface, mNat64PrefixInUse.toString());
@@ -196,6 +195,9 @@ public class Nat464Xlat extends BaseNetworkObserver {
} catch (ClassCastException | IllegalArgumentException | NullPointerException e) { } catch (ClassCastException | IllegalArgumentException | NullPointerException e) {
Slog.e(TAG, "Invalid IPv6 address " + addrStr); Slog.e(TAG, "Invalid IPv6 address " + addrStr);
} }
if (mPrefixDiscoveryRunning && !isPrefixDiscoveryNeeded()) {
stopPrefixDiscovery();
}
} }
/** /**
@@ -218,10 +220,15 @@ public class Nat464Xlat extends BaseNetworkObserver {
mNat64PrefixInUse = null; mNat64PrefixInUse = null;
mIface = null; mIface = null;
mBaseIface = null; mBaseIface = null;
if (requiresClat(mNetwork)) {
if (isPrefixDiscoveryNeeded()) {
if (!mPrefixDiscoveryRunning) {
startPrefixDiscovery();
}
mState = State.DISCOVERING; mState = State.DISCOVERING;
} else { } else {
stopPrefixDiscovery(); // Enters IDLE state. stopPrefixDiscovery();
mState = State.IDLE;
} }
} }
@@ -282,7 +289,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e); Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
} }
mState = State.DISCOVERING; mPrefixDiscoveryRunning = true;
} }
private void stopPrefixDiscovery() { private void stopPrefixDiscovery() {
@@ -291,11 +298,18 @@ public class Nat464Xlat extends BaseNetworkObserver {
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e); Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
} }
mState = State.IDLE; mPrefixDiscoveryRunning = false;
}
private boolean isPrefixDiscoveryNeeded() {
// If there is no NAT64 prefix in the RA, prefix discovery is always needed. It cannot be
// stopped after it succeeds, because stopping it will cause netd to report that the prefix
// has been removed, and that will cause us to stop clatd.
return requiresClat(mNetwork) && mNat64PrefixFromRa == null;
} }
private void maybeHandleNat64PrefixChange() { private void maybeHandleNat64PrefixChange() {
final IpPrefix newPrefix = getNat64Prefix(); final IpPrefix newPrefix = selectNat64Prefix();
if (!Objects.equals(mNat64PrefixInUse, newPrefix)) { if (!Objects.equals(mNat64PrefixInUse, newPrefix)) {
Slog.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to " Slog.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to "
+ newPrefix); + newPrefix);
@@ -314,13 +328,11 @@ public class Nat464Xlat extends BaseNetworkObserver {
// TODO: turn this class into a proper StateMachine. http://b/126113090 // TODO: turn this class into a proper StateMachine. http://b/126113090
switch (mState) { switch (mState) {
case IDLE: case IDLE:
if (requiresClat(mNetwork)) { if (isPrefixDiscoveryNeeded()) {
// Network is detected to be IPv6-only.
// TODO: consider going to STARTING directly if the NAT64 prefix is already
// known. This would however result in clatd running without prefix discovery
// running, which might be a surprising combination.
startPrefixDiscovery(); // Enters DISCOVERING state. startPrefixDiscovery(); // Enters DISCOVERING state.
return; mState = State.DISCOVERING;
} else if (requiresClat(mNetwork)) {
start(); // Enters STARTING state.
} }
break; break;
@@ -333,6 +345,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
if (!requiresClat(mNetwork)) { if (!requiresClat(mNetwork)) {
// IPv4 address added. Go back to IDLE state. // IPv4 address added. Go back to IDLE state.
stopPrefixDiscovery(); stopPrefixDiscovery();
mState = State.IDLE;
return; return;
} }
break; break;
@@ -351,8 +364,20 @@ public class Nat464Xlat extends BaseNetworkObserver {
} }
} }
private IpPrefix getNat64Prefix() { /**
return mNat64PrefixFromDns; * Picks a NAT64 prefix to use. Always prefers the prefix from the RA if one is received from
* both RA and DNS, because the prefix in the RA has better security and updatability, and will
* almost always be received first anyway.
*
* Any network that supports legacy hosts will support discovering the DNS64 prefix via DNS as
* well. If the prefix from the RA is withdrawn, fall back to that for reliability purposes.
*/
private IpPrefix selectNat64Prefix() {
return mNat64PrefixFromRa != null ? mNat64PrefixFromRa : mNat64PrefixFromDns;
}
public void setNat64PrefixFromRa(IpPrefix prefix) {
mNat64PrefixFromRa = prefix;
} }
public void setNat64PrefixFromDns(IpPrefix prefix) { public void setNat64PrefixFromDns(IpPrefix prefix) {
@@ -367,7 +392,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) { public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) {
// This must be done even if clatd is not running, because otherwise shouldStartClat would // This must be done even if clatd is not running, because otherwise shouldStartClat would
// never return true. // never return true.
lp.setNat64Prefix(getNat64Prefix()); lp.setNat64Prefix(selectNat64Prefix());
if (!isRunning()) { if (!isRunning()) {
return; return;

View File

@@ -105,14 +105,43 @@ class NetworkProviderTest {
.build() .build()
val cb = ConnectivityManager.NetworkCallback() val cb = ConnectivityManager.NetworkCallback()
mCm.requestNetwork(nr, cb) mCm.requestNetwork(nr, cb)
provider.expectCallback<OnNetworkRequested>() { provider.expectCallback<OnNetworkRequested>() { callback ->
callback -> callback.request.getNetworkSpecifier() == specifier && callback.request.getNetworkSpecifier() == specifier &&
callback.request.hasTransport(TRANSPORT_TEST) callback.request.hasTransport(TRANSPORT_TEST)
} }
val initialScore = 40
val updatedScore = 60
val nc = NetworkCapabilities().apply {
addTransportType(NetworkCapabilities.TRANSPORT_TEST)
removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
setNetworkSpecifier(specifier)
}
val lp = LinkProperties()
val config = NetworkAgentConfig.Builder().build()
val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc, lp,
initialScore, config, provider) {}
provider.expectCallback<OnNetworkRequested>() { callback ->
callback.request.getNetworkSpecifier() == specifier &&
callback.score == initialScore &&
callback.id == agent.providerId
}
agent.sendNetworkScore(updatedScore)
provider.expectCallback<OnNetworkRequested>() { callback ->
callback.request.getNetworkSpecifier() == specifier &&
callback.score == updatedScore &&
callback.id == agent.providerId
}
mCm.unregisterNetworkCallback(cb) mCm.unregisterNetworkCallback(cb)
provider.expectCallback<OnNetworkRequestWithdrawn>() { provider.expectCallback<OnNetworkRequestWithdrawn>() { callback ->
callback -> callback.request.getNetworkSpecifier() == specifier && callback.request.getNetworkSpecifier() == specifier &&
callback.request.hasTransport(TRANSPORT_TEST) callback.request.hasTransport(TRANSPORT_TEST)
} }
mCm.unregisterNetworkProvider(provider) mCm.unregisterNetworkProvider(provider)

View File

@@ -6179,6 +6179,111 @@ public class ConnectivityServiceTest {
mCm.unregisterNetworkCallback(networkCallback); mCm.unregisterNetworkCallback(networkCallback);
} }
private void expectNat64PrefixChange(TestableNetworkCallback callback,
TestNetworkAgentWrapper agent, IpPrefix prefix) {
callback.expectLinkPropertiesThat(agent, x -> Objects.equals(x.getNat64Prefix(), prefix));
}
@Test
public void testNat64PrefixMultipleSources() throws Exception {
final String iface = "wlan0";
final String pref64FromRaStr = "64:ff9b::";
final String pref64FromDnsStr = "2001:db8:64::";
final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96);
final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96);
final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96");
final NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_INTERNET)
.build();
final TestNetworkCallback callback = new TestNetworkCallback();
mCm.registerNetworkCallback(request, callback);
final LinkProperties baseLp = new LinkProperties();
baseLp.setInterfaceName(iface);
baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464"));
reset(mMockNetd, mMockDnsResolver);
InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver);
// If a network already has a NAT64 prefix on connect, clatd is started immediately and
// prefix discovery is never started.
LinkProperties lp = new LinkProperties(baseLp);
lp.setNat64Prefix(pref64FromRa);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
mCellNetworkAgent.connect(false);
final Network network = mCellNetworkAgent.getNetwork();
int netId = network.getNetId();
callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
callback.assertNoCallback();
assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix());
// If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started.
lp.setNat64Prefix(null);
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, null);
inOrder.verify(mMockNetd).clatdStop(iface);
inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
// If the RA prefix appears while DNS discovery is in progress, discovery is stopped and
// clatd is started with the prefix from the RA.
lp.setNat64Prefix(pref64FromRa);
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromRa);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
// Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS
// discovery has succeeded.
lp.setNat64Prefix(null);
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, null);
inOrder.verify(mMockNetd).clatdStop(iface);
inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
pref64FromDnsStr, 96);
expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromDns);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
// If the RA prefix reappears, clatd is restarted and prefix discovery is stopped.
lp.setNat64Prefix(pref64FromRa);
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromRa);
inOrder.verify(mMockNetd).clatdStop(iface);
inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
// If the RA prefix changes, clatd is restarted and prefix discovery is not started.
lp.setNat64Prefix(newPref64FromRa);
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, newPref64FromRa);
inOrder.verify(mMockNetd).clatdStop(iface);
inOrder.verify(mMockNetd).clatdStart(iface, newPref64FromRa.toString());
inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
// If the RA prefix changes to the same value, nothing happens.
lp.setNat64Prefix(newPref64FromRa);
mCellNetworkAgent.sendLinkProperties(lp);
callback.assertNoCallback();
assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix());
inOrder.verify(mMockNetd, never()).clatdStop(iface);
inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString());
inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
// The transition between no prefix and DNS prefix is tested in testStackedLinkProperties.
callback.assertNoCallback();
mCellNetworkAgent.disconnect();
mCm.unregisterNetworkCallback(callback);
}
@Test @Test
public void testDataActivityTracking() throws Exception { public void testDataActivityTracking() throws Exception {
final TestNetworkCallback networkCallback = new TestNetworkCallback(); final TestNetworkCallback networkCallback = new TestNetworkCallback();

View File

@@ -58,8 +58,10 @@ public class Nat464XlatTest {
static final String BASE_IFACE = "test0"; static final String BASE_IFACE = "test0";
static final String STACKED_IFACE = "v4-test0"; static final String STACKED_IFACE = "v4-test0";
static final LinkAddress V6ADDR = new LinkAddress("2001:db8:1::f00/64");
static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29"); static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29");
static final String NAT64_PREFIX = "64:ff9b::/96"; static final String NAT64_PREFIX = "64:ff9b::/96";
static final String OTHER_NAT64_PREFIX = "2001:db8:0:64::/96";
static final int NETID = 42; static final int NETID = 42;
@Mock ConnectivityService mConnectivity; @Mock ConnectivityService mConnectivity;
@@ -81,6 +83,14 @@ public class Nat464XlatTest {
}; };
} }
private void markNetworkConnected() {
mNai.networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
}
private void markNetworkDisconnected() {
mNai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, "", "");
}
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mLooper = new TestLooper(); mLooper = new TestLooper();
@@ -92,6 +102,7 @@ public class Nat464XlatTest {
mNai.linkProperties.setInterfaceName(BASE_IFACE); mNai.linkProperties.setInterfaceName(BASE_IFACE);
mNai.networkInfo = new NetworkInfo(null); mNai.networkInfo = new NetworkInfo(null);
mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI); mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI);
markNetworkConnected();
when(mNai.connService()).thenReturn(mConnectivity); when(mNai.connService()).thenReturn(mConnectivity);
when(mNai.netAgentConfig()).thenReturn(mAgentConfig); when(mNai.netAgentConfig()).thenReturn(mAgentConfig);
when(mNai.handler()).thenReturn(mHandler); when(mNai.handler()).thenReturn(mHandler);
@@ -139,7 +150,7 @@ public class Nat464XlatTest {
for (NetworkInfo.DetailedState state : supportedDetailedStates) { for (NetworkInfo.DetailedState state : supportedDetailedStates) {
mNai.networkInfo.setDetailedState(state, "reason", "extraInfo"); mNai.networkInfo.setDetailedState(state, "reason", "extraInfo");
mNai.linkProperties.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96")); mNai.linkProperties.setNat64Prefix(new IpPrefix(OTHER_NAT64_PREFIX));
assertRequiresClat(false, mNai); assertRequiresClat(false, mNai);
assertShouldStartClat(false, mNai); assertShouldStartClat(false, mNai);
@@ -176,11 +187,20 @@ public class Nat464XlatTest {
} }
} }
@Test private void makeClatUnnecessary(boolean dueToDisconnect) {
public void testNormalStartAndStop() throws Exception { if (dueToDisconnect) {
markNetworkDisconnected();
} else {
mNai.linkProperties.addLinkAddress(ADDR);
}
}
private void checkNormalStartAndStop(boolean dueToDisconnect) throws Exception {
Nat464Xlat nat = makeNat464Xlat(); Nat464Xlat nat = makeNat464Xlat();
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
mNai.linkProperties.addLinkAddress(V6ADDR);
nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
// Start clat. // Start clat.
@@ -200,6 +220,7 @@ public class Nat464XlatTest {
assertRunning(nat); assertRunning(nat);
// Stop clat (Network disconnects, IPv4 addr appears, ...). // Stop clat (Network disconnects, IPv4 addr appears, ...).
makeClatUnnecessary(dueToDisconnect);
nat.stop(); nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE)); verify(mNetd).clatdStop(eq(BASE_IFACE));
@@ -217,11 +238,23 @@ public class Nat464XlatTest {
verifyNoMoreInteractions(mNetd, mNms, mConnectivity); verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
} }
@Test
public void testNormalStartAndStopDueToDisconnect() throws Exception {
checkNormalStartAndStop(true);
}
@Test
public void testNormalStartAndStopDueToIpv4Addr() throws Exception {
checkNormalStartAndStop(false);
}
private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception { private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception {
Nat464Xlat nat = makeNat464Xlat(); Nat464Xlat nat = makeNat464Xlat();
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
InOrder inOrder = inOrder(mNetd, mConnectivity); InOrder inOrder = inOrder(mNetd, mConnectivity);
mNai.linkProperties.addLinkAddress(V6ADDR);
nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
nat.start(); nat.start();
@@ -344,10 +377,11 @@ public class Nat464XlatTest {
verifyNoMoreInteractions(mNetd, mNms, mConnectivity); verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
} }
@Test private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
public void testStopBeforeClatdStarts() throws Exception {
Nat464Xlat nat = makeNat464Xlat(); Nat464Xlat nat = makeNat464Xlat();
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
nat.start(); nat.start();
@@ -356,6 +390,7 @@ public class Nat464XlatTest {
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
makeClatUnnecessary(dueToDisconnect);
nat.stop(); nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE)); verify(mNetd).clatdStop(eq(BASE_IFACE));
@@ -377,9 +412,20 @@ public class Nat464XlatTest {
} }
@Test @Test
public void testStopAndClatdNeverStarts() throws Exception { public void testStopDueToDisconnectBeforeClatdStarts() throws Exception {
checkStopBeforeClatdStarts(true);
}
@Test
public void testStopDueToIpv4AddrBeforeClatdStarts() throws Exception {
checkStopBeforeClatdStarts(false);
}
private void checkStopAndClatdNeverStarts(boolean dueToDisconnect) throws Exception {
Nat464Xlat nat = makeNat464Xlat(); Nat464Xlat nat = makeNat464Xlat();
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
nat.start(); nat.start();
@@ -388,6 +434,7 @@ public class Nat464XlatTest {
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
makeClatUnnecessary(dueToDisconnect);
nat.stop(); nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE)); verify(mNetd).clatdStop(eq(BASE_IFACE));
@@ -398,6 +445,57 @@ public class Nat464XlatTest {
verifyNoMoreInteractions(mNetd, mNms, mConnectivity); verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
} }
@Test
public void testStopDueToDisconnectAndClatdNeverStarts() throws Exception {
checkStopAndClatdNeverStarts(true);
}
@Test
public void testStopDueToIpv4AddressAndClatdNeverStarts() throws Exception {
checkStopAndClatdNeverStarts(false);
}
@Test
public void testNat64PrefixPreference() throws Exception {
final IpPrefix prefixFromDns = new IpPrefix(NAT64_PREFIX);
final IpPrefix prefixFromRa = new IpPrefix(OTHER_NAT64_PREFIX);
Nat464Xlat nat = makeNat464Xlat();
final LinkProperties emptyLp = new LinkProperties();
LinkProperties fixedupLp;
fixedupLp = new LinkProperties();
nat.setNat64PrefixFromDns(prefixFromDns);
nat.fixupLinkProperties(emptyLp, fixedupLp);
assertEquals(prefixFromDns, fixedupLp.getNat64Prefix());
fixedupLp = new LinkProperties();
nat.setNat64PrefixFromRa(prefixFromRa);
nat.fixupLinkProperties(emptyLp, fixedupLp);
assertEquals(prefixFromRa, fixedupLp.getNat64Prefix());
fixedupLp = new LinkProperties();
nat.setNat64PrefixFromRa(null);
nat.fixupLinkProperties(emptyLp, fixedupLp);
assertEquals(prefixFromDns, fixedupLp.getNat64Prefix());
fixedupLp = new LinkProperties();
nat.setNat64PrefixFromRa(prefixFromRa);
nat.fixupLinkProperties(emptyLp, fixedupLp);
assertEquals(prefixFromRa, fixedupLp.getNat64Prefix());
fixedupLp = new LinkProperties();
nat.setNat64PrefixFromDns(null);
nat.fixupLinkProperties(emptyLp, fixedupLp);
assertEquals(prefixFromRa, fixedupLp.getNat64Prefix());
fixedupLp = new LinkProperties();
nat.setNat64PrefixFromRa(null);
nat.fixupLinkProperties(emptyLp, fixedupLp);
assertEquals(null, fixedupLp.getNat64Prefix());
}
static void assertIdle(Nat464Xlat nat) { static void assertIdle(Nat464Xlat nat) {
assertTrue("Nat464Xlat was not IDLE", !nat.isStarted()); assertTrue("Nat464Xlat was not IDLE", !nat.isStarted());
} }