Network-related commands porting

Test: built, flashed, booted
      system/netd/tests/runtests.sh passes

Change-Id: I14160f81050c2782301d27e622461e66b10fd070
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index ff24ccd..3e76fcf 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -25,6 +25,7 @@
 #include <android-base/strings.h>
 #include <cutils/properties.h>
 #include <log/log.h>
+#include <resolv_netid.h>
 #include <utils/Errors.h>
 #include <utils/String16.h>
 
@@ -40,6 +41,7 @@
 #include "InterfaceController.h"
 #include "NetdConstants.h"
 #include "NetdNativeService.h"
+#include "Permission.h"
 #include "Process.h"
 #include "RouteController.h"
 #include "SockDiag.h"
@@ -313,11 +315,10 @@
     return statusFromErrcode(res);
 }
 
-binder::Status NetdNativeService::networkCreatePhysical(int32_t netId,
-        const std::string& permission) {
+binder::Status NetdNativeService::networkCreatePhysical(int32_t netId, int32_t permission) {
     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
     auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId).arg(permission);
-    int ret = gCtls->netCtrl.createPhysicalNetwork(netId, stringToPermission(permission.c_str()));
+    int ret = gCtls->netCtrl.createPhysicalNetwork(netId, convertPermission(permission));
     gLog.log(entry.returns(ret).withAutomaticDuration());
     return statusFromErrcode(ret);
 }
@@ -1081,5 +1082,175 @@
     return binder::Status::ok();
 }
 
+binder::Status NetdNativeService::networkAddRoute(int32_t netId, const std::string& ifName,
+                                                  const std::string& destination,
+                                                  const std::string& nextHop) {
+    // Public methods of NetworkController are thread-safe.
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry()
+                         .prettyFunction(__PRETTY_FUNCTION__)
+                         .arg(netId)
+                         .arg(ifName)
+                         .arg(destination)
+                         .arg(nextHop);
+    bool legacy = false;
+    uid_t uid = 0;  // UID is only meaningful for legacy routes.
+    int res = gCtls->netCtrl.addRoute(netId, ifName.c_str(), destination.c_str(),
+                                      nextHop.empty() ? nullptr : nextHop.c_str(), legacy, uid);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::networkRemoveRoute(int32_t netId, const std::string& ifName,
+                                                     const std::string& destination,
+                                                     const std::string& nextHop) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry()
+                         .prettyFunction(__PRETTY_FUNCTION__)
+                         .arg(netId)
+                         .arg(ifName)
+                         .arg(destination)
+                         .arg(nextHop);
+    bool legacy = false;
+    uid_t uid = 0;  // UID is only meaningful for legacy routes.
+    int res = gCtls->netCtrl.removeRoute(netId, ifName.c_str(), destination.c_str(),
+                                         nextHop.empty() ? nullptr : nextHop.c_str(), legacy, uid);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::networkAddLegacyRoute(int32_t netId, const std::string& ifName,
+                                                        const std::string& destination,
+                                                        const std::string& nextHop, int32_t uid) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry()
+                         .prettyFunction(__PRETTY_FUNCTION__)
+                         .arg(netId)
+                         .arg(ifName)
+                         .arg(destination)
+                         .arg(nextHop)
+                         .arg(uid);
+    bool legacy = true;
+    int res = gCtls->netCtrl.addRoute(netId, ifName.c_str(), destination.c_str(),
+                                      nextHop.empty() ? nullptr : nextHop.c_str(), legacy,
+                                      (uid_t) uid);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::networkRemoveLegacyRoute(int32_t netId, const std::string& ifName,
+                                                           const std::string& destination,
+                                                           const std::string& nextHop,
+                                                           int32_t uid) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry()
+                         .prettyFunction(__PRETTY_FUNCTION__)
+                         .arg(netId)
+                         .arg(ifName)
+                         .arg(destination)
+                         .arg(nextHop)
+                         .arg(uid);
+    bool legacy = true;
+    int res = gCtls->netCtrl.removeRoute(netId, ifName.c_str(), destination.c_str(),
+                                         nextHop.empty() ? nullptr : nextHop.c_str(), legacy,
+                                         (uid_t) uid);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::networkGetDefault(int32_t* netId) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
+    *netId = gCtls->netCtrl.getDefaultNetwork();
+    gLog.log(entry.returns(*netId).withAutomaticDuration());
+    return binder::Status::ok();
+}
+
+binder::Status NetdNativeService::networkSetDefault(int32_t netId) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId);
+    int res = gCtls->netCtrl.setDefaultNetwork(netId);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::networkClearDefault() {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
+    unsigned netId = NETID_UNSET;
+    int res = gCtls->netCtrl.setDefaultNetwork(netId);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+std::vector<uid_t> NetdNativeService::intsToUids(const std::vector<int32_t>& intUids) {
+    return {begin(intUids), end(intUids)};
+}
+
+Permission NetdNativeService::convertPermission(int32_t permission) {
+    switch (permission) {
+        case INetd::PERMISSION_NETWORK:
+            return Permission::PERMISSION_NETWORK;
+        case INetd::PERMISSION_SYSTEM:
+            return Permission::PERMISSION_SYSTEM;
+        default:
+            return Permission::PERMISSION_NONE;
+    }
+}
+
+binder::Status NetdNativeService::networkSetPermissionForNetwork(int32_t netId,
+                                                                 int32_t permission) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId).arg(permission);
+    std::vector<unsigned> netIds = {(unsigned) netId};
+    int res = gCtls->netCtrl.setPermissionForNetworks(convertPermission(permission), netIds);
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::networkSetPermissionForUser(int32_t permission,
+                                                              const std::vector<int32_t>& uids) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(permission).arg(uids);
+    gCtls->netCtrl.setPermissionForUsers(convertPermission(permission), intsToUids(uids));
+    gLog.log(entry.withAutomaticDuration());
+    return binder::Status::ok();
+}
+
+binder::Status NetdNativeService::networkClearPermissionForUser(const std::vector<int32_t>& uids) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uids);
+    Permission permission = Permission::PERMISSION_NONE;
+    gCtls->netCtrl.setPermissionForUsers(permission, intsToUids(uids));
+    gLog.log(entry.withAutomaticDuration());
+    return binder::Status::ok();
+}
+
+binder::Status NetdNativeService::NetdNativeService::networkSetProtectAllow(int32_t uid) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+    std::vector<uid_t> uids = {(uid_t) uid};
+    gCtls->netCtrl.allowProtect(uids);
+    gLog.log(entry.withAutomaticDuration());
+    return binder::Status::ok();
+}
+
+binder::Status NetdNativeService::networkSetProtectDeny(int32_t uid) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+    std::vector<uid_t> uids = {(uid_t) uid};
+    gCtls->netCtrl.denyProtect(uids);
+    gLog.log(entry.withAutomaticDuration());
+    return binder::Status::ok();
+}
+
+binder::Status NetdNativeService::networkCanProtect(int32_t uid, bool* ret) {
+    ENFORCE_PERMISSION(NETWORK_STACK);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+    *ret = gCtls->netCtrl.canProtect((uid_t) uid);
+    gLog.log(entry.returns(*ret).withAutomaticDuration());
+    return binder::Status::ok();
+}
+
 }  // namespace net
 }  // namespace android