Add XfrmController to NetdNativeService

Add a new controller to Netd that can handle IPSec XFRM
commands from the framework.

-Add new XfrmController controller
-Connect XfrmController to Controllers
-Add APIs in XfrmController for creating Transport IpSec Assocs

Bug: 34811756
Test: 34812052
Change-Id: If518a53a83fa76ea4c866992055a741ae064c30d
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index a575642..f0729b1 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -60,6 +60,16 @@
     }
 }
 
+binder::Status getXfrmStatus(int xfrmCode) {
+    switch(xfrmCode) {
+        case 0:
+            return binder::Status::ok();
+        case -ENOENT:
+            return binder::Status::fromServiceSpecificError(xfrmCode);
+    }
+    return binder::Status::fromExceptionCode(xfrmCode);
+}
+
 #define ENFORCE_DEBUGGABLE() {                              \
     char value[PROPERTY_VALUE_MAX + 1];                     \
     if (property_get("ro.debuggable", value, NULL) != 1     \
@@ -309,5 +319,96 @@
             : binder::Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT);
 }
 
+binder::Status NetdNativeService::ipSecAllocateSpi(
+        int32_t transformId,
+        int32_t direction,
+        const std::string& localAddress,
+        const std::string& remoteAddress,
+        int32_t inSpi,
+        int32_t* outSpi) {
+    // Necessary locking done in IpSecService and kernel
+    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
+    ALOGD("ipSecAllocateSpi()");
+    return getXfrmStatus(gCtls->xfrmCtrl.ipSecAllocateSpi(
+                    transformId,
+                    direction,
+                    localAddress,
+                    remoteAddress,
+                    inSpi,
+                    outSpi));
+}
+
+binder::Status NetdNativeService::ipSecAddSecurityAssociation(
+        int32_t transformId,
+        int32_t mode,
+        int32_t direction,
+        const std::string& localAddress,
+        const std::string& remoteAddress,
+        int64_t underlyingNetworkHandle,
+        int32_t spi,
+        const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
+        const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
+        int32_t encapType,
+        int32_t encapLocalPort,
+        int32_t encapRemotePort,
+        int32_t* allocatedSpi) {
+    // Necessary locking done in IpSecService and kernel
+    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
+    ALOGD("ipSecAddSecurityAssociation()");
+    return getXfrmStatus(gCtls->xfrmCtrl.ipSecAddSecurityAssociation(
+              transformId, mode, direction, localAddress, remoteAddress,
+              underlyingNetworkHandle,
+              spi,
+              authAlgo, authKey, authTruncBits,
+              cryptAlgo, cryptKey, cryptTruncBits,
+              encapType, encapLocalPort, encapRemotePort,
+              allocatedSpi));
+}
+
+binder::Status NetdNativeService::ipSecDeleteSecurityAssociation(
+        int32_t transformId,
+        int32_t direction,
+        const std::string& localAddress,
+        const std::string& remoteAddress,
+        int32_t spi) {
+    // Necessary locking done in IpSecService and kernel
+    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
+    ALOGD("ipSecDeleteSecurityAssociation()");
+    return getXfrmStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityAssociation(
+                    transformId,
+                    direction,
+                    localAddress,
+                    remoteAddress,
+                    spi));
+}
+
+binder::Status NetdNativeService::ipSecApplyTransportModeTransform(
+        const android::base::unique_fd& socket,
+        int32_t transformId,
+        int32_t direction,
+        const std::string& localAddress,
+        const std::string& remoteAddress,
+        int32_t spi) {
+    // Necessary locking done in IpSecService and kernel
+    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
+    ALOGD("ipSecApplyTransportModeTransform()");
+    return getXfrmStatus(gCtls->xfrmCtrl.ipSecApplyTransportModeTransform(
+                    socket,
+                    transformId,
+                    direction,
+                    localAddress,
+                    remoteAddress,
+                    spi));
+}
+
+binder::Status NetdNativeService::ipSecRemoveTransportModeTransform(
+            const android::base::unique_fd& socket) {
+    // Necessary locking done in IpSecService and kernel
+    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
+    ALOGD("ipSecRemoveTransportModeTransform()");
+    return getXfrmStatus(gCtls->xfrmCtrl.ipSecRemoveTransportModeTransform(
+                    socket));
+}
+
 }  // namespace net
 }  // namespace android