1 /* 2 * Copyright (C) 2024 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 android.net.thread.utils 18 19 import android.Manifest.permission.MANAGE_TEST_NETWORKS 20 import android.content.Context 21 import android.net.InetAddresses.parseNumericAddress 22 import android.net.IpPrefix 23 import android.net.LinkProperties 24 import android.net.MacAddress 25 import android.net.RouteInfo 26 import com.android.testutils.PollPacketReader 27 import com.android.testutils.TestNetworkTracker 28 import com.android.testutils.initTestNetwork 29 import com.android.testutils.runAsShell 30 import java.time.Duration 31 32 object TestTunNetworkUtils { 33 private val networkTrackers = mutableListOf<TestNetworkTracker>() 34 35 @JvmStatic 36 @JvmOverloads setUpInfraNetworknull37 fun setUpInfraNetwork( 38 context: Context, 39 controller: ThreadNetworkControllerWrapper, 40 lp: LinkProperties = defaultLinkProperties(), 41 ): TestNetworkTracker { 42 val infraNetworkTracker: TestNetworkTracker = 43 runAsShell( 44 MANAGE_TEST_NETWORKS, 45 supplier = { initTestNetwork(context, lp, setupTimeoutMs = 5000) }, 46 ) 47 val infraNetworkName: String = infraNetworkTracker.testIface.getInterfaceName() 48 controller.setTestNetworkAsUpstreamAndWait(infraNetworkName) 49 networkTrackers.add(infraNetworkTracker) 50 51 return infraNetworkTracker 52 } 53 54 @JvmStatic tearDownInfraNetworknull55 fun tearDownInfraNetwork(testNetworkTracker: TestNetworkTracker) { 56 runAsShell(MANAGE_TEST_NETWORKS) { testNetworkTracker.teardown() } 57 } 58 59 @JvmStatic tearDownAllInfraNetworksnull60 fun tearDownAllInfraNetworks() { 61 networkTrackers.forEach { tearDownInfraNetwork(it) } 62 networkTrackers.clear() 63 } 64 65 @JvmStatic 66 @JvmOverloads startInfraDeviceAndWaitForOnLinkAddrnull67 fun startInfraDeviceAndWaitForOnLinkAddr( 68 pollPacketReader: PollPacketReader, 69 macAddress: MacAddress = MacAddress.fromString("1:2:3:4:5:6"), 70 ): InfraNetworkDevice { 71 val infraDevice = InfraNetworkDevice(macAddress, pollPacketReader) 72 infraDevice.runSlaac(Duration.ofSeconds(60)) 73 requireNotNull(infraDevice.ipv6Addr) 74 return infraDevice 75 } 76 defaultLinkPropertiesnull77 private fun defaultLinkProperties(): LinkProperties { 78 val lp = LinkProperties() 79 // TODO: use a fake DNS server 80 lp.setDnsServers(listOf(parseNumericAddress("8.8.8.8"))) 81 // NAT64 feature requires the infra network to have an IPv4 default route. 82 lp.addRoute( 83 RouteInfo( 84 IpPrefix("0.0.0.0/0") /* destination */, 85 null /* gateway */, 86 null /* iface */, 87 RouteInfo.RTN_UNICAST, 88 1500, /* mtu */ 89 ) 90 ) 91 return lp 92 } 93 } 94