1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.connectivity; 18 19 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertTrue; 24 import static org.mockito.Mockito.any; 25 import static org.mockito.Mockito.anyInt; 26 import static org.mockito.Mockito.anyString; 27 import static org.mockito.Mockito.eq; 28 import static org.mockito.Mockito.inOrder; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.times; 31 import static org.mockito.Mockito.verify; 32 import static org.mockito.Mockito.verifyNoMoreInteractions; 33 import static org.mockito.Mockito.when; 34 35 import android.net.ConnectivityManager; 36 import android.net.IDnsResolver; 37 import android.net.INetd; 38 import android.net.InterfaceConfigurationParcel; 39 import android.net.IpPrefix; 40 import android.net.LinkAddress; 41 import android.net.LinkProperties; 42 import android.net.NetworkAgentConfig; 43 import android.net.NetworkCapabilities; 44 import android.net.NetworkInfo; 45 import android.os.Build; 46 import android.os.Handler; 47 import android.os.test.TestLooper; 48 49 import androidx.annotation.NonNull; 50 import androidx.annotation.Nullable; 51 import androidx.test.filters.SmallTest; 52 53 import com.android.modules.utils.build.SdkLevel; 54 import com.android.server.ConnectivityService; 55 import com.android.testutils.DevSdkIgnoreRule; 56 import com.android.testutils.DevSdkIgnoreRunner; 57 58 import org.junit.Before; 59 import org.junit.Test; 60 import org.junit.runner.RunWith; 61 import org.mockito.ArgumentCaptor; 62 import org.mockito.InOrder; 63 import org.mockito.Mock; 64 import org.mockito.MockitoAnnotations; 65 66 @RunWith(DevSdkIgnoreRunner.class) 67 @SmallTest 68 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 69 public class Nat464XlatTest { 70 71 static final String BASE_IFACE = "test0"; 72 static final String STACKED_IFACE = "v4-test0"; 73 static final LinkAddress V6ADDR = new LinkAddress("2001:db8:1::f00/64"); 74 static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29"); 75 static final String NAT64_PREFIX = "64:ff9b::/96"; 76 static final String OTHER_NAT64_PREFIX = "2001:db8:0:64::/96"; 77 static final int NETID = 42; 78 79 @Mock ConnectivityService mConnectivity; 80 @Mock IDnsResolver mDnsResolver; 81 @Mock INetd mNetd; 82 @Mock NetworkAgentInfo mNai; 83 @Mock ClatCoordinator mClatCoordinator; 84 85 TestLooper mLooper; 86 Handler mHandler; 87 NetworkAgentConfig mAgentConfig = new NetworkAgentConfig(); 88 makeNat464Xlat(boolean isCellular464XlatEnabled)89 Nat464Xlat makeNat464Xlat(boolean isCellular464XlatEnabled) { 90 final ConnectivityService.Dependencies deps = new ConnectivityService.Dependencies() { 91 @Override public ClatCoordinator getClatCoordinator(INetd netd) { 92 return mClatCoordinator; 93 } 94 }; 95 96 return new Nat464Xlat(mNai, mNetd, mDnsResolver, deps) { 97 @Override protected int getNetId() { 98 return NETID; 99 } 100 101 @Override protected boolean isCellular464XlatEnabled() { 102 return isCellular464XlatEnabled; 103 } 104 }; 105 } 106 107 private void markNetworkConnected() { 108 mNai.networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); 109 } 110 111 private void markNetworkDisconnected() { 112 mNai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, "", ""); 113 } 114 115 @Before 116 public void setUp() throws Exception { 117 mLooper = new TestLooper(); 118 mHandler = new Handler(mLooper.getLooper()); 119 120 MockitoAnnotations.initMocks(this); 121 122 mNai.linkProperties = new LinkProperties(); 123 mNai.linkProperties.setInterfaceName(BASE_IFACE); 124 mNai.networkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, 125 null /* typeName */, null /* subtypeName */); 126 mNai.networkCapabilities = new NetworkCapabilities(); 127 markNetworkConnected(); 128 when(mNai.connService()).thenReturn(mConnectivity); 129 when(mNai.netAgentConfig()).thenReturn(mAgentConfig); 130 when(mNai.handler()).thenReturn(mHandler); 131 final InterfaceConfigurationParcel mConfig = new InterfaceConfigurationParcel(); 132 when(mNetd.interfaceGetCfg(eq(STACKED_IFACE))).thenReturn(mConfig); 133 mConfig.ipv4Addr = ADDR.getAddress().getHostAddress(); 134 mConfig.prefixLength = ADDR.getPrefixLength(); 135 } 136 137 private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) { 138 Nat464Xlat nat = makeNat464Xlat(true); 139 String msg = String.format("requiresClat expected %b for type=%d state=%s skip=%b " 140 + "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(), 141 nai.networkInfo.getDetailedState(), 142 mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(), 143 nai.linkProperties.getLinkAddresses()); 144 assertEquals(msg, expected, nat.requiresClat(nai)); 145 } 146 147 private void assertShouldStartClat(boolean expected, NetworkAgentInfo nai) { 148 Nat464Xlat nat = makeNat464Xlat(true); 149 String msg = String.format("shouldStartClat expected %b for type=%d state=%s skip=%b " 150 + "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(), 151 nai.networkInfo.getDetailedState(), 152 mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(), 153 nai.linkProperties.getLinkAddresses()); 154 assertEquals(msg, expected, nat.shouldStartClat(nai)); 155 } 156 157 @Test 158 public void testRequiresClat() throws Exception { 159 final int[] supportedTypes = { 160 ConnectivityManager.TYPE_MOBILE, 161 ConnectivityManager.TYPE_WIFI, 162 ConnectivityManager.TYPE_ETHERNET, 163 }; 164 165 // NetworkInfo doesn't allow setting the State directly, but rather 166 // requires setting DetailedState in order set State as a side-effect. 167 final NetworkInfo.DetailedState[] supportedDetailedStates = { 168 NetworkInfo.DetailedState.CONNECTED, 169 NetworkInfo.DetailedState.SUSPENDED, 170 }; 171 172 LinkProperties oldLp = new LinkProperties(mNai.linkProperties); 173 for (int type : supportedTypes) { 174 mNai.networkInfo.setType(type); 175 for (NetworkInfo.DetailedState state : supportedDetailedStates) { 176 mNai.networkInfo.setDetailedState(state, "reason", "extraInfo"); 177 178 mNai.linkProperties.setNat64Prefix(new IpPrefix(OTHER_NAT64_PREFIX)); 179 assertRequiresClat(false, mNai); 180 assertShouldStartClat(false, mNai); 181 182 mNai.linkProperties.addLinkAddress(new LinkAddress("fc00::1/64")); 183 assertRequiresClat(false, mNai); 184 assertShouldStartClat(false, mNai); 185 186 mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); 187 assertRequiresClat(true, mNai); 188 assertShouldStartClat(true, mNai); 189 190 mAgentConfig.skip464xlat = true; 191 assertRequiresClat(false, mNai); 192 assertShouldStartClat(false, mNai); 193 194 mAgentConfig.skip464xlat = false; 195 assertRequiresClat(true, mNai); 196 assertShouldStartClat(true, mNai); 197 198 mNai.linkProperties.addLinkAddress(new LinkAddress("192.0.2.2/24")); 199 assertRequiresClat(false, mNai); 200 assertShouldStartClat(false, mNai); 201 202 mNai.linkProperties.removeLinkAddress(new LinkAddress("192.0.2.2/24")); 203 assertRequiresClat(true, mNai); 204 assertShouldStartClat(true, mNai); 205 206 mNai.linkProperties.setNat64Prefix(null); 207 assertRequiresClat(true, mNai); 208 assertShouldStartClat(false, mNai); 209 210 mNai.linkProperties = new LinkProperties(oldLp); 211 } 212 } 213 } 214 215 private void makeClatUnnecessary(boolean dueToDisconnect) { 216 if (dueToDisconnect) { 217 markNetworkDisconnected(); 218 } else { 219 mNai.linkProperties.addLinkAddress(ADDR); 220 } 221 } 222 223 private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 224 if (inOrder != null) { 225 return inOrder.verify(t); 226 } else { 227 return verify(t); 228 } 229 } 230 231 private void verifyClatdStart(@Nullable InOrder inOrder) throws Exception { 232 if (SdkLevel.isAtLeastT()) { 233 verifyWithOrder(inOrder, mClatCoordinator) 234 .clatStart(eq(BASE_IFACE), eq(NETID), eq(new IpPrefix(NAT64_PREFIX))); 235 } else { 236 verifyWithOrder(inOrder, mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); 237 } 238 } 239 240 private void verifyNeverClatdStart() throws Exception { 241 if (SdkLevel.isAtLeastT()) { 242 verify(mClatCoordinator, never()).clatStart(anyString(), anyInt(), any()); 243 } else { 244 verify(mNetd, never()).clatdStart(anyString(), anyString()); 245 } 246 } 247 248 private void verifyClatdStop(@Nullable InOrder inOrder) throws Exception { 249 if (SdkLevel.isAtLeastT()) { 250 verifyWithOrder(inOrder, mClatCoordinator).clatStop(); 251 } else { 252 verifyWithOrder(inOrder, mNetd).clatdStop(eq(BASE_IFACE)); 253 } 254 } 255 256 private void checkNormalStartAndStop(boolean dueToDisconnect) throws Exception { 257 Nat464Xlat nat = makeNat464Xlat(true); 258 ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); 259 260 mNai.linkProperties.addLinkAddress(V6ADDR); 261 262 nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); 263 264 // Start clat. 265 nat.start(); 266 267 verifyClatdStart(null /* inOrder */); 268 269 // Stacked interface up notification arrives. 270 nat.interfaceLinkStateChanged(STACKED_IFACE, true); 271 mLooper.dispatchNext(); 272 273 verify(mNetd).interfaceGetCfg(eq(STACKED_IFACE)); 274 verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); 275 assertFalse(c.getValue().getStackedLinks().isEmpty()); 276 assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 277 assertRunning(nat); 278 279 // Stop clat (Network disconnects, IPv4 addr appears, ...). 280 makeClatUnnecessary(dueToDisconnect); 281 nat.stop(); 282 283 verifyClatdStop(null /* inOrder */); 284 verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); 285 assertTrue(c.getValue().getStackedLinks().isEmpty()); 286 assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 287 verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); 288 assertIdle(nat); 289 290 // Stacked interface removed notification arrives and is ignored. 291 nat.interfaceRemoved(STACKED_IFACE); 292 mLooper.dispatchNext(); 293 294 verifyNoMoreInteractions(mNetd, mConnectivity); 295 } 296 297 @Test 298 public void testNormalStartAndStopDueToDisconnect() throws Exception { 299 checkNormalStartAndStop(true); 300 } 301 302 @Test 303 public void testNormalStartAndStopDueToIpv4Addr() throws Exception { 304 checkNormalStartAndStop(false); 305 } 306 307 private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception { 308 Nat464Xlat nat = makeNat464Xlat(true); 309 ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); 310 InOrder inOrder = inOrder(mNetd, mConnectivity, mClatCoordinator); 311 312 mNai.linkProperties.addLinkAddress(V6ADDR); 313 314 nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); 315 316 nat.start(); 317 318 verifyClatdStart(inOrder); 319 320 // Stacked interface up notification arrives. 321 nat.interfaceLinkStateChanged(STACKED_IFACE, true); 322 mLooper.dispatchNext(); 323 324 inOrder.verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); 325 assertFalse(c.getValue().getStackedLinks().isEmpty()); 326 assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 327 assertRunning(nat); 328 329 // ConnectivityService stops clat (Network disconnects, IPv4 addr appears, ...). 330 nat.stop(); 331 332 verifyClatdStop(inOrder); 333 334 inOrder.verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); 335 assertTrue(c.getValue().getStackedLinks().isEmpty()); 336 assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 337 assertIdle(nat); 338 339 if (interfaceRemovedFirst) { 340 // Stacked interface removed notification arrives and is ignored. 341 nat.interfaceRemoved(STACKED_IFACE); 342 mLooper.dispatchNext(); 343 nat.interfaceLinkStateChanged(STACKED_IFACE, false); 344 mLooper.dispatchNext(); 345 } 346 347 assertTrue(c.getValue().getStackedLinks().isEmpty()); 348 assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 349 assertIdle(nat); 350 inOrder.verifyNoMoreInteractions(); 351 352 nat.start(); 353 354 verifyClatdStart(inOrder); 355 356 if (!interfaceRemovedFirst) { 357 // Stacked interface removed notification arrives and is ignored. 358 nat.interfaceRemoved(STACKED_IFACE); 359 mLooper.dispatchNext(); 360 nat.interfaceLinkStateChanged(STACKED_IFACE, false); 361 mLooper.dispatchNext(); 362 } 363 364 // Stacked interface up notification arrives. 365 nat.interfaceLinkStateChanged(STACKED_IFACE, true); 366 mLooper.dispatchNext(); 367 368 inOrder.verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); 369 assertFalse(c.getValue().getStackedLinks().isEmpty()); 370 assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 371 assertRunning(nat); 372 373 // ConnectivityService stops clat again. 374 nat.stop(); 375 376 verifyClatdStop(inOrder); 377 378 inOrder.verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); 379 assertTrue(c.getValue().getStackedLinks().isEmpty()); 380 assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 381 assertIdle(nat); 382 383 inOrder.verifyNoMoreInteractions(); 384 } 385 386 @Test 387 public void testStartStopStart() throws Exception { 388 checkStartStopStart(true); 389 } 390 391 @Test 392 public void testStartStopStartBeforeInterfaceRemoved() throws Exception { 393 checkStartStopStart(false); 394 } 395 396 @Test 397 public void testClatdCrashWhileRunning() throws Exception { 398 Nat464Xlat nat = makeNat464Xlat(true); 399 ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); 400 401 nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); 402 403 nat.start(); 404 405 verifyClatdStart(null /* inOrder */); 406 407 // Stacked interface up notification arrives. 408 nat.interfaceLinkStateChanged(STACKED_IFACE, true); 409 mLooper.dispatchNext(); 410 411 verify(mNetd).interfaceGetCfg(eq(STACKED_IFACE)); 412 verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); 413 assertFalse(c.getValue().getStackedLinks().isEmpty()); 414 assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 415 assertRunning(nat); 416 417 // Stacked interface removed notification arrives (clatd crashed, ...). 418 nat.interfaceRemoved(STACKED_IFACE); 419 mLooper.dispatchNext(); 420 421 verifyClatdStop(null /* inOrder */); 422 verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); 423 verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); 424 assertTrue(c.getValue().getStackedLinks().isEmpty()); 425 assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 426 assertIdle(nat); 427 428 // ConnectivityService stops clat: no-op. 429 nat.stop(); 430 431 verifyNoMoreInteractions(mNetd, mConnectivity); 432 } 433 434 private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception { 435 Nat464Xlat nat = makeNat464Xlat(true); 436 437 mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); 438 439 nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); 440 441 nat.start(); 442 443 verifyClatdStart(null /* inOrder */); 444 445 // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) 446 makeClatUnnecessary(dueToDisconnect); 447 nat.stop(); 448 449 verifyClatdStop(null /* inOrder */); 450 verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); 451 assertIdle(nat); 452 453 // In-flight interface up notification arrives: no-op 454 nat.interfaceLinkStateChanged(STACKED_IFACE, true); 455 mLooper.dispatchNext(); 456 457 // Interface removed notification arrives after stopClatd() takes effect: no-op. 458 nat.interfaceRemoved(STACKED_IFACE); 459 mLooper.dispatchNext(); 460 461 assertIdle(nat); 462 463 verifyNoMoreInteractions(mNetd, mConnectivity); 464 } 465 466 @Test 467 public void testStopDueToDisconnectBeforeClatdStarts() throws Exception { 468 checkStopBeforeClatdStarts(true); 469 } 470 471 @Test 472 public void testStopDueToIpv4AddrBeforeClatdStarts() throws Exception { 473 checkStopBeforeClatdStarts(false); 474 } 475 476 private void checkStopAndClatdNeverStarts(boolean dueToDisconnect) throws Exception { 477 Nat464Xlat nat = makeNat464Xlat(true); 478 479 mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); 480 481 nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); 482 483 nat.start(); 484 485 verifyClatdStart(null /* inOrder */); 486 487 // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) 488 makeClatUnnecessary(dueToDisconnect); 489 nat.stop(); 490 491 verifyClatdStop(null /* inOrder */); 492 verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); 493 assertIdle(nat); 494 495 verifyNoMoreInteractions(mNetd, mConnectivity); 496 } 497 498 @Test 499 public void testStopDueToDisconnectAndClatdNeverStarts() throws Exception { 500 checkStopAndClatdNeverStarts(true); 501 } 502 503 @Test 504 public void testStopDueToIpv4AddressAndClatdNeverStarts() throws Exception { 505 checkStopAndClatdNeverStarts(false); 506 } 507 508 @Test 509 public void testNat64PrefixPreference() throws Exception { 510 final IpPrefix prefixFromDns = new IpPrefix(NAT64_PREFIX); 511 final IpPrefix prefixFromRa = new IpPrefix(OTHER_NAT64_PREFIX); 512 513 Nat464Xlat nat = makeNat464Xlat(true); 514 515 final LinkProperties emptyLp = new LinkProperties(); 516 LinkProperties fixedupLp; 517 518 fixedupLp = new LinkProperties(); 519 nat.setNat64PrefixFromDns(prefixFromDns); 520 nat.fixupLinkProperties(emptyLp, fixedupLp); 521 assertEquals(prefixFromDns, fixedupLp.getNat64Prefix()); 522 523 fixedupLp = new LinkProperties(); 524 nat.setNat64PrefixFromRa(prefixFromRa); 525 nat.fixupLinkProperties(emptyLp, fixedupLp); 526 assertEquals(prefixFromRa, fixedupLp.getNat64Prefix()); 527 528 fixedupLp = new LinkProperties(); 529 nat.setNat64PrefixFromRa(null); 530 nat.fixupLinkProperties(emptyLp, fixedupLp); 531 assertEquals(prefixFromDns, fixedupLp.getNat64Prefix()); 532 533 fixedupLp = new LinkProperties(); 534 nat.setNat64PrefixFromRa(prefixFromRa); 535 nat.fixupLinkProperties(emptyLp, fixedupLp); 536 assertEquals(prefixFromRa, fixedupLp.getNat64Prefix()); 537 538 fixedupLp = new LinkProperties(); 539 nat.setNat64PrefixFromDns(null); 540 nat.fixupLinkProperties(emptyLp, fixedupLp); 541 assertEquals(prefixFromRa, fixedupLp.getNat64Prefix()); 542 543 fixedupLp = new LinkProperties(); 544 nat.setNat64PrefixFromRa(null); 545 nat.fixupLinkProperties(emptyLp, fixedupLp); 546 assertEquals(null, fixedupLp.getNat64Prefix()); 547 } 548 549 private void checkClatDisabledOnCellular(boolean onCellular) throws Exception { 550 // Disable 464xlat on cellular networks. 551 Nat464Xlat nat = makeNat464Xlat(false); 552 mNai.linkProperties.addLinkAddress(V6ADDR); 553 mNai.networkCapabilities.setTransportType(TRANSPORT_CELLULAR, onCellular); 554 nat.update(); 555 556 final IpPrefix nat64Prefix = new IpPrefix(NAT64_PREFIX); 557 if (onCellular) { 558 // Prefix discovery is never started. 559 verify(mDnsResolver, never()).startPrefix64Discovery(eq(NETID)); 560 assertIdle(nat); 561 562 // If a NAT64 prefix comes in from an RA, clat is not started either. 563 mNai.linkProperties.setNat64Prefix(nat64Prefix); 564 nat.setNat64PrefixFromRa(nat64Prefix); 565 nat.update(); 566 verifyNeverClatdStart(); 567 assertIdle(nat); 568 } else { 569 // Prefix discovery is started. 570 verify(mDnsResolver).startPrefix64Discovery(eq(NETID)); 571 assertIdle(nat); 572 573 // If a NAT64 prefix comes in from an RA, clat is started. 574 mNai.linkProperties.setNat64Prefix(nat64Prefix); 575 nat.setNat64PrefixFromRa(nat64Prefix); 576 nat.update(); 577 verifyClatdStart(null /* inOrder */); 578 assertStarting(nat); 579 } 580 } 581 582 @Test 583 public void testClatDisabledOnCellular() throws Exception { 584 checkClatDisabledOnCellular(true); 585 } 586 587 @Test 588 public void testClatDisabledOnNonCellular() throws Exception { 589 checkClatDisabledOnCellular(false); 590 } 591 592 static void assertIdle(Nat464Xlat nat) { 593 assertTrue("Nat464Xlat was not IDLE", !nat.isStarted()); 594 } 595 596 static void assertStarting(Nat464Xlat nat) { 597 assertTrue("Nat464Xlat was not STARTING", nat.isStarting()); 598 } 599 600 static void assertRunning(Nat464Xlat nat) { 601 assertTrue("Nat464Xlat was not RUNNING", nat.isRunning()); 602 } 603 } 604