Merge "Enable multiple active Ethernet interfaces"
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index 9ccdbe2..0829b4a 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -462,7 +462,7 @@
             mConfig.setMode(MODE_TUNNEL);
             mConfig.setSourceAddress(sourceAddress.getHostAddress());
             mConfig.setSpiResourceId(spi.getResourceId());
-            return new IpSecTransform(mContext, mConfig);
+            return new IpSecTransform(mContext, mConfig).activate();
         }
 
         /**
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 196a3bc..fa4624e 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -433,6 +433,10 @@
         }
     }
 
+    private static long addIfSupported(long stat) {
+        return (stat == UNSUPPORTED) ? 0 : stat;
+    }
+
     /**
      * Return number of packets transmitted across mobile networks since device
      * boot. Counts packets across all mobile network interfaces, and always
@@ -445,7 +449,7 @@
     public static long getMobileTxPackets() {
         long total = 0;
         for (String iface : getMobileIfaces()) {
-            total += getTxPackets(iface);
+            total += addIfSupported(getTxPackets(iface));
         }
         return total;
     }
@@ -462,7 +466,7 @@
     public static long getMobileRxPackets() {
         long total = 0;
         for (String iface : getMobileIfaces()) {
-            total += getRxPackets(iface);
+            total += addIfSupported(getRxPackets(iface));
         }
         return total;
     }
@@ -479,7 +483,7 @@
     public static long getMobileTxBytes() {
         long total = 0;
         for (String iface : getMobileIfaces()) {
-            total += getTxBytes(iface);
+            total += addIfSupported(getTxBytes(iface));
         }
         return total;
     }
@@ -496,7 +500,7 @@
     public static long getMobileRxBytes() {
         long total = 0;
         for (String iface : getMobileIfaces()) {
-            total += getRxBytes(iface);
+            total += addIfSupported(getRxBytes(iface));
         }
         return total;
     }
@@ -511,9 +515,7 @@
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
-            if (stat != UNSUPPORTED) {
-                total += stat;
-            }
+            total += addIfSupported(stat);
         }
         return total;
     }
@@ -528,9 +530,7 @@
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
-            if (stat != UNSUPPORTED) {
-                total += stat;
-            }
+            total += addIfSupported(stat);
         }
         return total;
     }
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index fe4ac6d..a07a982 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -87,6 +87,7 @@
     private static final String NETD_SERVICE_NAME = "netd";
     private static final int[] DIRECTIONS =
             new int[] {IpSecManager.DIRECTION_OUT, IpSecManager.DIRECTION_IN};
+    private static final String[] WILDCARD_ADDRESSES = new String[]{"0.0.0.0", "::"};
 
     private static final int NETD_FETCH_TIMEOUT_MS = 5000; // ms
     private static final int MAX_PORT_BIND_ATTEMPTS = 10;
@@ -413,12 +414,16 @@
                     .append(mTransformQuotaTracker)
                     .append(", mSocketQuotaTracker=")
                     .append(mSocketQuotaTracker)
+                    .append(", mTunnelQuotaTracker=")
+                    .append(mTunnelQuotaTracker)
                     .append(", mSpiRecords=")
                     .append(mSpiRecords)
                     .append(", mTransformRecords=")
                     .append(mTransformRecords)
                     .append(", mEncapSocketRecords=")
                     .append(mEncapSocketRecords)
+                    .append(", mTunnelInterfaceRecords=")
+                    .append(mTunnelInterfaceRecords)
                     .append("}")
                     .toString();
         }
@@ -815,12 +820,14 @@
             try {
                 mSrvConfig.getNetdInstance().removeVirtualTunnelInterface(mInterfaceName);
 
-                for (int direction : DIRECTIONS) {
-                    int mark = (direction == IpSecManager.DIRECTION_IN) ? mIkey : mOkey;
-                    mSrvConfig
-                            .getNetdInstance()
-                            .ipSecDeleteSecurityPolicy(
-                                    0, direction, mLocalAddress, mRemoteAddress, mark, 0xffffffff);
+                for(String wildcardAddr : WILDCARD_ADDRESSES) {
+                    for (int direction : DIRECTIONS) {
+                        int mark = (direction == IpSecManager.DIRECTION_IN) ? mIkey : mOkey;
+                        mSrvConfig
+                                .getNetdInstance()
+                                .ipSecDeleteSecurityPolicy(
+                                        0, direction, wildcardAddr, wildcardAddr, mark, 0xffffffff);
+                    }
                 }
             } catch (ServiceSpecificException e) {
                 // FIXME: get the error code and throw is at an IOException from Errno Exception
@@ -1261,19 +1268,21 @@
                     .getNetdInstance()
                     .addVirtualTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey);
 
-            for (int direction : DIRECTIONS) {
-                int mark = (direction == IpSecManager.DIRECTION_OUT) ? okey : ikey;
+            for(String wildcardAddr : WILDCARD_ADDRESSES) {
+                for (int direction : DIRECTIONS) {
+                    int mark = (direction == IpSecManager.DIRECTION_OUT) ? okey : ikey;
 
-                mSrvConfig
-                        .getNetdInstance()
-                        .ipSecAddSecurityPolicy(
+                    mSrvConfig
+                            .getNetdInstance()
+                            .ipSecAddSecurityPolicy(
                                 0, // Use 0 for reqId
                                 direction,
-                                "",
-                                "",
+                                wildcardAddr,
+                                wildcardAddr,
                                 0,
                                 mark,
                                 0xffffffff);
+                }
             }
 
             userRecord.mTunnelInterfaceRecords.put(
@@ -1646,16 +1655,18 @@
                 c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
 
                 // If outbound, also add SPI to the policy.
-                mSrvConfig
-                        .getNetdInstance()
-                        .ipSecUpdateSecurityPolicy(
-                                0, // Use 0 for reqId
-                                direction,
-                                "",
-                                "",
-                                transformInfo.getSpiRecord().getSpi(),
-                                mark,
-                                0xffffffff);
+                for(String wildcardAddr : WILDCARD_ADDRESSES) {
+                    mSrvConfig
+                            .getNetdInstance()
+                            .ipSecUpdateSecurityPolicy(
+                                    0, // Use 0 for reqId
+                                    direction,
+                                    wildcardAddr,
+                                    wildcardAddr,
+                                    transformInfo.getSpiRecord().getSpi(),
+                                    mark,
+                                    0xffffffff);
+                }
             }
 
             // Update SA with tunnel mark (ikey or okey based on direction)