Add the NAT64 prefix to LinkProperties.
Currently we support exactly one NAT64 prefix. This matches what
other components in the system (Dns64Configuration, clatd, etc.)
support.
Test: atest FrameworksNetTests
Change-Id: I45a11cebe43a5e1c60d50eca7889cb317565b598
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 4a466f3..617125b3 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -66,6 +66,7 @@
private int mMtu;
// in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
private String mTcpBufferSizes;
+ private IpPrefix mNat64Prefix;
private static final int MIN_MTU = 68;
private static final int MIN_MTU_V6 = 1280;
@@ -760,6 +761,32 @@
}
/**
+ * Returns the NAT64 prefix in use on this link, if any.
+ *
+ * @return the NAT64 prefix.
+ * @hide
+ */
+ public @Nullable IpPrefix getNat64Prefix() {
+ return mNat64Prefix;
+ }
+
+ /**
+ * Sets the NAT64 prefix in use on this link.
+ *
+ * Currently, only 96-bit prefixes (i.e., where the 32-bit IPv4 address is at the end of the
+ * 128-bit IPv6 address) are supported.
+ *
+ * @param prefix the NAT64 prefix.
+ * @hide
+ */
+ public void setNat64Prefix(IpPrefix prefix) {
+ if (prefix != null && prefix.getPrefixLength() != 96) {
+ throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix);
+ }
+ mNat64Prefix = prefix; // IpPrefix objects are immutable.
+ }
+
+ /**
* Adds a stacked link.
*
* If there is already a stacked link with the same interface name as link,
@@ -831,6 +858,7 @@
mStackedLinks.clear();
mMtu = 0;
mTcpBufferSizes = null;
+ mNat64Prefix = null;
}
/**
@@ -908,6 +936,11 @@
resultJoiner.add(mHttpProxy.toString());
}
+ if (mNat64Prefix != null) {
+ resultJoiner.add("Nat64Prefix:");
+ resultJoiner.add(mNat64Prefix.toString());
+ }
+
final Collection<LinkProperties> stackedLinksValues = mStackedLinks.values();
if (!stackedLinksValues.isEmpty()) {
final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]");
@@ -1295,6 +1328,17 @@
}
/**
+ * Compares this {@code LinkProperties} NAT64 prefix against the target.
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ * @hide
+ */
+ public boolean isIdenticalNat64Prefix(LinkProperties target) {
+ return Objects.equals(mNat64Prefix, target.mNat64Prefix);
+ }
+
+ /**
* Compares this {@code LinkProperties} instance against the target
* LinkProperties in {@code obj}. Two LinkPropertieses are equal if
* all their fields are equal in values.
@@ -1330,7 +1374,8 @@
&& isIdenticalHttpProxy(target)
&& isIdenticalStackedLinks(target)
&& isIdenticalMtu(target)
- && isIdenticalTcpBufferSizes(target);
+ && isIdenticalTcpBufferSizes(target)
+ && isIdenticalNat64Prefix(target);
}
/**
@@ -1443,7 +1488,8 @@
+ ((null == mTcpBufferSizes) ? 0 : mTcpBufferSizes.hashCode())
+ (mUsePrivateDns ? 57 : 0)
+ mPcscfs.size() * 67
- + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode());
+ + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
+ + Objects.hash(mNat64Prefix);
}
/**
@@ -1484,6 +1530,8 @@
} else {
dest.writeByte((byte)0);
}
+ dest.writeParcelable(mNat64Prefix, 0);
+
ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
dest.writeList(stackedLinks);
}
@@ -1535,6 +1583,7 @@
if (in.readByte() == 1) {
netProp.setHttpProxy(in.readParcelable(null));
}
+ netProp.setNat64Prefix(in.readParcelable(null));
ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
in.readList(stackedLinks, LinkProperties.class.getClassLoader());
for (LinkProperties stackedLink: stackedLinks) {
diff --git a/tests/net/java/android/net/LinkPropertiesTest.java b/tests/net/java/android/net/LinkPropertiesTest.java
index f82b380..932fee0 100644
--- a/tests/net/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/java/android/net/LinkPropertiesTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -33,6 +34,9 @@
import android.system.OsConstants;
import android.util.ArraySet;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
@@ -41,9 +45,6 @@
import java.util.List;
import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LinkPropertiesTest {
@@ -504,6 +505,40 @@
}
@Test
+ public void testNat64Prefix() throws Exception {
+ LinkProperties lp = new LinkProperties();
+ lp.addLinkAddress(LINKADDRV4);
+ lp.addLinkAddress(LINKADDRV6);
+
+ assertNull(lp.getNat64Prefix());
+
+ IpPrefix p = new IpPrefix("64:ff9b::/96");
+ lp.setNat64Prefix(p);
+ assertEquals(p, lp.getNat64Prefix());
+
+ p = new IpPrefix("2001:db8:a:b:1:2:3::/96");
+ lp.setNat64Prefix(p);
+ assertEquals(p, lp.getNat64Prefix());
+
+ p = new IpPrefix("2001:db8:a:b:1:2::/80");
+ try {
+ lp.setNat64Prefix(p);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ p = new IpPrefix("64:ff9b::/64");
+ try {
+ lp.setNat64Prefix(p);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ assertEquals(new IpPrefix("2001:db8:a:b:1:2:3::/96"), lp.getNat64Prefix());
+
+ lp.setNat64Prefix(null);
+ assertNull(lp.getNat64Prefix());
+ }
+
+ @Test
public void testIsProvisioned() {
LinkProperties lp4 = new LinkProperties();
assertFalse("v4only:empty", lp4.isProvisioned());
@@ -815,7 +850,7 @@
}
@Test
- public void testLinkPropertiesParcelable() {
+ public void testLinkPropertiesParcelable() throws Exception {
LinkProperties source = new LinkProperties();
source.setInterfaceName(NAME);
// set 2 link addresses
@@ -833,6 +868,8 @@
source.setMtu(MTU);
+ source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
+
Parcel p = Parcel.obtain();
source.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);