Support IPv4-only and IPv6-only provisioning
Bug: 28437662
Change-Id: I95b2d6eeb48cc526c8e6e015c5130ff9141fb898
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 34152cf..d8eab35 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -276,6 +276,16 @@
public static class Builder {
private ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
+ public Builder withoutIPv4() {
+ mConfig.mEnableIPv4 = false;
+ return this;
+ }
+
+ public Builder withoutIPv6() {
+ mConfig.mEnableIPv6 = false;
+ return this;
+ }
+
public Builder withoutIpReachabilityMonitor() {
mConfig.mUsingIpReachabilityMonitor = false;
return this;
@@ -311,6 +321,8 @@
}
}
+ /* package */ boolean mEnableIPv4 = true;
+ /* package */ boolean mEnableIPv6 = true;
/* package */ boolean mUsingIpReachabilityMonitor = true;
/* package */ int mRequestedPreDhcpActionMs;
/* package */ StaticIpConfiguration mStaticIpConfig;
@@ -320,6 +332,8 @@
public ProvisioningConfiguration() {}
public ProvisioningConfiguration(ProvisioningConfiguration other) {
+ mEnableIPv4 = other.mEnableIPv4;
+ mEnableIPv6 = other.mEnableIPv6;
mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
mRequestedPreDhcpActionMs = other.mRequestedPreDhcpActionMs;
mStaticIpConfig = other.mStaticIpConfig;
@@ -330,6 +344,8 @@
@Override
public String toString() {
return new StringJoiner(", ", getClass().getSimpleName() + "{", "}")
+ .add("mEnableIPv4: " + mEnableIPv4)
+ .add("mEnableIPv6: " + mEnableIPv6)
.add("mUsingIpReachabilityMonitor: " + mUsingIpReachabilityMonitor)
.add("mRequestedPreDhcpActionMs: " + mRequestedPreDhcpActionMs)
.add("mStaticIpConfig: " + mStaticIpConfig)
@@ -883,6 +899,51 @@
}
}
+ private boolean startIPv4() {
+ // If we have a StaticIpConfiguration attempt to apply it and
+ // handle the result accordingly.
+ if (mConfiguration.mStaticIpConfig != null) {
+ if (setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {
+ handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
+ } else {
+ if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
+ recordMetric(IpManagerEvent.PROVISIONING_FAIL);
+ mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
+ return false;
+ }
+ } else {
+ // Start DHCPv4.
+ mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpManager.this, mInterfaceName);
+ mDhcpClient.registerForPreDhcpNotification();
+ mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
+
+ if (mConfiguration.mProvisioningTimeoutMs > 0) {
+ final long alarmTime = SystemClock.elapsedRealtime() +
+ mConfiguration.mProvisioningTimeoutMs;
+ mProvisioningTimeoutAlarm.schedule(alarmTime);
+ }
+ }
+
+ return true;
+ }
+
+ private boolean startIPv6() {
+ // Set privacy extensions.
+ try {
+ mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
+ mNwService.enableIpv6(mInterfaceName);
+ } catch (RemoteException re) {
+ Log.e(mTag, "Unable to change interface settings: " + re);
+ return false;
+ } catch (IllegalStateException ie) {
+ Log.e(mTag, "Unable to change interface settings: " + ie);
+ return false;
+ }
+
+ return true;
+ }
+
+
class StoppedState extends State {
@Override
public void enter() {
@@ -978,15 +1039,9 @@
mCallback.setFallbackMulticastFilter(mMulticastFiltering);
}
- // Set privacy extensions.
- try {
- mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
- mNwService.enableIpv6(mInterfaceName);
- // TODO: Perhaps clearIPv4Address() as well.
- } catch (RemoteException re) {
- Log.e(mTag, "Unable to change interface settings: " + re);
- } catch (IllegalStateException ie) {
- Log.e(mTag, "Unable to change interface settings: " + ie);
+ if (mConfiguration.mEnableIPv6) {
+ // TODO: Consider transitionTo(mStoppingState) if this fails.
+ startIPv6();
}
if (mConfiguration.mUsingIpReachabilityMonitor) {
@@ -1001,31 +1056,10 @@
});
}
- // If we have a StaticIpConfiguration attempt to apply it and
- // handle the result accordingly.
- if (mConfiguration.mStaticIpConfig != null) {
- if (setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {
- handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
- } else {
- if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
- recordMetric(IpManagerEvent.PROVISIONING_FAIL);
- mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
+ if (mConfiguration.mEnableIPv4) {
+ if (!startIPv4()) {
transitionTo(mStoppingState);
}
- } else {
- // Start DHCPv4.
- mDhcpClient = DhcpClient.makeDhcpClient(
- mContext,
- IpManager.this,
- mInterfaceName);
- mDhcpClient.registerForPreDhcpNotification();
- mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
-
- if (mConfiguration.mProvisioningTimeoutMs > 0) {
- final long alarmTime = SystemClock.elapsedRealtime() +
- mConfiguration.mProvisioningTimeoutMs;
- mProvisioningTimeoutAlarm.schedule(alarmTime);
- }
}
}