Move some code out of CommandListener.

1. Move lots of initialization code to Controllers.cpp.
2. Move stringToPermission to Permission.h, which seems like a
   better place for it.

Bug: 34873832
Test: builds, boots
Change-Id: I01ba8e1d062d298eab71a1b90899df042fdc2360
diff --git a/include/Permission.h b/include/Permission.h
index 19881df..32f3188 100644
--- a/include/Permission.h
+++ b/include/Permission.h
@@ -49,4 +49,14 @@
     }
 }
 
+inline Permission stringToPermission(const char* arg) {
+    if (!strcmp(arg, "NETWORK")) {
+        return PERMISSION_NETWORK;
+    }
+    if (!strcmp(arg, "SYSTEM")) {
+        return PERMISSION_SYSTEM;
+    }
+    return PERMISSION_NONE;
+}
+
 #endif  // NETD_INCLUDE_PERMISSION_H
diff --git a/server/Android.mk b/server/Android.mk
index dd0ffa7..258c9a6 100644
--- a/server/Android.mk
+++ b/server/Android.mk
@@ -149,6 +149,7 @@
         IptablesRestoreController.cpp IptablesRestoreControllerTest.cpp \
         BandwidthController.cpp BandwidthControllerTest.cpp \
         FirewallControllerTest.cpp FirewallController.cpp \
+        IdletimerController.cpp \
         NatControllerTest.cpp NatController.cpp \
         SockDiagTest.cpp SockDiag.cpp \
         StrictController.cpp StrictControllerTest.cpp \
diff --git a/server/CommandListener.cpp b/server/CommandListener.cpp
index e0f065e..df4ea41 100644
--- a/server/CommandListener.cpp
+++ b/server/CommandListener.cpp
@@ -43,7 +43,6 @@
 #include "BandwidthController.h"
 #include "IdletimerController.h"
 #include "InterfaceController.h"
-#include "oem_iptables_hook.h"
 #include "NetdConstants.h"
 #include "FirewallController.h"
 #include "RouteController.h"
@@ -58,16 +57,6 @@
 
 const unsigned NUM_OEM_IDS = NetworkController::MAX_OEM_ID - NetworkController::MIN_OEM_ID + 1;
 
-Permission stringToPermission(const char* arg) {
-    if (!strcmp(arg, "NETWORK")) {
-        return PERMISSION_NETWORK;
-    }
-    if (!strcmp(arg, "SYSTEM")) {
-        return PERMISSION_SYSTEM;
-    }
-    return PERMISSION_NONE;
-}
-
 unsigned stringToNetId(const char* arg) {
     if (!strcmp(arg, "local")) {
         return NetworkController::LOCAL_NET_ID;
@@ -104,82 +93,6 @@
 
 }  // namespace
 
-/**
- * List of module chains to be created, along with explicit ordering. ORDERING
- * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE.
- */
-static const char* FILTER_INPUT[] = {
-        // Bandwidth should always be early in input chain, to make sure we
-        // correctly count incoming traffic against data plan.
-        BandwidthController::LOCAL_INPUT,
-        FirewallController::LOCAL_INPUT,
-        NULL,
-};
-
-static const char* FILTER_FORWARD[] = {
-        OEM_IPTABLES_FILTER_FORWARD,
-        FirewallController::LOCAL_FORWARD,
-        BandwidthController::LOCAL_FORWARD,
-        NatController::LOCAL_FORWARD,
-        NULL,
-};
-
-static const char* FILTER_OUTPUT[] = {
-        OEM_IPTABLES_FILTER_OUTPUT,
-        FirewallController::LOCAL_OUTPUT,
-        StrictController::LOCAL_OUTPUT,
-        BandwidthController::LOCAL_OUTPUT,
-        NULL,
-};
-
-static const char* RAW_PREROUTING[] = {
-        BandwidthController::LOCAL_RAW_PREROUTING,
-        IdletimerController::LOCAL_RAW_PREROUTING,
-        NatController::LOCAL_RAW_PREROUTING,
-        NULL,
-};
-
-static const char* MANGLE_POSTROUTING[] = {
-        BandwidthController::LOCAL_MANGLE_POSTROUTING,
-        IdletimerController::LOCAL_MANGLE_POSTROUTING,
-        NULL,
-};
-
-static const char* MANGLE_FORWARD[] = {
-        NatController::LOCAL_MANGLE_FORWARD,
-        NULL,
-};
-
-static const char* NAT_PREROUTING[] = {
-        OEM_IPTABLES_NAT_PREROUTING,
-        NULL,
-};
-
-static const char* NAT_POSTROUTING[] = {
-        NatController::LOCAL_NAT_POSTROUTING,
-        NULL,
-};
-
-static void createChildChains(IptablesTarget target, const char* table, const char* parentChain,
-        const char** childChains) {
-    const char** childChain = childChains;
-    do {
-        // Order is important:
-        // -D to delete any pre-existing jump rule (removes references
-        //    that would prevent -X from working)
-        // -F to flush any existing chain
-        // -X to delete any existing chain
-        // -N to create the chain
-        // -A to append the chain to parent
-
-        execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL);
-        execIptablesSilently(target, "-t", table, "-F", *childChain, NULL);
-        execIptablesSilently(target, "-t", table, "-X", *childChain, NULL);
-        execIptables(target, "-t", table, "-N", *childChain, NULL);
-        execIptables(target, "-t", table, "-A", parentChain, "-j", *childChain, NULL);
-    } while (*(++childChain) != NULL);
-}
-
 void CommandListener::registerLockingCmd(FrameworkCommand *cmd, android::RWLock& lock) {
     registerCmd(new LockingFrameworkCommand(cmd, lock));
 }
@@ -199,51 +112,6 @@
     registerLockingCmd(new ClatdCmd());
     registerLockingCmd(new NetworkCommand());
     registerLockingCmd(new StrictCmd());
-
-    /*
-     * This is the only time we touch top-level chains in iptables; controllers
-     * should only mutate rules inside of their children chains, as created by
-     * the constants above.
-     *
-     * Modules should never ACCEPT packets (except in well-justified cases);
-     * they should instead defer to any remaining modules using RETURN, or
-     * otherwise DROP/REJECT.
-     */
-
-    // Create chains for children modules
-    createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT);
-    createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
-    createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT);
-    createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING);
-    createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING);
-    createChildChains(V4V6, "mangle", "FORWARD", MANGLE_FORWARD);
-    createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING);
-    createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING);
-
-    // Let each module setup their child chains
-    setupOemIptablesHook();
-
-    /* When enabled, DROPs all packets except those matching rules. */
-    gCtls->firewallCtrl.setupIptablesHooks();
-
-    /* Does DROPs in FORWARD by default */
-    gCtls->natCtrl.setupIptablesHooks();
-    /*
-     * Does REJECT in INPUT, OUTPUT. Does counting also.
-     * No DROP/REJECT allowed later in netfilter-flow hook order.
-     */
-    gCtls->bandwidthCtrl.setupIptablesHooks();
-    /*
-     * Counts in nat: PREROUTING, POSTROUTING.
-     * No DROP/REJECT allowed later in netfilter-flow hook order.
-     */
-    gCtls->idletimerCtrl.setupIptablesHooks();
-
-    gCtls->bandwidthCtrl.enableBandwidthControl(false);
-
-    if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) {
-        ALOGE("failed to initialize RouteController (%s)", strerror(-ret));
-    }
 }
 
 CommandListener::InterfaceCmd::InterfaceCmd() :
diff --git a/server/Controllers.cpp b/server/Controllers.cpp
index f2f3e13..cdc5dad 100644
--- a/server/Controllers.cpp
+++ b/server/Controllers.cpp
@@ -15,15 +15,148 @@
  */
 
 #include "Controllers.h"
+#include "IdletimerController.h"
+#include "NetworkController.h"
+#include "RouteController.h"
+#include "oem_iptables_hook.h"
 
 namespace android {
 namespace net {
 
+namespace {
+/**
+ * List of module chains to be created, along with explicit ordering. ORDERING
+ * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE.
+ */
+static const char* FILTER_INPUT[] = {
+        // Bandwidth should always be early in input chain, to make sure we
+        // correctly count incoming traffic against data plan.
+        BandwidthController::LOCAL_INPUT,
+        FirewallController::LOCAL_INPUT,
+        NULL,
+};
+
+static const char* FILTER_FORWARD[] = {
+        OEM_IPTABLES_FILTER_FORWARD,
+        FirewallController::LOCAL_FORWARD,
+        BandwidthController::LOCAL_FORWARD,
+        NatController::LOCAL_FORWARD,
+        NULL,
+};
+
+static const char* FILTER_OUTPUT[] = {
+        OEM_IPTABLES_FILTER_OUTPUT,
+        FirewallController::LOCAL_OUTPUT,
+        StrictController::LOCAL_OUTPUT,
+        BandwidthController::LOCAL_OUTPUT,
+        NULL,
+};
+
+static const char* RAW_PREROUTING[] = {
+        BandwidthController::LOCAL_RAW_PREROUTING,
+        IdletimerController::LOCAL_RAW_PREROUTING,
+        NatController::LOCAL_RAW_PREROUTING,
+        NULL,
+};
+
+static const char* MANGLE_POSTROUTING[] = {
+        BandwidthController::LOCAL_MANGLE_POSTROUTING,
+        IdletimerController::LOCAL_MANGLE_POSTROUTING,
+        NULL,
+};
+
+static const char* MANGLE_FORWARD[] = {
+        NatController::LOCAL_MANGLE_FORWARD,
+        NULL,
+};
+
+static const char* NAT_PREROUTING[] = {
+        OEM_IPTABLES_NAT_PREROUTING,
+        NULL,
+};
+
+static const char* NAT_POSTROUTING[] = {
+        NatController::LOCAL_NAT_POSTROUTING,
+        NULL,
+};
+
+static void createChildChains(IptablesTarget target, const char* table, const char* parentChain,
+        const char** childChains) {
+    const char** childChain = childChains;
+    do {
+        // Order is important:
+        // -D to delete any pre-existing jump rule (removes references
+        //    that would prevent -X from working)
+        // -F to flush any existing chain
+        // -X to delete any existing chain
+        // -N to create the chain
+        // -A to append the chain to parent
+
+        execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL);
+        execIptablesSilently(target, "-t", table, "-F", *childChain, NULL);
+        execIptablesSilently(target, "-t", table, "-X", *childChain, NULL);
+        execIptables(target, "-t", table, "-N", *childChain, NULL);
+        execIptables(target, "-t", table, "-A", parentChain, "-j", *childChain, NULL);
+    } while (*(++childChain) != NULL);
+}
+
+}  // namespace
+
 Controllers::Controllers() : clatdCtrl(&netCtrl) {
     InterfaceController::initializeAll();
     IptablesRestoreController::installSignalHandler(&iptablesRestoreCtrl);
 }
 
+void Controllers::initIptablesRules() {
+    /*
+     * This is the only time we touch top-level chains in iptables; controllers
+     * should only mutate rules inside of their children chains, as created by
+     * the constants above.
+     *
+     * Modules should never ACCEPT packets (except in well-justified cases);
+     * they should instead defer to any remaining modules using RETURN, or
+     * otherwise DROP/REJECT.
+     */
+
+    // Create chains for children modules
+    createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT);
+    createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
+    createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT);
+    createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING);
+    createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING);
+    createChildChains(V4V6, "mangle", "FORWARD", MANGLE_FORWARD);
+    createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING);
+    createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING);
+
+    // Let each module setup their child chains
+    setupOemIptablesHook();
+
+    /* When enabled, DROPs all packets except those matching rules. */
+    firewallCtrl.setupIptablesHooks();
+
+    /* Does DROPs in FORWARD by default */
+    natCtrl.setupIptablesHooks();
+    /*
+     * Does REJECT in INPUT, OUTPUT. Does counting also.
+     * No DROP/REJECT allowed later in netfilter-flow hook order.
+     */
+    bandwidthCtrl.setupIptablesHooks();
+    /*
+     * Counts in nat: PREROUTING, POSTROUTING.
+     * No DROP/REJECT allowed later in netfilter-flow hook order.
+     */
+    idletimerCtrl.setupIptablesHooks();
+}
+
+void Controllers::init() {
+    initIptablesRules();
+    bandwidthCtrl.enableBandwidthControl(false);
+
+    if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) {
+        ALOGE("failed to initialize RouteController (%s)", strerror(-ret));
+    }
+}
+
 Controllers* gCtls = nullptr;
 
 }  // namespace net
diff --git a/server/Controllers.h b/server/Controllers.h
index dd8f028..ac17fc1 100644
--- a/server/Controllers.h
+++ b/server/Controllers.h
@@ -36,7 +36,8 @@
 namespace android {
 namespace net {
 
-struct Controllers {
+class Controllers {
+public:
     Controllers();
 
     NetworkController netCtrl;
@@ -51,6 +52,11 @@
     StrictController strictCtrl;
     EventReporter eventReporter;
     IptablesRestoreController iptablesRestoreCtrl;
+
+    void init();
+
+private:
+    void initIptablesRules();
 };
 
 extern Controllers* gCtls;
diff --git a/server/main.cpp b/server/main.cpp
index aab15d6..7b15a76 100644
--- a/server/main.cpp
+++ b/server/main.cpp
@@ -79,6 +79,8 @@
     };
 
     gCtls = new android::net::Controllers();
+    gCtls->init();
+
     CommandListener cl;
     nm->setBroadcaster((SocketListener *) &cl);