11cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai/*
21cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * Copyright (C) 2016 The Android Open Source Project
31cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai *
41cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * Licensed under the Apache License, Version 2.0 (the "License");
51cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * you may not use this file except in compliance with the License.
61cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * You may obtain a copy of the License at
71cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai *
81cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai *      http://www.apache.org/licenses/LICENSE-2.0
91cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai *
101cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * Unless required by applicable law or agreed to in writing, software
111cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * distributed under the License is distributed on an "AS IS" BASIS,
121cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * See the License for the specific language governing permissions and
141cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai * limitations under the License.
151cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai */
161cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai
1793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti#include <regex>
1893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti#include <set>
1993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti#include <string>
2093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
2193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti#include <android-base/strings.h>
2205306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti#include <android-base/stringprintf.h>
2305306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti
2419ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti#define LOG_TAG "Netd"
2519ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti#include <cutils/log.h>
2619ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti
271cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai#include "Controllers.h"
281ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "IdletimerController.h"
291ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "NetworkController.h"
301ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "RouteController.h"
3119ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti#include "Stopwatch.h"
321ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "oem_iptables_hook.h"
331cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai
341cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imainamespace android {
351cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imainamespace net {
361cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai
3793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittiusing android::base::Join;
3893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittiusing android::base::StringPrintf;
3993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittiusing android::base::StringAppendF;
4093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
4109d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colittiauto Controllers::execIptablesRestore  = ::execIptablesRestore;
4293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittiauto Controllers::execIptablesRestoreWithOutput = ::execIptablesRestoreWithOutput;
4309d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti
441ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittinamespace {
4593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
461ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti/**
471ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * List of module chains to be created, along with explicit ordering. ORDERING
481ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE.
491ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti */
5093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> FILTER_INPUT = {
511ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        // Bandwidth should always be early in input chain, to make sure we
521ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        // correctly count incoming traffic against data plan.
531ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        BandwidthController::LOCAL_INPUT,
541ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        FirewallController::LOCAL_INPUT,
551ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
561ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
5793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> FILTER_FORWARD = {
581ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        OEM_IPTABLES_FILTER_FORWARD,
591ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        FirewallController::LOCAL_FORWARD,
601ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        BandwidthController::LOCAL_FORWARD,
611ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        NatController::LOCAL_FORWARD,
621ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
631ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
6493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> FILTER_OUTPUT = {
651ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        OEM_IPTABLES_FILTER_OUTPUT,
661ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        FirewallController::LOCAL_OUTPUT,
671ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        StrictController::LOCAL_OUTPUT,
681ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        BandwidthController::LOCAL_OUTPUT,
691ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
701ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
7193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> RAW_PREROUTING = {
721ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        BandwidthController::LOCAL_RAW_PREROUTING,
731ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        IdletimerController::LOCAL_RAW_PREROUTING,
741ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        NatController::LOCAL_RAW_PREROUTING,
751ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
761ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
7793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> MANGLE_POSTROUTING = {
7805306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti        OEM_IPTABLES_MANGLE_POSTROUTING,
791ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        BandwidthController::LOCAL_MANGLE_POSTROUTING,
801ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        IdletimerController::LOCAL_MANGLE_POSTROUTING,
811ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
821ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
8393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> MANGLE_INPUT = {
8408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz        WakeupController::LOCAL_MANGLE_INPUT,
85d78843eb11fdde1611598fd27d347912070c0555Lorenzo Colitti        RouteController::LOCAL_MANGLE_INPUT,
86d78843eb11fdde1611598fd27d347912070c0555Lorenzo Colitti};
87d78843eb11fdde1611598fd27d347912070c0555Lorenzo Colitti
8893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> MANGLE_FORWARD = {
891ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        NatController::LOCAL_MANGLE_FORWARD,
901ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
911ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
9293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> NAT_PREROUTING = {
931ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        OEM_IPTABLES_NAT_PREROUTING,
941ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
951ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
9693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::vector<const char*> NAT_POSTROUTING = {
971ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        NatController::LOCAL_NAT_POSTROUTING,
981ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti};
991ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
10093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti// Commands to create child chains and to match created chains in iptables -S output. Keep in sync.
10193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const char* CHILD_CHAIN_TEMPLATE = "-A %s -j %s\n";
10293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistatic const std::regex CHILD_CHAIN_REGEX("^-A ([^ ]+) -j ([^ ]+)$",
10393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti                                          std::regex_constants::extended);
10493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
10509d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti}  // namespace
10609d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti
10709d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti/* static */
10893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colittistd::set<std::string> Controllers::findExistingChildChains(const IptablesTarget target,
10993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti                                                           const char* table,
11093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti                                                           const char* parentChain) {
11193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    if (target == V4V6) {
11293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        ALOGE("findExistingChildChains only supports one protocol at a time");
11393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        abort();
11493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    }
11593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
11693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::set<std::string> existing;
11793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
11893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // List the current contents of parentChain.
11993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //
12093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // TODO: there is no guarantee that nothing else modifies the chain in the few milliseconds
12193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // between when we list the existing rules and when we delete them. However:
12293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // - Since this code is only run on startup, nothing else in netd will be running.
12393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // - While vendor code is known to add its own rules to chains created by netd, it should never
12493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   be modifying the rules in childChains or the rules that hook said chains into their parent
12593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   chains.
12693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::string command = StringPrintf("*%s\n-S %s\nCOMMIT\n", table, parentChain);
12793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::string output;
12893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    if (Controllers::execIptablesRestoreWithOutput(target, command, &output) == -1) {
12993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        ALOGE("Error listing chain %s in table %s\n", parentChain, table);
13093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        return existing;
13193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    }
13293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
13393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // The only rules added by createChildChains are of the simple form "-A <parent> -j <child>".
13493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // Find those rules and add each one's child chain to existing.
13593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::smatch matches;
13693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::stringstream stream(output);
13793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::string rule;
13893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    while (std::getline(stream, rule, '\n')) {
13993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        if (std::regex_search(rule, matches, CHILD_CHAIN_REGEX) && matches[1] == parentChain) {
14093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti            existing.insert(matches[2]);
14193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        }
14293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    }
14393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
14493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    return existing;
14593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti}
14693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
14793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti/* static */
14809d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colittivoid Controllers::createChildChains(IptablesTarget target, const char* table,
14909d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti                                    const char* parentChain,
15093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti                                    const std::vector<const char*>& childChains,
15109d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti                                    bool exclusive) {
15293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::string command = StringPrintf("*%s\n", table);
15393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti
15493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // We cannot just clear all the chains we create because vendor code modifies filter OUTPUT and
15593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // mangle POSTROUTING directly. So:
15693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //
15793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // - If we're the exclusive owner of this chain, simply clear it entirely.
15893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    // - If not, then list the chain's current contents to ensure that if we restart after a crash,
15993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   we leave the existing rules alone in the positions they currently occupy. This is faster
16093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   than blindly deleting our rules and recreating them, because deleting a rule that doesn't
16193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   exists causes iptables-restore to quit, which takes ~30ms per delete. It's also more
16293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   correct, because if we delete rules and re-add them, they'll be in the wrong position with
16393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //   regards to the vendor rules.
16493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    //
165cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    // TODO: Make all chains exclusive once vendor code uses the oem_* rules.
16693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    std::set<std::string> existingChildChains;
167cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    if (exclusive) {
168cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti        // Just running ":chain -" flushes user-defined chains, but not built-in chains like INPUT.
169cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti        // Since at this point we don't know if parentChain is a built-in chain, do both.
17093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        StringAppendF(&command, ":%s -\n", parentChain);
17193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        StringAppendF(&command, "-F %s\n", parentChain);
17293f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    } else {
17393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        existingChildChains = findExistingChildChains(target, table, parentChain);
174cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    }
1751ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
17693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    for (const auto& childChain : childChains) {
17793f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        // Always clear the child chain.
17893f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        StringAppendF(&command, ":%s -\n", childChain);
17993f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        // But only add it to the parent chain if it's not already there.
18093f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti        if (existingChildChains.find(childChain) == existingChildChains.end()) {
18193f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti            StringAppendF(&command, CHILD_CHAIN_TEMPLATE, parentChain, childChain);
182cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti        }
18393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    }
18409d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti    command += "COMMIT\n";
18505306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti    execIptablesRestore(target, command);
18605306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti}
18705306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti
18808b84cd0d223ae3059ce7d4d55b389fdea187580Joel ScherpelzControllers::Controllers()
18908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz    : clatdCtrl(&netCtrl),
19008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz      wakeupCtrl(
19108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz          [this](const std::string& prefix, uid_t uid, gid_t gid, uint64_t timestampNs) {
19208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz              const auto listener = eventReporter.getNetdEventListener();
19308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz              if (listener == nullptr) {
19408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz                  ALOGE("getNetdEventListener() returned nullptr. dropping wakeup event");
19508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz                  return;
19608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz              }
19708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz              listener->onWakeupEvent(String16(prefix.c_str()), uid, gid, timestampNs);
19808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz          },
19908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz          &iptablesRestoreCtrl) {
2002c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline    InterfaceController::initializeAll();
2012c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline}
2021cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai
20309d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colittivoid Controllers::initChildChains() {
2041ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    /*
2051ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * This is the only time we touch top-level chains in iptables; controllers
2061ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * should only mutate rules inside of their children chains, as created by
2071ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * the constants above.
2081ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     *
2091ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * Modules should never ACCEPT packets (except in well-justified cases);
2101ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * they should instead defer to any remaining modules using RETURN, or
2111ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * otherwise DROP/REJECT.
2121ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     */
2131ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
21405306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti    // Create chains for child modules.
215cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT, true);
216cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD, true);
217cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING, true);
218cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    createChildChains(V4V6, "mangle", "FORWARD", MANGLE_FORWARD, true);
219d78843eb11fdde1611598fd27d347912070c0555Lorenzo Colitti    createChildChains(V4V6, "mangle", "INPUT", MANGLE_INPUT, true);
220cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING, true);
221cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti    createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING, true);
22209d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti
22393f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    createChildChains(V4, "filter", "OUTPUT", FILTER_OUTPUT, false);
22493f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    createChildChains(V6, "filter", "OUTPUT", FILTER_OUTPUT, false);
22593f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    createChildChains(V4, "mangle", "POSTROUTING", MANGLE_POSTROUTING, false);
22693f4999ab3c593d2821bc34df489597adbf57e89Lorenzo Colitti    createChildChains(V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING, false);
22709d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti}
22809d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti
22909d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colittivoid Controllers::initIptablesRules() {
23009d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti    Stopwatch s;
23109d8c762645a18f359ab80558a8aad9003d86461Lorenzo Colitti    initChildChains();
23219ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Creating child chains: %.1fms", s.getTimeAndReset());
2331ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
2341ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    // Let each module setup their child chains
2351ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    setupOemIptablesHook();
23619ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Setting up OEM hooks: %.1fms", s.getTimeAndReset());
2371ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
2381ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    /* When enabled, DROPs all packets except those matching rules. */
2391ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    firewallCtrl.setupIptablesHooks();
24019ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Setting up FirewallController hooks: %.1fms", s.getTimeAndReset());
2411ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
2421ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    /* Does DROPs in FORWARD by default */
2431ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    natCtrl.setupIptablesHooks();
24419ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Setting up NatController hooks: %.1fms", s.getTimeAndReset());
24519ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti
2461ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    /*
2471ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * Does REJECT in INPUT, OUTPUT. Does counting also.
2481ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * No DROP/REJECT allowed later in netfilter-flow hook order.
2491ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     */
2501ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    bandwidthCtrl.setupIptablesHooks();
25119ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Setting up BandwidthController hooks: %.1fms", s.getTimeAndReset());
25219ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti
2531ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    /*
2541ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * Counts in nat: PREROUTING, POSTROUTING.
2551ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     * No DROP/REJECT allowed later in netfilter-flow hook order.
2561ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti     */
2571ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    idletimerCtrl.setupIptablesHooks();
25819ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Setting up IdletimerController hooks: %.1fms", s.getTimeAndReset());
2591ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}
2601ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
2611ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittivoid Controllers::init() {
2621ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    initIptablesRules();
26319ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti
26419ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    Stopwatch s;
2651ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    bandwidthCtrl.enableBandwidthControl(false);
26619ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Disabling bandwidth control: %.1fms", s.getTimeAndReset());
2671ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
2681ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) {
2691ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti        ALOGE("failed to initialize RouteController (%s)", strerror(-ret));
2701ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti    }
27119ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti    ALOGI("Initializing RouteController: %.1fms", s.getTimeAndReset());
2721ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}
2731ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti
2741cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre ImaiControllers* gCtls = nullptr;
2751cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai
2761cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai}  // namespace net
2771cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai}  // namespace android
278