From 981b34f6b84b557943e2735717a2ecb7adc73521 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 8 Jan 2019 09:58:59 +0900 Subject: [PATCH] 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 --- core/java/android/net/LinkProperties.java | 53 ++++++++++++++++++- .../java/android/net/LinkPropertiesTest.java | 45 ++++++++++++++-- 2 files changed, 92 insertions(+), 6 deletions(-) diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 4a466f3007..617125b3f9 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -66,6 +66,7 @@ public final class LinkProperties implements Parcelable { 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; @@ -759,6 +760,32 @@ public final class LinkProperties implements Parcelable { return mHttpProxy; } + /** + * 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. * @@ -831,6 +858,7 @@ public final class LinkProperties implements Parcelable { mStackedLinks.clear(); mMtu = 0; mTcpBufferSizes = null; + mNat64Prefix = null; } /** @@ -908,6 +936,11 @@ public final class LinkProperties implements Parcelable { resultJoiner.add(mHttpProxy.toString()); } + if (mNat64Prefix != null) { + resultJoiner.add("Nat64Prefix:"); + resultJoiner.add(mNat64Prefix.toString()); + } + final Collection stackedLinksValues = mStackedLinks.values(); if (!stackedLinksValues.isEmpty()) { final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]"); @@ -1294,6 +1327,17 @@ public final class LinkProperties implements Parcelable { return Objects.equals(mTcpBufferSizes, target.mTcpBufferSizes); } + /** + * 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 @@ -1330,7 +1374,8 @@ public final class LinkProperties implements Parcelable { && isIdenticalHttpProxy(target) && isIdenticalStackedLinks(target) && isIdenticalMtu(target) - && isIdenticalTcpBufferSizes(target); + && isIdenticalTcpBufferSizes(target) + && isIdenticalNat64Prefix(target); } /** @@ -1443,7 +1488,8 @@ public final class LinkProperties implements Parcelable { + ((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 @@ public final class LinkProperties implements Parcelable { } else { dest.writeByte((byte)0); } + dest.writeParcelable(mNat64Prefix, 0); + ArrayList stackedLinks = new ArrayList<>(mStackedLinks.values()); dest.writeList(stackedLinks); } @@ -1535,6 +1583,7 @@ public final class LinkProperties implements Parcelable { if (in.readByte() == 1) { netProp.setHttpProxy(in.readParcelable(null)); } + netProp.setNat64Prefix(in.readParcelable(null)); ArrayList stackedLinks = new ArrayList(); 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 f82b380f5d..932fee0c19 100644 --- a/tests/net/java/android/net/LinkPropertiesTest.java +++ b/tests/net/java/android/net/LinkPropertiesTest.java @@ -18,6 +18,7 @@ package android.net; 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.support.test.runner.AndroidJUnit4; 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.Collections; import java.util.List; import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; - @RunWith(AndroidJUnit4.class) @SmallTest public class LinkPropertiesTest { @@ -503,6 +504,40 @@ public class LinkPropertiesTest { assertTrue(lp.equals(lp)); } + @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(); @@ -815,7 +850,7 @@ public class LinkPropertiesTest { } @Test - public void testLinkPropertiesParcelable() { + public void testLinkPropertiesParcelable() throws Exception { LinkProperties source = new LinkProperties(); source.setInterfaceName(NAME); // set 2 link addresses @@ -833,6 +868,8 @@ public class LinkPropertiesTest { 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);