Merge "PermissionMonitor: Move intent receiver to ConnectivityService."
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index 1bc0d32..77562db 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -25,6 +25,7 @@
 import static android.system.OsConstants.RT_SCOPE_SITE;
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -167,7 +168,7 @@
      * @param prefixLength The prefix length.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public LinkAddress(InetAddress address, int prefixLength) {
         this(address, prefixLength, 0, 0);
         this.scope = scopeForUnicastAddress(address);
@@ -190,7 +191,7 @@
      * @param string The string to parse.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public LinkAddress(String address) {
         this(address, 0, 0);
         this.scope = scopeForUnicastAddress(this.address);
diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java
index 771faaf..be1a455 100644
--- a/tests/net/java/android/net/IpSecConfigTest.java
+++ b/tests/net/java/android/net/IpSecConfigTest.java
@@ -47,6 +47,7 @@
         assertNull(c.getEncryption());
         assertNull(c.getAuthentication());
         assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getSpiResourceId());
+        assertEquals(0, c.getXfrmInterfaceId());
     }
 
     private IpSecConfig getSampleConfig() {
@@ -77,6 +78,7 @@
         c.setNattKeepaliveInterval(42);
         c.setMarkValue(12);
         c.setMarkMask(23);
+        c.setXfrmInterfaceId(34);
 
         return c;
     }
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 9b919ab..4dc0341 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -71,6 +71,9 @@
     private final LinkAddress mLocalInnerAddress;
     private final int mFamily;
 
+    private static final int[] ADDRESS_FAMILIES =
+            new int[] {AF_INET, AF_INET6};
+
     @Parameterized.Parameters
     public static Collection ipSecConfigs() {
         return Arrays.asList(
@@ -196,6 +199,7 @@
                         anyString(),
                         eq(TEST_SPI),
                         anyInt(),
+                        anyInt(),
                         anyInt());
 
         // Verify quota and RefcountedResource objects cleaned up
@@ -231,6 +235,7 @@
                         anyString(),
                         eq(TEST_SPI),
                         anyInt(),
+                        anyInt(),
                         anyInt());
 
         // Verify quota and RefcountedResource objects cleaned up
@@ -304,7 +309,8 @@
                         eq((authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0),
                         eq(config.getEncapType()),
                         eq(encapSocketPort),
-                        eq(config.getEncapRemotePort()));
+                        eq(config.getEncapRemotePort()),
+                        eq(config.getXfrmInterfaceId()));
     }
 
     @Test
@@ -430,6 +436,7 @@
                         anyString(),
                         eq(TEST_SPI),
                         anyInt(),
+                        anyInt(),
                         anyInt());
         // quota is not released until the SPI is released by the Transform
         assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
@@ -452,6 +459,7 @@
                         anyString(),
                         eq(TEST_SPI),
                         anyInt(),
+                        anyInt(),
                         anyInt());
 
         // Verify quota and RefcountedResource objects cleaned up
@@ -469,6 +477,7 @@
                         anyString(),
                         anyInt(),
                         anyInt(),
+                        anyInt(),
                         anyInt());
         assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
 
@@ -504,6 +513,7 @@
                         anyString(),
                         eq(TEST_SPI),
                         anyInt(),
+                        anyInt(),
                         anyInt());
 
         // Verify quota and RefcountedResource objects cleaned up
@@ -572,11 +582,12 @@
 
         assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
         verify(mMockNetd)
-                .addVirtualTunnelInterface(
+                .ipSecAddTunnelInterface(
                         eq(createTunnelResp.interfaceName),
                         eq(mSourceAddr),
                         eq(mDestinationAddr),
                         anyInt(),
+                        anyInt(),
                         anyInt());
     }
 
@@ -591,7 +602,7 @@
 
         // Verify quota and RefcountedResource objects cleaned up
         assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
-        verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName));
+        verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
         try {
             userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
                     createTunnelResp.resourceId);
@@ -614,7 +625,7 @@
 
         // Verify quota and RefcountedResource objects cleaned up
         assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
-        verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName));
+        verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
         try {
             userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
                     createTunnelResp.resourceId);
@@ -624,6 +635,41 @@
     }
 
     @Test
+    public void testApplyTunnelModeTransform() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+
+        IpSecTransformResponse createTransformResp =
+                mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+        IpSecTunnelInterfaceResponse createTunnelResp =
+                createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
+
+        int transformResourceId = createTransformResp.resourceId;
+        int tunnelResourceId = createTunnelResp.resourceId;
+        mIpSecService.applyTunnelModeTransform(tunnelResourceId, IpSecManager.DIRECTION_OUT,
+                transformResourceId, "blessedPackage");
+
+        for (int selAddrFamily : ADDRESS_FAMILIES) {
+            verify(mMockNetd)
+                    .ipSecUpdateSecurityPolicy(
+                            eq(mUid),
+                            eq(selAddrFamily),
+                            eq(IpSecManager.DIRECTION_OUT),
+                            anyString(),
+                            anyString(),
+                            eq(TEST_SPI),
+                            anyInt(), // iKey/oKey
+                            anyInt(), // mask
+                            eq(tunnelResourceId));
+        }
+
+        ipSecConfig.setXfrmInterfaceId(tunnelResourceId);
+        verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
+    }
+
+    @Test
     public void testAddRemoveAddressFromTunnelInterface() throws Exception {
         for (String pkgName : new String[]{"blessedPackage", "systemPackage"}) {
             IpSecTunnelInterfaceResponse createTunnelResp =