Snap for 11869550 from 710e048edd47dcf8653bf25735d9eb897d66d1ab to 24Q3-release
Change-Id: I51486936bd7883816f3c6c3d6f6ad9be9cd2a16b
diff --git a/framework/src/android/net/connectivity/ConnectivityCompatChanges.java b/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
index 02ef8b7..c726dab 100644
--- a/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
+++ b/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
@@ -118,7 +118,7 @@
* @hide
*/
@ChangeId
- @EnabledAfter(targetSdkVersion = 35) // TODO: change to VANILLA_ICE_CREAM.
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public static final long NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION = 333340911L;
private ConnectivityCompatChanges() {
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index b535ebf..91fec90 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "BpfHandler"
+#define LOG_TAG "NetdUpdatable"
#include "BpfHandler.h"
diff --git a/service/Android.bp b/service/Android.bp
index 1d74efc..1dd09a9 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -188,7 +188,7 @@
"androidx.annotation_annotation",
"connectivity-net-module-utils-bpf",
"connectivity_native_aidl_interface-lateststable-java",
- "dnsresolver_aidl_interface-V14-java",
+ "dnsresolver_aidl_interface-V15-java",
"modules-utils-shell-command-handler",
"net-utils-device-common",
"net-utils-device-common-ip",
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 39ea286..fff809e 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -554,6 +554,8 @@
* default network for each app.
* Order ints passed to netd must be in the 0~999 range. Larger values code for
* a lower priority, see {@link NativeUidRangeConfig}.
+ * Note that only the highest priority preference is applied if the uid is the target of
+ * multiple preferences.
*
* Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID.
* The default request uses PREFERENCE_ORDER_DEFAULT.
diff --git a/service/src/com/android/server/connectivity/DnsManager.java b/service/src/com/android/server/connectivity/DnsManager.java
index 8e6854a..ac02229 100644
--- a/service/src/com/android/server/connectivity/DnsManager.java
+++ b/service/src/com/android/server/connectivity/DnsManager.java
@@ -390,6 +390,7 @@
: new String[0]; // Off
paramsParcel.transportTypes = nc.getTransportTypes();
paramsParcel.meteredNetwork = nc.isMetered();
+ paramsParcel.interfaceNames = lp.getAllInterfaceNames().toArray(new String[0]);
// Prepare to track the validation status of the DNS servers in the
// resolver config when private DNS is in opportunistic or strict mode.
if (useTls) {
@@ -403,13 +404,14 @@
}
Log.d(TAG, String.format("sendDnsConfigurationForNetwork(%d, %s, %s, %d, %d, %d, %d, "
- + "%d, %d, %s, %s, %s, %b)", paramsParcel.netId,
+ + "%d, %d, %s, %s, %s, %b, %s)", paramsParcel.netId,
Arrays.toString(paramsParcel.servers), Arrays.toString(paramsParcel.domains),
paramsParcel.sampleValiditySeconds, paramsParcel.successThreshold,
paramsParcel.minSamples, paramsParcel.maxSamples, paramsParcel.baseTimeoutMsec,
paramsParcel.retryCount, paramsParcel.tlsName,
Arrays.toString(paramsParcel.tlsServers),
- Arrays.toString(paramsParcel.transportTypes), paramsParcel.meteredNetwork));
+ Arrays.toString(paramsParcel.transportTypes), paramsParcel.meteredNetwork,
+ Arrays.toString(paramsParcel.interfaceNames)));
try {
mDnsResolver.setResolverConfiguration(paramsParcel);
diff --git a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkLinkMessage.java b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkLinkMessage.java
index 92ec0c4..df7010e 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkLinkMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkLinkMessage.java
@@ -41,6 +41,10 @@
public static final short IFLA_ADDRESS = 1;
public static final short IFLA_IFNAME = 3;
public static final short IFLA_MTU = 4;
+ public static final short IFLA_INET6_ADDR_GEN_MODE = 8;
+ public static final short IFLA_AF_SPEC = 26;
+
+ public static final short IN6_ADDR_GEN_MODE_NONE = 1;
private int mMtu;
@NonNull
diff --git a/staticlibs/device/com/android/net/module/util/netlink/StructIfinfoMsg.java b/staticlibs/device/com/android/net/module/util/netlink/StructIfinfoMsg.java
index 02d1574..28eeaea 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/StructIfinfoMsg.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/StructIfinfoMsg.java
@@ -49,7 +49,7 @@
@Field(order = 4, type = Type.U32)
public final long change;
- StructIfinfoMsg(short family, int type, int index, long flags, long change) {
+ public StructIfinfoMsg(short family, int type, int index, long flags, long change) {
this.family = family;
this.type = type;
this.index = index;
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/SetFeatureFlagsRule.kt b/staticlibs/testutils/devicetests/com/android/testutils/SetFeatureFlagsRule.kt
index 4185b05..d5e91c2 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/SetFeatureFlagsRule.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/SetFeatureFlagsRule.kt
@@ -24,6 +24,7 @@
* A JUnit Rule that sets feature flags based on `@FeatureFlag` annotations.
*
* This rule enables dynamic control of feature flag states during testing.
+ * And restores the original values after performing tests.
*
* **Usage:**
* ```kotlin
@@ -31,6 +32,8 @@
* @get:Rule
* val setFeatureFlagsRule = SetFeatureFlagsRule(setFlagsMethod = (name, enabled) -> {
* // Custom handling code.
+ * }, (name) -> {
+ * // Custom getter code to retrieve the original values.
* })
*
* // ... test methods with @FeatureFlag annotations
@@ -41,7 +44,10 @@
* }
* ```
*/
-class SetFeatureFlagsRule(val setFlagsMethod: (name: String, enabled: Boolean) -> Unit) : TestRule {
+class SetFeatureFlagsRule(
+ val setFlagsMethod: (name: String, enabled: Boolean?) -> Unit,
+ val getFlagsMethod: (name: String) -> Boolean?
+) : TestRule {
/**
* This annotation marks a test method as requiring a specific feature flag to be configured.
*
@@ -69,13 +75,20 @@
FeatureFlag::class.java
)
+ val valuesToBeRestored = mutableMapOf<String, Boolean?>()
for (featureFlagAnnotation in featureFlagAnnotations) {
+ valuesToBeRestored[featureFlagAnnotation.name] =
+ getFlagsMethod(featureFlagAnnotation.name)
setFlagsMethod(featureFlagAnnotation.name, featureFlagAnnotation.enabled)
}
// Execute the test method, which includes methods annotated with
// @Before, @Test and @After.
base.evaluate()
+
+ valuesToBeRestored.forEach {
+ setFlagsMethod(it.key, it.value)
+ }
}
}
}
diff --git a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
index 44512bb..ea3d2dd 100644
--- a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
@@ -29,8 +29,6 @@
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
-import static com.android.testutils.MiscAsserts.assertContainsExactly;
-import static com.android.testutils.MiscAsserts.assertContainsStringsExactly;
import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
import static org.junit.Assert.assertEquals;
@@ -38,12 +36,12 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.net.ConnectivitySettingsManager;
@@ -74,7 +72,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -122,29 +119,6 @@
assertFieldCountEquals(3, ResolverOptionsParcel.class);
}
- private void assertResolverParamsEquals(@NonNull ResolverParamsParcel actual,
- @NonNull ResolverParamsParcel expected) {
- assertEquals(actual.netId, expected.netId);
- assertEquals(actual.sampleValiditySeconds, expected.sampleValiditySeconds);
- assertEquals(actual.successThreshold, expected.successThreshold);
- assertEquals(actual.minSamples, expected.minSamples);
- assertEquals(actual.maxSamples, expected.maxSamples);
- assertEquals(actual.baseTimeoutMsec, expected.baseTimeoutMsec);
- assertEquals(actual.retryCount, expected.retryCount);
- assertContainsStringsExactly(actual.servers, expected.servers);
- assertContainsStringsExactly(actual.domains, expected.domains);
- assertEquals(actual.tlsName, expected.tlsName);
- assertContainsStringsExactly(actual.tlsServers, expected.tlsServers);
- assertContainsStringsExactly(actual.tlsFingerprints, expected.tlsFingerprints);
- assertEquals(actual.caCertificate, expected.caCertificate);
- assertEquals(actual.tlsConnectTimeoutMs, expected.tlsConnectTimeoutMs);
- assertResolverOptionsEquals(actual.resolverOptions, expected.resolverOptions);
- assertContainsExactly(actual.transportTypes, expected.transportTypes);
- assertEquals(actual.meteredNetwork, expected.meteredNetwork);
- assertEquals(actual.dohParams, expected.dohParams);
- assertFieldCountEquals(18, ResolverParamsParcel.class);
- }
-
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -365,11 +339,6 @@
mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
mDnsManager.flushVmDnsCache();
- final ArgumentCaptor<ResolverParamsParcel> resolverParamsParcelCaptor =
- ArgumentCaptor.forClass(ResolverParamsParcel.class);
- verify(mMockDnsResolver, times(1)).setResolverConfiguration(
- resolverParamsParcelCaptor.capture());
- final ResolverParamsParcel actualParams = resolverParamsParcelCaptor.getValue();
final ResolverParamsParcel expectedParams = new ResolverParamsParcel();
expectedParams.netId = TEST_NETID;
expectedParams.sampleValiditySeconds = TEST_DEFAULT_SAMPLE_VALIDITY_SECONDS;
@@ -384,7 +353,8 @@
expectedParams.resolverOptions = null;
expectedParams.meteredNetwork = true;
expectedParams.dohParams = null;
- assertResolverParamsEquals(actualParams, expectedParams);
+ expectedParams.interfaceNames = new String[]{TEST_IFACENAME};
+ verify(mMockDnsResolver, times(1)).setResolverConfiguration(eq(expectedParams));
}
@Test
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index a19e4e7..c0a0f02 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -318,7 +318,7 @@
new SetFeatureFlagsRule((name, enabled) -> {
mFeatureFlags.put(name, enabled);
return null;
- });
+ }, (name) -> mFeatureFlags.getOrDefault(name, false));
private class MockContext extends BroadcastInterceptingContext {
private final Context mBaseContext;
diff --git a/thread/service/java/com/android/server/thread/TunInterfaceController.java b/thread/service/java/com/android/server/thread/TunInterfaceController.java
index b76c1e9..976f93d 100644
--- a/thread/service/java/com/android/server/thread/TunInterfaceController.java
+++ b/thread/service/java/com/android/server/thread/TunInterfaceController.java
@@ -16,30 +16,40 @@
package com.android.server.thread;
+import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.EADDRINUSE;
+import static android.system.OsConstants.IFF_MULTICAST;
+import static android.system.OsConstants.IFF_NOARP;
+import static android.system.OsConstants.NETLINK_ROUTE;
+
+import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWLINK;
+import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IFLA_AF_SPEC;
+import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IFLA_INET6_ADDR_GEN_MODE;
+import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IN6_ADDR_GEN_MODE_NONE;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_ACK;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import android.annotation.Nullable;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.RouteInfo;
-import android.net.util.SocketUtils;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.system.ErrnoException;
import android.system.Os;
-import android.system.OsConstants;
import android.util.Log;
+import com.android.net.module.util.HexDump;
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.net.module.util.netlink.NetlinkUtils;
-import com.android.net.module.util.netlink.RtNetlinkAddressMessage;
+import com.android.net.module.util.netlink.StructIfinfoMsg;
+import com.android.net.module.util.netlink.StructNlAttr;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
import com.android.server.thread.openthread.Ipv6AddressInfo;
import com.android.server.thread.openthread.OnMeshPrefixConfig;
-import java.io.FileDescriptor;
import java.io.IOException;
-import java.io.InterruptedIOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -47,12 +57,15 @@
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
/** Controller for virtual/tunnel network interfaces. */
public class TunInterfaceController {
private static final String TAG = "TunIfController";
+ private static final boolean DBG = false;
private static final long INFINITE_LIFETIME = 0xffffffffL;
static final int MTU = 1280;
@@ -62,14 +75,13 @@
private final String mIfName;
private final LinkProperties mLinkProperties = new LinkProperties();
- private ParcelFileDescriptor mParcelTunFd;
- private FileDescriptor mNetlinkSocket;
- private static int sNetlinkSeqNo = 0;
private final MulticastSocket mMulticastSocket; // For join group and leave group
- private NetworkInterface mNetworkInterface;
private final List<InetAddress> mMulticastAddresses = new ArrayList<>();
private final List<RouteInfo> mNetDataPrefixes = new ArrayList<>();
+ private ParcelFileDescriptor mParcelTunFd;
+ private NetworkInterface mNetworkInterface;
+
/** Creates a new {@link TunInterfaceController} instance for given interface. */
public TunInterfaceController(String interfaceName) {
mIfName = interfaceName;
@@ -91,26 +103,21 @@
public void createTunInterface() throws IOException {
mParcelTunFd = ParcelFileDescriptor.adoptFd(nativeCreateTunInterface(mIfName, MTU));
try {
- mNetlinkSocket = NetlinkUtils.netlinkSocketForProto(OsConstants.NETLINK_ROUTE);
- } catch (ErrnoException e) {
- throw new IOException("Failed to create netlink socket", e);
- }
- try {
mNetworkInterface = NetworkInterface.getByName(mIfName);
} catch (SocketException e) {
throw new IOException("Failed to get NetworkInterface", e);
}
+
+ setAddrGenModeToNone();
}
public void destroyTunInterface() {
try {
mParcelTunFd.close();
- SocketUtils.closeSocket(mNetlinkSocket);
} catch (IOException e) {
// Should never fail
}
mParcelTunFd = null;
- mNetlinkSocket = null;
mNetworkInterface = null;
}
@@ -142,14 +149,14 @@
public void addAddress(LinkAddress address) {
Log.d(TAG, "Adding address " + address + " with flags: " + address.getFlags());
- long validLifetimeSeconds;
long preferredLifetimeSeconds;
+ long validLifetimeSeconds;
if (address.getDeprecationTime() == LinkAddress.LIFETIME_PERMANENT
|| address.getDeprecationTime() == LinkAddress.LIFETIME_UNKNOWN) {
- validLifetimeSeconds = INFINITE_LIFETIME;
+ preferredLifetimeSeconds = INFINITE_LIFETIME;
} else {
- validLifetimeSeconds =
+ preferredLifetimeSeconds =
Math.max(
(address.getDeprecationTime() - SystemClock.elapsedRealtime()) / 1000L,
0L);
@@ -157,28 +164,23 @@
if (address.getExpirationTime() == LinkAddress.LIFETIME_PERMANENT
|| address.getExpirationTime() == LinkAddress.LIFETIME_UNKNOWN) {
- preferredLifetimeSeconds = INFINITE_LIFETIME;
+ validLifetimeSeconds = INFINITE_LIFETIME;
} else {
- preferredLifetimeSeconds =
+ validLifetimeSeconds =
Math.max(
(address.getExpirationTime() - SystemClock.elapsedRealtime()) / 1000L,
0L);
}
- byte[] message =
- RtNetlinkAddressMessage.newRtmNewAddressMessage(
- sNetlinkSeqNo++,
- address.getAddress(),
- (short) address.getPrefixLength(),
- address.getFlags(),
- (byte) address.getScope(),
- Os.if_nametoindex(mIfName),
- validLifetimeSeconds,
- preferredLifetimeSeconds);
- try {
- Os.write(mNetlinkSocket, message, 0, message.length);
- } catch (ErrnoException | InterruptedIOException e) {
- Log.e(TAG, "Failed to add address " + address, e);
+ if (!NetlinkUtils.sendRtmNewAddressRequest(
+ Os.if_nametoindex(mIfName),
+ address.getAddress(),
+ (short) address.getPrefixLength(),
+ address.getFlags(),
+ (byte) address.getScope(),
+ preferredLifetimeSeconds,
+ validLifetimeSeconds)) {
+ Log.w(TAG, "Failed to add address " + address.getAddress().getHostAddress());
return;
}
mLinkProperties.addLinkAddress(address);
@@ -188,22 +190,17 @@
/** Removes an address from the interface. */
public void removeAddress(LinkAddress address) {
Log.d(TAG, "Removing address " + address);
- byte[] message =
- RtNetlinkAddressMessage.newRtmDelAddressMessage(
- sNetlinkSeqNo++,
- address.getAddress(),
- (short) address.getPrefixLength(),
- Os.if_nametoindex(mIfName));
// Intentionally update the mLinkProperties before send netlink message because the
// address is already removed from ot-daemon and apps can't reach to the address even
// when the netlink request below fails
mLinkProperties.removeLinkAddress(address);
mLinkProperties.removeRoute(getRouteForAddress(address));
- try {
- Os.write(mNetlinkSocket, message, 0, message.length);
- } catch (ErrnoException | InterruptedIOException e) {
- Log.e(TAG, "Failed to remove address " + address, e);
+ if (!NetlinkUtils.sendRtmDelAddressRequest(
+ Os.if_nametoindex(mIfName),
+ (Inet6Address) address.getAddress(),
+ (short) address.getPrefixLength())) {
+ Log.w(TAG, "Failed to remove address " + address.getAddress().getHostAddress());
}
}
@@ -366,4 +363,66 @@
Log.e(TAG, "failed to leave group " + address.getHostAddress(), e);
}
}
+
+ /**
+ * Sets the address generation mode to {@code IN6_ADDR_GEN_MODE_NONE}.
+ *
+ * <p>So that the "thread-wpan" interface has only one IPv6 link local address which is
+ * generated by OpenThread.
+ */
+ private void setAddrGenModeToNone() {
+ StructNlMsgHdr header = new StructNlMsgHdr();
+ header.nlmsg_type = RTM_NEWLINK;
+ header.nlmsg_pid = 0;
+ header.nlmsg_seq = 0;
+ header.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+
+ StructIfinfoMsg ifInfo =
+ new StructIfinfoMsg(
+ (short) 0 /* family */,
+ 0 /* type */,
+ Os.if_nametoindex(mIfName),
+ (IFF_MULTICAST | IFF_NOARP) /* flags */,
+ 0xffffffff /* change */);
+
+ // Nested attributes
+ // IFLA_AF_SPEC
+ // AF_INET6
+ // IFLA_INET6_ADDR_GEN_MODE
+ StructNlAttr addrGenMode =
+ new StructNlAttr(IFLA_INET6_ADDR_GEN_MODE, (byte) IN6_ADDR_GEN_MODE_NONE);
+ StructNlAttr afInet6 = new StructNlAttr((short) AF_INET6, addrGenMode);
+ StructNlAttr afSpec = new StructNlAttr(IFLA_AF_SPEC, afInet6);
+
+ final int msgLength =
+ StructNlMsgHdr.STRUCT_SIZE
+ + StructIfinfoMsg.STRUCT_SIZE
+ + afSpec.getAlignedLength();
+ byte[] msg = new byte[msgLength];
+ ByteBuffer buf = ByteBuffer.wrap(msg);
+ buf.order(ByteOrder.nativeOrder());
+
+ header.nlmsg_len = msgLength;
+ header.pack(buf);
+ ifInfo.pack(buf);
+ afSpec.pack(buf);
+
+ if (buf.position() != msgLength) {
+ throw new AssertionError(
+ String.format(
+ "Unexpected netlink message size (actual = %d, expected = %d)",
+ buf.position(), msgLength));
+ }
+
+ if (DBG) {
+ Log.d(TAG, "ADDR_GEN_MODE message is:");
+ Log.d(TAG, HexDump.dumpHexString(msg));
+ }
+
+ try {
+ NetlinkUtils.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to set ADDR_GEN_MODE to NONE", e);
+ }
+ }
}
diff --git a/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java b/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java
index 91ca23e..61b6eac 100644
--- a/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java
+++ b/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java
@@ -176,7 +176,7 @@
// TODO (b/323300829): add test for removing an OT address
@Test
- public void tunInterface_joinedNetwork_otAddressesAddedToTunInterface() throws Exception {
+ public void tunInterface_joinedNetwork_otAndTunAddressesMatch() throws Exception {
mController.joinAndWait(DEFAULT_DATASET);
List<Inet6Address> otAddresses = mOtCtl.getAddresses();
@@ -185,9 +185,12 @@
// that we can write assertThat() in the Predicate
waitFor(
() -> {
- String ifconfig = runShellCommand("ifconfig thread-wpan");
- return otAddresses.stream()
- .allMatch(addr -> ifconfig.contains(addr.getHostAddress()));
+ List<Inet6Address> tunAddresses =
+ getIpv6LinkAddresses("thread-wpan").stream()
+ .map(linkAddr -> (Inet6Address) linkAddr.getAddress())
+ .toList();
+ return otAddresses.containsAll(tunAddresses)
+ && tunAddresses.containsAll(otAddresses);
},
TUN_ADDR_UPDATE_TIMEOUT);
}
diff --git a/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java b/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java
index 78f5770..ada46c8 100644
--- a/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java
+++ b/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java
@@ -301,7 +301,7 @@
return false;
}
- public static List<LinkAddress> getIpv6LinkAddresses(String interfaceName) throws IOException {
+ public static List<LinkAddress> getIpv6LinkAddresses(String interfaceName) {
List<LinkAddress> addresses = new ArrayList<>();
final String cmd = " ip -6 addr show dev " + interfaceName;
final String output = runShellCommandOrThrow(cmd);