Introduce Netd APIs for multinetworks.
Just stubs for now. Implementation will follow in subsequent CLs.
Change-Id: I10a2e4aca594c10a26d58afb4c250141386d3f0f
(cherry picked from commit 0d5146bed37b4e5b6909617e5f958a66bfee1e48)
diff --git a/Android.mk b/Android.mk
index 0c6210c..4e7df6b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,7 @@
NatController.cpp \
NetdCommand.cpp \
NetdConstants.cpp \
+ NetId.cpp \
NetlinkHandler.cpp \
NetlinkManager.cpp \
NetworkController.cpp \
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 6ec2afc..fb7c371 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -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 @@
registerCmd(new ResolverCmd());
registerCmd(new FirewallCmd());
registerCmd(new ClatdCmd());
+ registerCmd(new NetworkCmd());
if (!sNetCtrl)
sNetCtrl = new NetworkController();
@@ -1587,3 +1589,95 @@
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");
+}
diff --git a/CommandListener.h b/CommandListener.h
index d737270..da00e7c 100644
--- a/CommandListener.h
+++ b/CommandListener.h
@@ -144,6 +144,16 @@
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
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
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
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