Add a feature flag to control if accepting the IPv6 link-local DNS.
The default feature flag is true which doesn't change the current
behavior, just providing a function method which allows us to push
a different flag value from g3 and does not accpet the IPv6 link-local
dns, then we can do A/B testing on beta devices to see if the fix does
work as expected.
Bug: 163492391
Test: atest NetworkStackIntegrationTests
Test: atest NetworkStackRootTests
(cherry picked from https://android-review.googlesource.com/q/commit:eedf05b688aa3d910089b2305312dd488e7150d8)
Merged-In: I405d023711ad0c4c71541675eeda8cd2582e1bdc
Change-Id: I405d023711ad0c4c71541675eeda8cd2582e1bdc
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java
index f1fb3da..052cfae 100644
--- a/src/android/net/ip/IpClientLinkObserver.java
+++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -28,6 +28,7 @@
import static com.android.net.module.util.netlink.NetlinkConstants.RTPROT_KERNEL;
import static com.android.net.module.util.netlink.NetlinkConstants.RTPROT_RA;
import static com.android.net.module.util.netlink.NetlinkConstants.RT_SCOPE_UNIVERSE;
+import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_ACCEPT_IPV6_LINK_LOCAL_DNS_VERSION;
import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_PARSE_NETLINK_EVENTS_VERSION;
import android.app.AlarmManager;
@@ -203,6 +204,11 @@
mHandler.post(mNetlinkMonitor::stop);
}
+ private boolean isIpv6LinkLocalDnsAccepted() {
+ return mDependencies.isFeatureEnabled(mContext,
+ IPCLIENT_ACCEPT_IPV6_LINK_LOCAL_DNS_VERSION, true /* default value */);
+ }
+
private void maybeLog(String operation, String iface, LinkAddress address) {
if (DBG) {
Log.d(mTag, operation + ": " + address + " on " + iface
@@ -540,8 +546,11 @@
if (!mNetlinkEventParsingEnabled) return;
final String[] addresses = new String[opt.servers.length];
for (int i = 0; i < opt.servers.length; i++) {
- final Inet6Address addr = opt.servers[i];
- addresses[i] = InetAddressUtils.withScopeId(addr, mIfindex).getHostAddress();
+ final Inet6Address addr = InetAddressUtils.withScopeId(opt.servers[i], mIfindex);
+ if (!addr.isLinkLocalAddress()
+ || (addr.isLinkLocalAddress() && isIpv6LinkLocalDnsAccepted())) {
+ addresses[i] = addr.getHostAddress();
+ }
}
updateInterfaceDnsServerInfo(opt.header.lifetime, addresses);
}
diff --git a/src/com/android/networkstack/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java
index 147c33a..e87b824 100755
--- a/src/com/android/networkstack/util/NetworkStackUtils.java
+++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -240,6 +240,14 @@
"ipclient_parse_netlink_events_version";
/**
+ * Experiment flag to check if an on-link IPv6 link local DNS is acceptable. The default flag
+ * value is true, just add this flag for A/B testing to see if this fix works as expected via
+ * experiment rollout.
+ */
+ public static final String IPCLIENT_ACCEPT_IPV6_LINK_LOCAL_DNS_VERSION =
+ "ipclient_accept_ipv6_link_local_dns_version";
+
+ /**
* Experiment flag to disable accept_ra parameter when IPv6 provisioning loss happens due to
* the default route has gone.
*/
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index 2fb5ac8..69e7b69 100644
--- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -2046,12 +2046,14 @@
reset(mCb);
}
- @Test
- public void testRaRdnss_Ipv6LinkLocalDns() throws Exception {
+ private void runRaRdnssIpv6LinkLocalDnsTest(boolean isIpv6LinkLocalDnsAccepted)
+ throws Exception {
ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
.withoutIpReachabilityMonitor()
.withoutIPv4()
.build();
+ setFeatureEnabled(NetworkStackUtils.IPCLIENT_ACCEPT_IPV6_LINK_LOCAL_DNS_VERSION,
+ isIpv6LinkLocalDnsAccepted /* default value */);
startIpClientProvisioning(config);
final ByteBuffer pio = buildPioOption(600, 300, "2001:db8:1::/64");
@@ -2063,7 +2065,11 @@
waitForRouterSolicitation();
mPacketReader.sendResponse(ra);
+ }
+ @Test
+ public void testRaRdnss_Ipv6LinkLocalDns() throws Exception {
+ runRaRdnssIpv6LinkLocalDnsTest(true /* isIpv6LinkLocalDnsAccepted */);
final ArgumentCaptor<LinkProperties> captor = ArgumentCaptor.forClass(LinkProperties.class);
verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningSuccess(captor.capture());
final LinkProperties lp = captor.getValue();
@@ -2073,6 +2079,20 @@
assertTrue(lp.isIpv6Provisioned());
}
+ @Test
+ public void testRaRdnss_disableIpv6LinkLocalDns() throws Exception {
+ // Only run the test when the flag of parsing netlink events is enabled, feature flag
+ // "ipclient_accept_ipv6_link_local_dns" doesn't affect the legacy code.
+ assumeTrue(mIsNetlinkEventParseEnabled);
+ runRaRdnssIpv6LinkLocalDnsTest(false /* isIpv6LinkLocalDnsAccepted */);
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(argThat(lp -> {
+ return lp.hasGlobalIpv6Address()
+ && lp.hasIpv6DefaultRoute()
+ && !lp.hasIpv6DnsServer();
+ }));
+ verify(mCb, never()).onProvisioningSuccess(any());
+ }
+
private void expectNat64PrefixUpdate(InOrder inOrder, IpPrefix expected) throws Exception {
inOrder.verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(
argThat(lp -> Objects.equals(expected, lp.getNat64Prefix())));