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 1705306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti#include <android-base/stringprintf.h> 1805306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti 1919ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti#define LOG_TAG "Netd" 2019ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti#include <cutils/log.h> 2119ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti 221cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai#include "Controllers.h" 231ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "IdletimerController.h" 241ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "NetworkController.h" 251ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "RouteController.h" 2619ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti#include "Stopwatch.h" 271ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti#include "oem_iptables_hook.h" 281cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai 291cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imainamespace android { 301cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imainamespace net { 311cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai 321ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittinamespace { 331ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti/** 341ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * List of module chains to be created, along with explicit ordering. ORDERING 351ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE. 361ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti */ 371ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* FILTER_INPUT[] = { 381ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti // Bandwidth should always be early in input chain, to make sure we 391ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti // correctly count incoming traffic against data plan. 401ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti BandwidthController::LOCAL_INPUT, 411ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti FirewallController::LOCAL_INPUT, 421ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 431ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 441ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 451ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* FILTER_FORWARD[] = { 461ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti OEM_IPTABLES_FILTER_FORWARD, 471ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti FirewallController::LOCAL_FORWARD, 481ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti BandwidthController::LOCAL_FORWARD, 491ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NatController::LOCAL_FORWARD, 501ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 511ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 521ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 531ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* FILTER_OUTPUT[] = { 541ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti OEM_IPTABLES_FILTER_OUTPUT, 551ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti FirewallController::LOCAL_OUTPUT, 561ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti StrictController::LOCAL_OUTPUT, 571ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti BandwidthController::LOCAL_OUTPUT, 581ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 591ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 601ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 611ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* RAW_PREROUTING[] = { 621ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti BandwidthController::LOCAL_RAW_PREROUTING, 631ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti IdletimerController::LOCAL_RAW_PREROUTING, 641ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NatController::LOCAL_RAW_PREROUTING, 651ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 661ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 671ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 681ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* MANGLE_POSTROUTING[] = { 6905306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti OEM_IPTABLES_MANGLE_POSTROUTING, 701ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti BandwidthController::LOCAL_MANGLE_POSTROUTING, 711ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti IdletimerController::LOCAL_MANGLE_POSTROUTING, 721ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 731ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 741ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 751ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* MANGLE_FORWARD[] = { 761ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NatController::LOCAL_MANGLE_FORWARD, 771ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 781ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 791ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 801ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* NAT_PREROUTING[] = { 811ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti OEM_IPTABLES_NAT_PREROUTING, 821ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 831ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 841ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 851ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic const char* NAT_POSTROUTING[] = { 861ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NatController::LOCAL_NAT_POSTROUTING, 871ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti NULL, 881ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti}; 891ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 901ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittistatic void createChildChains(IptablesTarget target, const char* table, const char* parentChain, 91cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti const char** childChains, bool exclusive) { 92cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti std::string command = android::base::StringPrintf("*%s\n", table); 93cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti 94cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti // If we're the exclusive owner of this chain, clear it entirely. This saves us from having to 95cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti // run one execIptablesSilently command to delete each child chain. We can't use -D in 96cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti // iptables-restore because it's a fatal error if the rule doesn't exist. 97cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti // TODO: Make all chains exclusive once vendor code uses the oem_* rules. 98cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti if (exclusive) { 99cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti // Just running ":chain -" flushes user-defined chains, but not built-in chains like INPUT. 100cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti // Since at this point we don't know if parentChain is a built-in chain, do both. 101cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti command += android::base::StringPrintf(":%s -\n", parentChain); 102cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti command += android::base::StringPrintf("-F %s\n", parentChain); 103cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti } 1041ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 10505306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti const char** childChain = childChains; 10605306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti do { 107cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti if (!exclusive) { 108cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL); 109cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti } 11005306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti command += android::base::StringPrintf(":%s -\n", *childChain); 11105306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti command += android::base::StringPrintf("-A %s -j %s\n", parentChain, *childChain); 11205306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti } while (*(++childChain) != NULL); 11305306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti command += "COMMIT\n\n"; 11405306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti execIptablesRestore(target, command); 11505306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti} 11605306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti 1171ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti} // namespace 1181ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1192c5aaa1876db659556c2e9605beccc670e6b7c0dErik KlineControllers::Controllers() : clatdCtrl(&netCtrl) { 1202c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline InterfaceController::initializeAll(); 1212c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline} 1221cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai 1231ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittivoid Controllers::initIptablesRules() { 1241ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti /* 1251ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * This is the only time we touch top-level chains in iptables; controllers 1261ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * should only mutate rules inside of their children chains, as created by 1271ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * the constants above. 1281ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * 1291ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * Modules should never ACCEPT packets (except in well-justified cases); 1301ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * they should instead defer to any remaining modules using RETURN, or 1311ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * otherwise DROP/REJECT. 1321ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti */ 1331ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 13405306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti // Create chains for child modules. 13505306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti // We cannot use createChildChainsFast for all chains because vendor code modifies filter OUTPUT 13605306fb80d3b08775a6899384700ecaa8d644b62Lorenzo Colitti // and mangle POSTROUTING directly. 13719ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti Stopwatch s; 138cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT, true); 139cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD, true); 140cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT, false); 141cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING, true); 142cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING, false); 143cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4V6, "mangle", "FORWARD", MANGLE_FORWARD, true); 144cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING, true); 145cda022e61c37cc6e6bd863c5a6525108e3789ca8Lorenzo Colitti createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING, true); 14619ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Creating child chains: %.1fms", s.getTimeAndReset()); 1471ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1481ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti // Let each module setup their child chains 1491ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti setupOemIptablesHook(); 15019ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Setting up OEM hooks: %.1fms", s.getTimeAndReset()); 1511ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1521ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti /* When enabled, DROPs all packets except those matching rules. */ 1531ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti firewallCtrl.setupIptablesHooks(); 15419ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Setting up FirewallController hooks: %.1fms", s.getTimeAndReset()); 1551ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1561ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti /* Does DROPs in FORWARD by default */ 1571ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti natCtrl.setupIptablesHooks(); 15819ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Setting up NatController hooks: %.1fms", s.getTimeAndReset()); 15919ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti 1601ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti /* 1611ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * Does REJECT in INPUT, OUTPUT. Does counting also. 1621ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * No DROP/REJECT allowed later in netfilter-flow hook order. 1631ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti */ 1641ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti bandwidthCtrl.setupIptablesHooks(); 16519ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Setting up BandwidthController hooks: %.1fms", s.getTimeAndReset()); 16619ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti 1671ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti /* 1681ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * Counts in nat: PREROUTING, POSTROUTING. 1691ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti * No DROP/REJECT allowed later in netfilter-flow hook order. 1701ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti */ 1711ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti idletimerCtrl.setupIptablesHooks(); 17219ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Setting up IdletimerController hooks: %.1fms", s.getTimeAndReset()); 1731ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti} 1741ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1751ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colittivoid Controllers::init() { 1761ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti initIptablesRules(); 17719ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti 17819ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti Stopwatch s; 1791ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti bandwidthCtrl.enableBandwidthControl(false); 18019ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Disabling bandwidth control: %.1fms", s.getTimeAndReset()); 1811ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1821ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) { 1831ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti ALOGE("failed to initialize RouteController (%s)", strerror(-ret)); 1841ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti } 18519ee8a8dd675ecf788a5a527b843b59fbbe3255fLorenzo Colitti ALOGI("Initializing RouteController: %.1fms", s.getTimeAndReset()); 1861ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti} 1871ed96e2d3fa89ca4848750a6b3bbbcf677946d27Lorenzo Colitti 1881cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre ImaiControllers* gCtls = nullptr; 1891cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai 1901cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai} // namespace net 1911cfa54374f5ba63d69d6fcca767c4f6647cb6de2Pierre Imai} // namespace android 192