OSDN Git Service

Introduce Netd APIs for multinetworks.
authorSreeram Ramachandran <sreeram@google.com>
Thu, 27 Mar 2014 01:33:47 +0000 (18:33 -0700)
committerSreeram Ramachandran <sreeram@google.com>
Tue, 13 May 2014 17:30:23 +0000 (17:30 +0000)
Just stubs for now. Implementation will follow in subsequent CLs.

Change-Id: I10a2e4aca594c10a26d58afb4c250141386d3f0f
(cherry picked from commit 0d5146bed37b4e5b6909617e5f958a66bfee1e48)

Android.mk
CommandListener.cpp
CommandListener.h
Fwmark.h [new file with mode: 0644]
NetId.cpp [new file with mode: 0644]
NetId.h [new file with mode: 0644]

index 0c6210c..4e7df6b 100644 (file)
@@ -14,6 +14,7 @@ LOCAL_SRC_FILES:=                                      \
                   NatController.cpp                    \
                   NetdCommand.cpp                      \
                   NetdConstants.cpp                    \
+                  NetId.cpp                            \
                   NetlinkHandler.cpp                   \
                   NetlinkManager.cpp                   \
                   NetworkController.cpp                \
index 6ec2afc..fb7c371 100644 (file)
@@ -44,6 +44,7 @@
 #include "oem_iptables_hook.h"
 #include "NetdConstants.h"
 #include "FirewallController.h"
+#include "NetId.h"
 
 NetworkController *CommandListener::sNetCtrl = NULL;
 TetherController *CommandListener::sTetherCtrl = NULL;
@@ -148,6 +149,7 @@ CommandListener::CommandListener() :
     registerCmd(new ResolverCmd());
     registerCmd(new FirewallCmd());
     registerCmd(new ClatdCmd());
+    registerCmd(new NetworkCmd());
 
     if (!sNetCtrl)
         sNetCtrl = new NetworkController();
@@ -1587,3 +1589,95 @@ int CommandListener::ClatdCmd::runCommand(SocketClient *cli, int argc,
 
     return 0;
 }
+
+CommandListener::NetworkCmd::NetworkCmd() : NetdCommand("network") {
+}
+
+int CommandListener::NetworkCmd::syntaxError(SocketClient* cli, const char* message) {
+    cli->sendMsg(ResponseCode::CommandSyntaxError, message, false);
+    return 0;
+}
+
+int CommandListener::NetworkCmd::paramError(SocketClient* cli, const char* message) {
+    cli->sendMsg(ResponseCode::CommandParameterError, message, false);
+    return 0;
+}
+
+int CommandListener::NetworkCmd::runCommand(SocketClient* cli, int argc, char** argv) {
+    if (argc < 2) {
+        return syntaxError(cli, "Missing argument");
+    }
+    //    0      1       2         3         4
+    // network create <netId> <interface> [CNS|CI]
+    if (!strcmp(argv[1], "create")) {
+        if (argc < 4) {
+            return syntaxError(cli, "Missing argument");
+        }
+        unsigned int netId = strtoul(argv[2], NULL, 0);
+        if (!isNetIdValid(netId)) {
+            return paramError(cli, "Invalid NetId");
+        }
+        const char* iface = argv[3];
+        const char* perm = argc > 4 ? argv[4] : NULL;
+        if (perm && strcmp(perm, "CNS") && strcmp(perm, "CI")) {
+            return paramError(cli, "Invalid permission");
+        }
+        // netIdToInterfaces[netId].push_back(iface);
+        // bool is_cns = perm && !strcmp(perm, "CNS");
+        // bool is_ci = perm && !strcmp(perm, "CI");
+        // if (perm) netIdToPermission[netId] = perm;
+        // int table = ...;  // compute routing table number for iface
+        // int fwmark = getFwmark(netId, false, false, is_cns, is_ci);
+        // int mask = getFwmarkMask(true, false, false, is_cns, is_ci);
+        // int exp_fwmark = getFwmark(netId, true, false, is_cns, is_ci);
+        // int exp_mask = getFwmarkMask(true, true, false, is_cns, is_ci);
+        // ip rule add fwmark <exp_fwmark>/<exp_mask> table <table>
+        // ip rule add oif <iface> table <table>
+        // ip rule add fwmark <fwmark>/<mask> table <table>
+        return 0;
+    }
+    //    0       1       2
+    // network destroy <netId>
+    if (!strcmp(argv[1], "destroy")) {
+        if (argc < 3) {
+            return syntaxError(cli, "Missing argument");
+        }
+        unsigned int netId = strtoul(argv[2], NULL, 0);
+        if (!isNetIdValid(netId)) {
+            return paramError(cli, "Invalid NetId");
+        }
+        // const char* perm = netIdToPermission[netId].c_str();
+        // bool is_cns = !strcmp(perm, "CNS");
+        // bool is_ci = !strcmp(perm, "CI");
+        // int fwmark = getFwmark(netId, false, false, is_cns, is_ci);
+        // int mask = getFwmarkMask(true, false, false, is_cns, is_ci);
+        // int exp_fwmark = getFwmark(netId, true, false, is_cns, is_ci);
+        // int exp_mask = getFwmarkMask(true, true, false, is_cns, is_ci);
+        // foreach iface in netIdToInterfaces[netId]:
+        //     int table = ...;  // compute routing table number for iface
+        //     ip rule del fwmark <exp_fwmark>/<exp_mask> table <table>
+        //     ip rule del oif <iface> table <table>
+        //     ip rule del fwmark <fwmark>/<mask> table <table>
+        //     ioctl(SIOCKILLADDR, ...);
+        // netIdToInterfaces.erase(netId);
+        // netIdToPermission.erase(netId);
+        return 0;
+    }
+    // network dns <add|remove> <netId> <num-resolvers> <resolver1> .. <resolverN> [searchDomain1] .. [searchDomainM]
+    // network route <add|remove> <other-route-params>
+    // network legacy <uid> route <add|remove> <other-route-params>
+    // network default set <netId> [kill-old-default's-sockets]
+    //     -- "kill-old-default's-sockets" is a bool
+    // network default clear
+    //     -- when no interfaces are active (e.g.: airplane mode)
+    // network permission add [CI] [CNS] <uid1> .. <uidN>
+    // network permission clear <uid1> .. <uidN>
+    // network vpn create <netId> [owner_uid]
+    // network vpn destroy <netId>
+    // network <bind|unbind> <netId> <uid1> .. <uidN>
+    //     -- uid range can be specified as "uidX-uidY"
+    // TODO:
+    //   o tethering
+    //   o p2p
+    return syntaxError(cli, "Unknown argument");
+}
index d737270..da00e7c 100644 (file)
@@ -144,6 +144,16 @@ private:
         virtual ~ClatdCmd() {}
         int runCommand(SocketClient *c, int argc, char ** argv);
     };
+
+    class NetworkCmd : public NetdCommand {
+    public:
+        NetworkCmd();
+        virtual ~NetworkCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv);
+    private:
+        int syntaxError(SocketClient* cli, const char* message);
+        int paramError(SocketClient* cli, const char* message);
+    };
 };
 
 #endif
diff --git a/Fwmark.h b/Fwmark.h
new file mode 100644 (file)
index 0000000..a736bb6
--- /dev/null
+++ b/Fwmark.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _FWMARK_H
+#define _FWMARK_H
+
+const unsigned int FWMARK_NETID = 0xffff;
+const unsigned int FWMARK_EXPLICIT = 0x10000;
+const unsigned int FWMARK_PROTECT = 0x20000;
+const unsigned int FWMARK_CNS = 0x40000;  // CHANGE_NETWORK_STATE
+const unsigned int FWMARK_CI = 0x80000;  // CONNECTIVITY_INTERNAL
+
+unsigned int getFwmark(unsigned int netId, bool exp, bool protect, bool cns,
+                       bool ci) {
+    unsigned int fwmark = netId & FWMARK_NETID;
+    if (exp) fwmark |= FWMARK_EXPLICIT;
+    if (protect) fwmark |= FWMARK_PROTECT;
+    if (cns) fwmark |= FWMARK_CNS;
+    if (ci) fwmark |= FWMARK_CI;
+    return fwmark;
+}
+
+unsigned int getFwmarkMask(bool netId, bool exp, bool protect, bool cns, bool ci) {
+    return getFwmark(netId ? FWMARK_NETID : 0, exp, protect, cns, ci);
+}
+#endif
diff --git a/NetId.cpp b/NetId.cpp
new file mode 100644 (file)
index 0000000..a07cc9f
--- /dev/null
+++ b/NetId.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "NetId.h"
+
+bool isNetIdValid(unsigned int netId) {
+    return MIN_NET_ID <= netId && netId <= MAX_NET_ID;
+}
diff --git a/NetId.h b/NetId.h
new file mode 100644 (file)
index 0000000..207d29e
--- /dev/null
+++ b/NetId.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _NET_ID_H
+#define _NET_ID_H
+
+// Keep these in sync with ConnectivityService.java.
+const unsigned int MIN_NET_ID = 10;
+const unsigned int MAX_NET_ID = 65535;
+
+bool isNetIdValid(unsigned int netId);
+
+#endif