19ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat/* 29ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Copyright (C) 2008 The Android Open Source Project 39ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 49ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 59ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * you may not use this file except in compliance with the License. 69ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * You may obtain a copy of the License at 79ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 89ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * http://www.apache.org/licenses/LICENSE-2.0 99ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 109ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Unless required by applicable law or agreed to in writing, software 119ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * distributed under the License is distributed on an "AS IS" BASIS, 129ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * See the License for the specific language governing permissions and 149ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * limitations under the License. 159ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat */ 169ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 17baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall#define LOG_NDEBUG 0 180031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <stdlib.h> 209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <errno.h> 219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/socket.h> 229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/stat.h> 23001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand#include <sys/wait.h> 249ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <fcntl.h> 259ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <netinet/in.h> 269ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <arpa/inet.h> 27ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h> 28ac208608c9e10ef199fdd11c38a31675ee9290c0John Michelau#include <cutils/properties.h> 299ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 309ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#define LOG_TAG "NatController" 319ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <cutils/log.h> 32001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand#include <logwrap/logwrap.h> 339ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 349ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include "NatController.h" 35c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt#include "NetdConstants.h" 3687475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran#include "RouteController.h" 379ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 388e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeyconst char* NatController::LOCAL_FORWARD = "natctrl_FORWARD"; 39e8164ddc8204b626c1144a0a504754bf6622c6fdLorenzo Colitticonst char* NatController::LOCAL_MANGLE_FORWARD = "natctrl_mangle_FORWARD"; 408e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeyconst char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING"; 41baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrallconst char* NatController::LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters"; 428e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 4387475a1471373b72ffc9f81f17dfd7884723fa86Sreeram RamachandranNatController::NatController() { 449ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 469ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::~NatController() { 479ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 489ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 494ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrallstruct CommandsAndArgs { 504ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall /* The array size doesn't really matter as the compiler will barf if too many initializers are specified. */ 514ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall const char *cmd[32]; 524ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall bool checkRes; 534ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall}; 544ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall 55001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchandint NatController::runCmd(int argc, const char **argv) { 5611b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall int res; 579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 58001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand res = android_fork_execvp(argc, (char **)argv, NULL, false, false); 59baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 60baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall#if !LOG_NDEBUG 61baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall std::string full_cmd = argv[0]; 62baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall argc--; argv++; 63baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* 64baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * HACK: Sometimes runCmd() is called with a ridcously large value (32) 65baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * and it works because the argv[] contains a NULL after the last 66baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * true argv. So here we use the NULL argv[] to terminate when the argc 67baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * is horribly wrong, and argc for the normal cases. 68baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall */ 69baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall for (; argc && argv[0]; argc--, argv++) { 70baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall full_cmd += " "; 71baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall full_cmd += argv[0]; 72baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 73baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall ALOGV("runCmd(%s) res=%d", full_cmd.c_str(), res); 74baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall#endif 7511b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall return res; 769ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 779ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 780031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrallint NatController::setupIptablesHooks() { 79baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall int res; 80baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall res = setDefaults(); 81baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (res < 0) { 82baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return res; 83baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 84baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 85baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall struct CommandsAndArgs defaultCommands[] = { 86baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* 876b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * First chain is for tethering counters. 88baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * This chain is reached via --goto, and then RETURNS. 896b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * 906b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * Second chain is used to limit downstream mss to the upstream pmtu 916b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * so we don't end up fragmenting every large packet tethered devices 926b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * send. Note this feature requires kernel support with flag 936b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * CONFIG_NETFILTER_XT_TARGET_TCPMSS=y, which not all builds will have, 946b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * so the final rule is allowed to fail. 956b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * Bug 17629786 asks to make the failure more obvious, or even fatal 966b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao * so that all builds eventually gain the performance improvement. 97baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall */ 98baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-F", LOCAL_TETHER_COUNTERS_CHAIN,}, 0}, 99baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-X", LOCAL_TETHER_COUNTERS_CHAIN,}, 0}, 100baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-N", LOCAL_TETHER_COUNTERS_CHAIN,}, 1}, 101e8164ddc8204b626c1144a0a504754bf6622c6fdLorenzo Colitti {{IPTABLES_PATH, "-t", "mangle", "-A", LOCAL_MANGLE_FORWARD, "-p", "tcp", "--tcp-flags", 1026b6f22fac4c33fcd349aaf6970bbdc191db752a3Gordon Gao "SYN", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu"}, 0}, 103baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall }; 104baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) { 105baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) && 106baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall defaultCommands[cmdNum].checkRes) { 107baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 108baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 109baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 110f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall ifacePairList.clear(); 111baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 1120031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall return 0; 1130031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall} 1140031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 1150031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrallint NatController::setDefaults() { 116baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* 117baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * The following only works because: 118baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * - the defaultsCommands[].cmd array is padded with NULL, and 119baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * - the 1st argc of runCmd() will just be the max for the CommandsAndArgs[].cmd, and 120baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * - internally it will be memcopied to an array and terminated with a NULL. 121baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall */ 1224ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall struct CommandsAndArgs defaultCommands[] = { 123baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-F", LOCAL_FORWARD,}, 1}, 124baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-A", LOCAL_FORWARD, "-j", "DROP"}, 1}, 125baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-t", "nat", "-F", LOCAL_NAT_POSTROUTING}, 1}, 126001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 1274ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) { 1284ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) && 1294ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall defaultCommands[cmdNum].checkRes) { 1304ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall return -1; 1314ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall } 1324ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall } 133fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 134fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount = 0; 1354ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 1369ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 1379ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 1389ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 13987475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandranint NatController::enableNat(const char* intIface, const char* extIface) { 140baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface); 141baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 14269261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall if (!isIfaceName(intIface) || !isIfaceName(extIface)) { 143fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 144fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 145fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 1469ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 147baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */ 148baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (!strcmp(intIface, extIface)) { 149baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall ALOGE("Duplicate interface specified: %s %s", intIface, extIface); 150baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall errno = EINVAL; 151baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 152baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 153baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 154fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // add this if we are the first added nat 155659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (natCount == 0) { 156001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd[] = { 157001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 158001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-t", 159001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "nat", 160001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-A", 161baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_NAT_POSTROUTING, 162001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 163001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 164001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-j", 165001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "MASQUERADE" 166001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 167001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd), cmd)) { 16887475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran ALOGE("Error setting postroute rule: iface=%s", extIface); 169fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 170fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 171fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 172fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 173fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 174fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 175659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (setForwardRules(true, intIface, extIface) != 0) { 176659692a56cca02822a43b792baba2632d39eb739JP Abgrall ALOGE("Error setting forward rules"); 177659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (natCount == 0) { 178659692a56cca02822a43b792baba2632d39eb739JP Abgrall setDefaults(); 179659692a56cca02822a43b792baba2632d39eb739JP Abgrall } 180659692a56cca02822a43b792baba2632d39eb739JP Abgrall errno = ENODEV; 181659692a56cca02822a43b792baba2632d39eb739JP Abgrall return -1; 182659692a56cca02822a43b792baba2632d39eb739JP Abgrall } 183659692a56cca02822a43b792baba2632d39eb739JP Abgrall 184659692a56cca02822a43b792baba2632d39eb739JP Abgrall /* Always make sure the drop rule is at the end */ 185659692a56cca02822a43b792baba2632d39eb739JP Abgrall const char *cmd1[] = { 186659692a56cca02822a43b792baba2632d39eb739JP Abgrall IPTABLES_PATH, 187659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-D", 188baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 189659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-j", 190659692a56cca02822a43b792baba2632d39eb739JP Abgrall "DROP" 191659692a56cca02822a43b792baba2632d39eb739JP Abgrall }; 192659692a56cca02822a43b792baba2632d39eb739JP Abgrall runCmd(ARRAY_SIZE(cmd1), cmd1); 193659692a56cca02822a43b792baba2632d39eb739JP Abgrall const char *cmd2[] = { 194659692a56cca02822a43b792baba2632d39eb739JP Abgrall IPTABLES_PATH, 195659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-A", 196baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 197659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-j", 198659692a56cca02822a43b792baba2632d39eb739JP Abgrall "DROP" 199659692a56cca02822a43b792baba2632d39eb739JP Abgrall }; 200659692a56cca02822a43b792baba2632d39eb739JP Abgrall runCmd(ARRAY_SIZE(cmd2), cmd2); 201659692a56cca02822a43b792baba2632d39eb739JP Abgrall 20287475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran if (int ret = RouteController::enableTethering(intIface, extIface)) { 20387475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran ALOGE("failed to add tethering rule for iif=%s oif=%s", intIface, extIface); 2048b3b91c6cad577e2928a29073fc962c57ef75af5Sreeram Ramachandran if (natCount == 0) { 2058b3b91c6cad577e2928a29073fc962c57ef75af5Sreeram Ramachandran setDefaults(); 2068b3b91c6cad577e2928a29073fc962c57ef75af5Sreeram Ramachandran } 20787475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran errno = -ret; 20887475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran return -1; 20987475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran } 21087475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran 211659692a56cca02822a43b792baba2632d39eb739JP Abgrall natCount++; 212fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 213fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 214fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 215f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrallbool NatController::checkTetherCountingRuleExist(const char *pair_name) { 216f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall std::list<std::string>::iterator it; 217f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 218f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall for (it = ifacePairList.begin(); it != ifacePairList.end(); it++) { 219f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall if (*it == pair_name) { 220f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall /* We already have this counter */ 221f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall return true; 222f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall } 223f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall } 224f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall return false; 225f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall} 226f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 227baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrallint NatController::setTetherCountingRules(bool add, const char *intIface, const char *extIface) { 228baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 229baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* We only ever add tethering quota rules so that they stick. */ 230baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (!add) { 231baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 232baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 23356afacf838d24cf8e54d2cf0d8ab9182ab704125Sreeram Ramachandran char *pair_name; 234f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall asprintf(&pair_name, "%s_%s", intIface, extIface); 235f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 236f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall if (checkTetherCountingRuleExist(pair_name)) { 237f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 238baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 239baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 240baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall const char *cmd2b[] = { 241baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall IPTABLES_PATH, 242baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-A", 243baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN, 244baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-i", 245baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall intIface, 246baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-o", 247baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall extIface, 248baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-j", 249baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "RETURN" 250baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall }; 251baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 252baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (runCmd(ARRAY_SIZE(cmd2b), cmd2b) && add) { 253f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 254baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 255baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 256f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall ifacePairList.push_front(pair_name); 257f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 258f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 259f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall asprintf(&pair_name, "%s_%s", extIface, intIface); 260f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall if (checkTetherCountingRuleExist(pair_name)) { 261f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 262baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 263baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 264baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 265baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall const char *cmd3b[] = { 266baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall IPTABLES_PATH, 267baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-A", 268baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN, 269baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-i", 270baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall extIface, 271baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-o", 272baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall intIface, 273baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-j", 274baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "RETURN" 275baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall }; 276baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 277baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (runCmd(ARRAY_SIZE(cmd3b), cmd3b) && add) { 278baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall // unwind what's been done, but don't care about success - what more could we do? 279f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 280baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 281baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 282f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall ifacePairList.push_front(pair_name); 283f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 284baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 285baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall} 286baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 287baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrallint NatController::setForwardRules(bool add, const char *intIface, const char *extIface) { 288001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd1[] = { 289001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 290001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand add ? "-A" : "-D", 291baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 292001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-i", 293001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 294001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 295001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand intIface, 296001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-m", 297001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "state", 298001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "--state", 299001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "ESTABLISHED,RELATED", 300baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-g", 301baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN 302001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 303001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand int rc = 0; 304001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 305001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd1), cmd1) && add) { 3069ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 3079ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 3089ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 309001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd2[] = { 310001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 311001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand add ? "-A" : "-D", 312baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 313001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-i", 314001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand intIface, 315001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 316001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 317001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-m", 318001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "state", 319001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "--state", 320001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "INVALID", 321001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-j", 322001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "DROP" 323001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 324001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 325001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd3[] = { 326001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 327001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand add ? "-A" : "-D", 328baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 329001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-i", 330001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand intIface, 331001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 332001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 333baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-g", 334baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN 335001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 336001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 337001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd2), cmd2) && add) { 338f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt // bail on error, but only if adding 339001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand rc = -1; 340001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand goto err_invalid_drop; 341ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt } 342ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt 343001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd3), cmd3) && add) { 344210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 345001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand rc = -1; 346001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand goto err_return; 3479ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 3480031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 349baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (setTetherCountingRules(add, intIface, extIface) && add) { 350baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall rc = -1; 351baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall goto err_return; 352baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 353baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 354fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 355001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 356001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchanderr_return: 357001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand cmd2[1] = "-D"; 358001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand runCmd(ARRAY_SIZE(cmd2), cmd2); 359001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchanderr_invalid_drop: 360001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand cmd1[1] = "-D"; 361001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand runCmd(ARRAY_SIZE(cmd1), cmd1); 362001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand return rc; 363fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 3649ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 36587475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandranint NatController::disableNat(const char* intIface, const char* extIface) { 36669261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall if (!isIfaceName(intIface) || !isIfaceName(extIface)) { 367fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 368fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 3699ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 3709ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 37187475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran if (int ret = RouteController::disableTethering(intIface, extIface)) { 37287475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran ALOGE("failed to remove tethering rule for iif=%s oif=%s", intIface, extIface); 37387475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran errno = -ret; 374fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 375210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 3769ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 377fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setForwardRules(false, intIface, extIface); 378fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (--natCount <= 0) { 3794ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 3804ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo setDefaults(); 381fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 382fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 3839ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 384