Manage NAT64 prefix discovery lifecycle in the framework.
Currently NAT64 prefix discovery, which runs in netd, is started by netd itself when a network is programmed with all-IPv6 DNS servers. Unfortunately this is not correct because in many cases we program DNS servers before the network is connected and it's actually possible to send packets to them. In general netd does not have enough visibility into network lifecycle management to decide when to start and stop prefix discovery. So move it into the framework with the rest of the 464xlat control plane. Bug: 65674744 Test: atest FrameworksNetTests Change-Id: I8fa051a9c216d9c05082bf7d0bbb0cbd56000162
This commit is contained in:
@@ -5103,8 +5103,9 @@ public class ConnectivityServiceTest {
|
||||
final TestNetworkCallback networkCallback = new TestNetworkCallback();
|
||||
mCm.registerNetworkCallback(networkRequest, networkCallback);
|
||||
|
||||
// Prepare ipv6 only link properties and connect.
|
||||
// Prepare ipv6 only link properties.
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
final int cellNetId = mCellNetworkAgent.getNetwork().netId;
|
||||
final LinkProperties cellLp = new LinkProperties();
|
||||
cellLp.setInterfaceName(MOBILE_IFNAME);
|
||||
cellLp.addLinkAddress(myIpv6);
|
||||
@@ -5114,17 +5115,37 @@ public class ConnectivityServiceTest {
|
||||
when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
|
||||
.thenReturn(getClatInterfaceConfig(myIpv4));
|
||||
|
||||
// Connect with ipv6 link properties, then expect clat setup ipv4 and update link
|
||||
// properties properly.
|
||||
// Connect with ipv6 link properties. Expect prefix discovery to be started.
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
mCellNetworkAgent.connect(true);
|
||||
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
|
||||
|
||||
// When NAT64 prefix detection succeeds, LinkProperties are updated and clatd is started.
|
||||
// Switching default network updates TCP buffer sizes.
|
||||
verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES);
|
||||
|
||||
// Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that
|
||||
// the NAT64 prefix was removed because one was never discovered.
|
||||
cellLp.addLinkAddress(myIpv4);
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
|
||||
|
||||
verifyNoMoreInteractions(mMockNetd);
|
||||
reset(mMockNetd);
|
||||
|
||||
// Remove IPv4 address. Expect prefix discovery to be started again.
|
||||
cellLp.removeLinkAddress(myIpv4);
|
||||
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
|
||||
|
||||
// When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
|
||||
Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent);
|
||||
assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix());
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(mCellNetworkAgent.getNetwork().netId,
|
||||
true /* added */, kNat64PrefixString, 96);
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
|
||||
kNat64PrefixString, 96);
|
||||
LinkProperties lpBeforeClat = (LinkProperties) networkCallback.expectCallback(
|
||||
CallbackState.LINK_PROPERTIES, mCellNetworkAgent).arg;
|
||||
assertEquals(0, lpBeforeClat.getStackedLinks().size());
|
||||
@@ -5148,15 +5169,17 @@ public class ConnectivityServiceTest {
|
||||
assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST);
|
||||
assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0));
|
||||
|
||||
// Add ipv4 address, expect that clatd is stopped and stacked linkproperties are cleaned up.
|
||||
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
|
||||
// linkproperties are cleaned up.
|
||||
cellLp.addLinkAddress(myIpv4);
|
||||
cellLp.addRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
|
||||
|
||||
// As soon as stop is called, the linkproperties lose the stacked interface.
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
|
||||
LinkProperties expected = new LinkProperties(cellLp);
|
||||
expected.setNat64Prefix(kNat64Prefix);
|
||||
@@ -5167,25 +5190,39 @@ public class ConnectivityServiceTest {
|
||||
clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME);
|
||||
networkCallback.assertNoCallback();
|
||||
|
||||
verifyNoMoreInteractions(mMockNetd);
|
||||
reset(mMockNetd);
|
||||
|
||||
// Remove IPv4 address and expect clatd to be started again.
|
||||
// Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
|
||||
kNat64PrefixString, 96);
|
||||
networkCallback.expectLinkPropertiesLike((lp) -> lp.getNat64Prefix() == null,
|
||||
mCellNetworkAgent);
|
||||
|
||||
// Remove IPv4 address and expect prefix discovery and clatd to be started again.
|
||||
cellLp.removeLinkAddress(myIpv4);
|
||||
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
|
||||
cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
|
||||
kNat64PrefixString, 96);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
|
||||
|
||||
|
||||
// Clat iface comes up. Expect stacked link to be added.
|
||||
clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
|
||||
networkCallback.expectLinkPropertiesLike((lp) -> lp.getStackedLinks().size() == 1,
|
||||
networkCallback.expectLinkPropertiesLike(
|
||||
(lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null,
|
||||
mCellNetworkAgent);
|
||||
|
||||
// NAT64 prefix is removed. Expect that clat is stopped.
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(mCellNetworkAgent.getNetwork().netId,
|
||||
false /* added */, kNat64PrefixString, 96);
|
||||
networkCallback.expectLinkPropertiesLike((lp) -> lp.getNat64Prefix() == null,
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
|
||||
kNat64PrefixString, 96);
|
||||
networkCallback.expectLinkPropertiesLike(
|
||||
(lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null,
|
||||
mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
|
||||
networkCallback.expectLinkPropertiesLike((lp) -> lp.getStackedLinks().size() == 0,
|
||||
|
||||
@@ -58,6 +58,7 @@ public class Nat464XlatTest {
|
||||
static final String STACKED_IFACE = "v4-test0";
|
||||
static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29");
|
||||
static final String NAT64_PREFIX = "64:ff9b::/96";
|
||||
static final int NETID = 42;
|
||||
|
||||
@Mock ConnectivityService mConnectivity;
|
||||
@Mock NetworkMisc mMisc;
|
||||
@@ -70,7 +71,11 @@ public class Nat464XlatTest {
|
||||
Handler mHandler;
|
||||
|
||||
Nat464Xlat makeNat464Xlat() {
|
||||
return new Nat464Xlat(mNai, mNetd, mNms);
|
||||
return new Nat464Xlat(mNai, mNetd, mNms) {
|
||||
@Override protected int getNetId() {
|
||||
return NETID;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -93,7 +98,7 @@ public class Nat464XlatTest {
|
||||
}
|
||||
|
||||
private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) {
|
||||
String msg = String.format("requiresClat expected %b for type=%d state=%s skip464xlat=%b "
|
||||
String msg = String.format("requiresClat expected %b for type=%d state=%s skip=%b "
|
||||
+ "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
|
||||
nai.networkInfo.getDetailedState(),
|
||||
mMisc.skip464xlat, nai.linkProperties.getNat64Prefix(),
|
||||
@@ -101,6 +106,15 @@ public class Nat464XlatTest {
|
||||
assertEquals(msg, expected, Nat464Xlat.requiresClat(nai));
|
||||
}
|
||||
|
||||
private void assertShouldStartClat(boolean expected, NetworkAgentInfo nai) {
|
||||
String msg = String.format("shouldStartClat expected %b for type=%d state=%s skip=%b "
|
||||
+ "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
|
||||
nai.networkInfo.getDetailedState(),
|
||||
mMisc.skip464xlat, nai.linkProperties.getNat64Prefix(),
|
||||
nai.linkProperties.getLinkAddresses());
|
||||
assertEquals(msg, expected, Nat464Xlat.shouldStartClat(nai));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiresClat() throws Exception {
|
||||
final int[] supportedTypes = {
|
||||
@@ -124,21 +138,35 @@ public class Nat464XlatTest {
|
||||
|
||||
mNai.linkProperties.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96"));
|
||||
assertRequiresClat(false, mNai);
|
||||
assertShouldStartClat(false, mNai);
|
||||
|
||||
mNai.linkProperties.addLinkAddress(new LinkAddress("fc00::1/64"));
|
||||
assertRequiresClat(false, mNai);
|
||||
assertShouldStartClat(false, mNai);
|
||||
|
||||
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
|
||||
assertRequiresClat(true, mNai);
|
||||
assertShouldStartClat(true, mNai);
|
||||
|
||||
mMisc.skip464xlat = true;
|
||||
assertRequiresClat(false, mNai);
|
||||
assertShouldStartClat(false, mNai);
|
||||
|
||||
mMisc.skip464xlat = false;
|
||||
assertRequiresClat(true, mNai);
|
||||
assertShouldStartClat(true, mNai);
|
||||
|
||||
mNai.linkProperties.addLinkAddress(new LinkAddress("192.0.2.2/24"));
|
||||
assertRequiresClat(false, mNai);
|
||||
assertShouldStartClat(false, mNai);
|
||||
|
||||
mNai.linkProperties.removeLinkAddress(new LinkAddress("192.0.2.2/24"));
|
||||
assertRequiresClat(true, mNai);
|
||||
assertShouldStartClat(true, mNai);
|
||||
|
||||
mNai.linkProperties.setNat64Prefix(null);
|
||||
assertRequiresClat(true, mNai);
|
||||
assertShouldStartClat(false, mNai);
|
||||
|
||||
mNai.linkProperties = new LinkProperties(oldLp);
|
||||
}
|
||||
@@ -152,7 +180,7 @@ public class Nat464XlatTest {
|
||||
|
||||
nat.setNat64Prefix(new IpPrefix(NAT64_PREFIX));
|
||||
|
||||
// ConnectivityService starts clat.
|
||||
// Start clat.
|
||||
nat.start();
|
||||
|
||||
verify(mNms).registerObserver(eq(nat));
|
||||
@@ -168,7 +196,7 @@ public class Nat464XlatTest {
|
||||
assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
|
||||
assertRunning(nat);
|
||||
|
||||
// ConnectivityService stops clat (Network disconnects, IPv4 addr appears, ...).
|
||||
// Stop clat (Network disconnects, IPv4 addr appears, ...).
|
||||
nat.stop();
|
||||
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
@@ -176,6 +204,7 @@ public class Nat464XlatTest {
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
assertTrue(c.getValue().getStackedLinks().isEmpty());
|
||||
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
assertIdle(nat);
|
||||
|
||||
// Stacked interface removed notification arrives and is ignored.
|
||||
@@ -192,7 +221,6 @@ public class Nat464XlatTest {
|
||||
|
||||
nat.setNat64Prefix(new IpPrefix(NAT64_PREFIX));
|
||||
|
||||
// ConnectivityService starts clat.
|
||||
nat.start();
|
||||
|
||||
inOrder.verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
|
||||
@@ -229,7 +257,6 @@ public class Nat464XlatTest {
|
||||
assertIdle(nat);
|
||||
inOrder.verifyNoMoreInteractions();
|
||||
|
||||
// ConnectivityService starts clatd again.
|
||||
nat.start();
|
||||
|
||||
inOrder.verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
|
||||
@@ -281,7 +308,6 @@ public class Nat464XlatTest {
|
||||
|
||||
nat.setNat64Prefix(new IpPrefix(NAT64_PREFIX));
|
||||
|
||||
// ConnectivityService starts clat.
|
||||
nat.start();
|
||||
|
||||
verify(mNms).registerObserver(eq(nat));
|
||||
@@ -304,6 +330,7 @@ public class Nat464XlatTest {
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
assertTrue(c.getValue().getStackedLinks().isEmpty());
|
||||
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
|
||||
assertIdle(nat);
|
||||
@@ -320,7 +347,6 @@ public class Nat464XlatTest {
|
||||
|
||||
nat.setNat64Prefix(new IpPrefix(NAT64_PREFIX));
|
||||
|
||||
// ConnectivityService starts clat.
|
||||
nat.start();
|
||||
|
||||
verify(mNms).registerObserver(eq(nat));
|
||||
@@ -331,13 +357,13 @@ public class Nat464XlatTest {
|
||||
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
assertIdle(nat);
|
||||
|
||||
// In-flight interface up notification arrives: no-op
|
||||
nat.interfaceLinkStateChanged(STACKED_IFACE, true);
|
||||
mLooper.dispatchNext();
|
||||
|
||||
|
||||
// Interface removed notification arrives after stopClatd() takes effect: no-op.
|
||||
nat.interfaceRemoved(STACKED_IFACE);
|
||||
mLooper.dispatchNext();
|
||||
@@ -353,7 +379,6 @@ public class Nat464XlatTest {
|
||||
|
||||
nat.setNat64Prefix(new IpPrefix(NAT64_PREFIX));
|
||||
|
||||
// ConnectivityService starts clat.
|
||||
nat.start();
|
||||
|
||||
verify(mNms).registerObserver(eq(nat));
|
||||
@@ -364,6 +389,7 @@ public class Nat464XlatTest {
|
||||
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
assertIdle(nat);
|
||||
|
||||
verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
|
||||
|
||||
Reference in New Issue
Block a user