Move createChildChains to iptables-restore.
This reduces netd startup time by about 2x.
Before:
02-02 14:01:20.075 485 485 I Netd : Creating child chains: 2983.5ms
02-02 14:01:20.398 485 485 I Netd : Netd started in 3325ms
After:
02-02 15:23:51.872 480 480 I Netd : Creating child chains: 1572.3ms
02-02 15:23:52.200 480 480 I Netd : Netd started in 1943ms
We cannot switch all chains to iptables-restore because vendor
code manipulates those chains directly. If we did, we would save
an additional ~1 second.
Add an oem_mangle_post chain linked from mangle POSTROUTING so
that said vendor code can modify that instead of POSTROUTING
directly. (There is already an oem_out chain, so no changes are
needed for vendor code to move off of OUTPUT.)
Bug: 34873832
Test: builds, boots, unit and integration tests pass
Test: iptables-save output before and after CL sees no unexpected rule changes
Change-Id: I64cc32e7e14d9966bf6bc9bcc604af8c5d19eae8
diff --git a/server/Controllers.cpp b/server/Controllers.cpp
index 85b6b1e..1a618c1 100644
--- a/server/Controllers.cpp
+++ b/server/Controllers.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
+
#define LOG_TAG "Netd"
#include <cutils/log.h>
@@ -64,6 +66,7 @@
};
static const char* MANGLE_POSTROUTING[] = {
+ OEM_IPTABLES_MANGLE_POSTROUTING,
BandwidthController::LOCAL_MANGLE_POSTROUTING,
IdletimerController::LOCAL_MANGLE_POSTROUTING,
NULL,
@@ -104,6 +107,24 @@
} while (*(++childChain) != NULL);
}
+// Fast version of createChildChains. This is only safe to use if the parent chain contains nothing
+// apart from the specified child chains.
+static void createChildChainsFast(IptablesTarget target, const char* table, const char* parentChain,
+ const char** childChains) {
+ const char** childChain = childChains;
+ std::string command = android::base::StringPrintf("*%s\n", table);
+ command += android::base::StringPrintf(":%s -\n", parentChain);
+ // Just running ":chain -" flushes user-defined chains, but not built-in chains like INPUT.
+ // Since at this point we don't know if parentChain is a built-in chain, do both.
+ command += android::base::StringPrintf("-F %s\n", parentChain);
+ do {
+ command += android::base::StringPrintf(":%s -\n", *childChain);
+ command += android::base::StringPrintf("-A %s -j %s\n", parentChain, *childChain);
+ } while (*(++childChain) != NULL);
+ command += "COMMIT\n\n";
+ execIptablesRestore(target, command);
+}
+
} // namespace
Controllers::Controllers() : clatdCtrl(&netCtrl) {
@@ -122,16 +143,18 @@
* otherwise DROP/REJECT.
*/
- // Create chains for children modules
+ // Create chains for child modules.
+ // We cannot use createChildChainsFast for all chains because vendor code modifies filter OUTPUT
+ // and mangle POSTROUTING directly.
Stopwatch s;
- createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT);
- createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
+ createChildChainsFast(V4V6, "filter", "INPUT", FILTER_INPUT);
+ createChildChainsFast(V4V6, "filter", "FORWARD", FILTER_FORWARD);
createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT);
- createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING);
+ createChildChainsFast(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);
+ createChildChainsFast(V4V6, "mangle", "FORWARD", MANGLE_FORWARD);
+ createChildChainsFast(V4, "nat", "PREROUTING", NAT_PREROUTING);
+ createChildChainsFast(V4, "nat", "POSTROUTING", NAT_POSTROUTING);
ALOGI("Creating child chains: %.1fms", s.getTimeAndReset());
// Let each module setup their child chains