1fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt/* 2fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * Copyright (C) 2008 The Android Open Source Project 3fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * 4fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 5fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * you may not use this file except in compliance with the License. 6fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * You may obtain a copy of the License at 7fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * 8fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 9fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * 10fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * Unless required by applicable law or agreed to in writing, software 11fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 12fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * See the License for the specific language governing permissions and 14fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt * limitations under the License. 15fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt */ 16fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 17fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <stdlib.h> 18fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <errno.h> 19fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <fcntl.h> 20fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <string.h> 21fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 22fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <sys/socket.h> 23fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <sys/stat.h> 24fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <sys/types.h> 25fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <sys/wait.h> 26fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 27fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <netinet/in.h> 28fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <arpa/inet.h> 29fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 30fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#define LOG_TAG "SecondaryTablController" 31fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <cutils/log.h> 32fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include <cutils/properties.h> 33001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand#include <logwrap/logwrap.h> 349e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 35fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include "ResponseCode.h" 36c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt#include "NetdConstants.h" 37fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include "SecondaryTableController.h" 38fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 399a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubakerconst char* SecondaryTableController::LOCAL_MANGLE_OUTPUT = "st_mangle_OUTPUT"; 40ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrallconst char* SecondaryTableController::LOCAL_MANGLE_POSTROUTING = "st_mangle_POSTROUTING"; 414a946095dad15548ae399665be111be9cb1d9aa6Chad Brubakerconst char* SecondaryTableController::LOCAL_MANGLE_EXEMPT = "st_mangle_EXEMPT"; 422251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubakerconst char* SecondaryTableController::LOCAL_MANGLE_IFACE_FORMAT = "st_mangle_%s_OUTPUT"; 437a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubakerconst char* SecondaryTableController::LOCAL_NAT_POSTROUTING = "st_nat_POSTROUTING"; 442251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubakerconst char* SecondaryTableController::LOCAL_FILTER_OUTPUT = "st_filter_OUTPUT"; 459a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker 46d2617936acc15567fc5111bbdb4dde20845c3cbaChad BrubakerSecondaryTableController::SecondaryTableController(UidMarkMap *map) : mUidMarkMap(map) { 47fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int i; 48fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i=0; i < INTERFACES_TRACKED; i++) { 49fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt mInterfaceTable[i][0] = 0; 50fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // TODO - use a hashtable or other prebuilt container class 51fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt mInterfaceRuleCount[i] = 0; 52fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 53fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 54fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 55fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert GreenwaltSecondaryTableController::~SecondaryTableController() { 56fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 57fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 582251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubakerint SecondaryTableController::setupIptablesHooks() { 592251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker int res = execIptables(V4V6, 602251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 612251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 622251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-F", 632251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_MANGLE_OUTPUT, 642251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 654a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker res |= execIptables(V4V6, 664a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "-t", 674a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "mangle", 684a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "-F", 694a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker LOCAL_MANGLE_EXEMPT, 704a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker NULL); 712349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker // rule for skipping anything marked with the PROTECT_MARK 722251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char protect_mark_str[11]; 732251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(protect_mark_str, sizeof(protect_mark_str), "%d", PROTECT_MARK); 742251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker res |= execIptables(V4V6, 752251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 762251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 772251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-A", 782251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_MANGLE_OUTPUT, 792251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-m", 802251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mark", 812251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--mark", 822251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker protect_mark_str, 832251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-j", 842251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "RETURN", 852251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 862251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 872349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker // protect the legacy VPN daemons from routes. 882349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker // TODO: Remove this when legacy VPN's are removed. 892251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker res |= execIptables(V4V6, 902251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 912251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 922251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-A", 932251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_MANGLE_OUTPUT, 942251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-m", 952251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "owner", 962251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--uid-owner", 972251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "vpn", 982251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-j", 992251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "RETURN", 1002251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 1012251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return res; 1022251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker} 1032251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 104fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint SecondaryTableController::findTableNumber(const char *iface) { 105fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int i; 106fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < INTERFACES_TRACKED; i++) { 1073c20787d7935c2016e8e3cc49d8f15647c12c41cJaime A Lopez-Sollano // compare through the final null, hence +1 1083c20787d7935c2016e8e3cc49d8f15647c12c41cJaime A Lopez-Sollano if (strncmp(iface, mInterfaceTable[i], IFNAMSIZ + 1) == 0) { 109fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return i; 110fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 111fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 112fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 113fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 114fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 115fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint SecondaryTableController::addRoute(SocketClient *cli, char *iface, char *dest, int prefix, 116fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char *gateway) { 117fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int tableIndex = findTableNumber(iface); 118fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableIndex == -1) { 119fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableIndex = findTableNumber(""); // look for an empty slot 120fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableIndex == -1) { 1215ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Max number of NATed interfaces reached"); 122fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 123fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt cli->sendMsg(ResponseCode::OperationFailed, "Max number NATed", true); 124fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 125fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 126d14fd4f83ffeea4ad1cd559a41f775f6814565ccJaime A Lopez-Sollano strncpy(mInterfaceTable[tableIndex], iface, IFNAMSIZ); 127d14fd4f83ffeea4ad1cd559a41f775f6814565ccJaime A Lopez-Sollano // Ensure null termination even if truncation happened 128d14fd4f83ffeea4ad1cd559a41f775f6814565ccJaime A Lopez-Sollano mInterfaceTable[tableIndex][IFNAMSIZ] = 0; 129fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 130fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 131063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt return modifyRoute(cli, ADD, iface, dest, prefix, gateway, tableIndex); 132063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt} 133063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 134c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltint SecondaryTableController::modifyRoute(SocketClient *cli, const char *action, char *iface, 135c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt char *dest, int prefix, char *gateway, int tableIndex) { 136001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand char dest_str[44]; // enough to store an IPv6 address + 3 character bitmask 137001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand char tableIndex_str[11]; 138001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand int ret; 139001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 140001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand // IP tool doesn't like "::" - the equiv of 0.0.0.0 that it accepts for ipv4 141001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand snprintf(dest_str, sizeof(dest_str), "%s/%d", dest, prefix); 142001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand snprintf(tableIndex_str, sizeof(tableIndex_str), "%d", tableIndex + BASE_TABLE_NUMBER); 143063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 144063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt if (strcmp("::", gateway) == 0) { 145001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd[] = { 146001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IP_PATH, 147001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "route", 148001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand action, 149001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand dest_str, 150001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "dev", 151001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand iface, 152001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "table", 153001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand tableIndex_str 154001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 155001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand ret = runCmd(ARRAY_SIZE(cmd), cmd); 156063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } else { 157001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd[] = { 158001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IP_PATH, 159001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "route", 160001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand action, 161001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand dest_str, 162001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "via", 163001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand gateway, 164001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "dev", 165001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand iface, 166001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "table", 167001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand tableIndex_str 168001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 169001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand ret = runCmd(ARRAY_SIZE(cmd), cmd); 170063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } 171063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 172001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (ret) { 1735ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("ip route %s failed: %s route %s %s/%d via %s dev %s table %d", action, 174063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt IP_PATH, action, dest, prefix, gateway, iface, tableIndex+BASE_TABLE_NUMBER); 175fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 176063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt cli->sendMsg(ResponseCode::OperationFailed, "ip route modification failed", true); 177fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 178fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 179063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 180063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt if (strcmp(action, ADD) == 0) { 181063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt mInterfaceRuleCount[tableIndex]++; 182063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } else { 183063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt if (--mInterfaceRuleCount[tableIndex] < 1) { 184063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt mInterfaceRuleCount[tableIndex] = 0; 185063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt mInterfaceTable[tableIndex][0] = 0; 186063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } 187063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } 188c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt modifyRuleCount(tableIndex, action); 189063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt cli->sendMsg(ResponseCode::CommandOkay, "Route modified", false); 190fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 191fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 192fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 193c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltvoid SecondaryTableController::modifyRuleCount(int tableIndex, const char *action) { 194c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt if (strcmp(action, ADD) == 0) { 195c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt mInterfaceRuleCount[tableIndex]++; 196c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } else { 197c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt if (--mInterfaceRuleCount[tableIndex] < 1) { 198c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt mInterfaceRuleCount[tableIndex] = 0; 199c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt mInterfaceTable[tableIndex][0] = 0; 200c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 201c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 202c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt} 203c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 204c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltint SecondaryTableController::verifyTableIndex(int tableIndex) { 205c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt if ((tableIndex < 0) || 206c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt (tableIndex >= INTERFACES_TRACKED) || 207c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt (mInterfaceTable[tableIndex][0] == 0)) { 208c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return -1; 209c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } else { 210c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return 0; 211c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 212c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt} 213c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 214c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char *SecondaryTableController::getVersion(const char *addr) { 215c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt if (strchr(addr, ':') != NULL) { 216c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return "-6"; 217c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } else { 218c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return "-4"; 219c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 220c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt} 221c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 2222251c0fbcf24a9c8fd77b23851f60304087bab2bChad BrubakerIptablesTarget SecondaryTableController::getIptablesTarget(const char *addr) { 2232251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (strchr(addr, ':') != NULL) { 2242251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return V6; 2252251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } else { 2262251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return V4; 2272251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } 2282251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker} 2292251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 230fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint SecondaryTableController::removeRoute(SocketClient *cli, char *iface, char *dest, int prefix, 231fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char *gateway) { 232fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int tableIndex = findTableNumber(iface); 233fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableIndex == -1) { 2345ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Interface not found"); 235fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 236fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); 237fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 238fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 239fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 240063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt return modifyRoute(cli, DEL, iface, dest, prefix, gateway, tableIndex); 241fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 242fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 243c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltint SecondaryTableController::modifyFromRule(int tableIndex, const char *action, 244c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt const char *addr) { 245001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand char tableIndex_str[11]; 246c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 247c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt if (verifyTableIndex(tableIndex)) { 248c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return -1; 249c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 250001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 251001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand snprintf(tableIndex_str, sizeof(tableIndex_str), "%d", tableIndex + 252001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand BASE_TABLE_NUMBER); 253001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd[] = { 254001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IP_PATH, 255001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand getVersion(addr), 256001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "rule", 257001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand action, 258001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "from", 259001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand addr, 260001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "table", 261001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand tableIndex_str 262001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 263001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd), cmd)) { 264c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return -1; 265c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 266c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 267c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt modifyRuleCount(tableIndex, action); 268c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return 0; 269c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt} 270c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 271c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltint SecondaryTableController::modifyLocalRoute(int tableIndex, const char *action, 272c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt const char *iface, const char *addr) { 273001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand char tableIndex_str[11]; 274c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 275c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt if (verifyTableIndex(tableIndex)) { 276c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt return -1; 277c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt } 278c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 279c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt modifyRuleCount(tableIndex, action); // some del's will fail as the iface is already gone. 280c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 281001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand snprintf(tableIndex_str, sizeof(tableIndex_str), "%d", tableIndex + 282001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand BASE_TABLE_NUMBER); 283001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd[] = { 284001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IP_PATH, 285001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "route", 286001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand action, 287001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand addr, 288001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "dev", 289001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand iface, 290001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "table", 291001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand tableIndex_str 292001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 293001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 294001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand return runCmd(ARRAY_SIZE(cmd), cmd); 295c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt} 2967a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubakerint SecondaryTableController::addFwmarkRule(const char *iface) { 2977a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker return setFwmarkRule(iface, true); 2987a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker} 2997a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker 3007a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubakerint SecondaryTableController::removeFwmarkRule(const char *iface) { 3017a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker return setFwmarkRule(iface, false); 3027a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker} 3037a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker 3047a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubakerint SecondaryTableController::setFwmarkRule(const char *iface, bool add) { 3057a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker int tableIndex = findTableNumber(iface); 3067a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker if (tableIndex == -1) { 3077a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker tableIndex = findTableNumber(""); // look for an empty slot 3087a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker if (tableIndex == -1) { 3097a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker ALOGE("Max number of NATed interfaces reached"); 3107a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker errno = ENODEV; 3117a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker return -1; 3127a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker } 3137a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker strncpy(mInterfaceTable[tableIndex], iface, IFNAMSIZ); 3147a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker // Ensure null termination even if truncation happened 3157a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker mInterfaceTable[tableIndex][IFNAMSIZ] = 0; 3167a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker } 3172251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker int mark = tableIndex + BASE_TABLE_NUMBER; 3182251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char mark_str[11]; 3192251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker int ret; 3202251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3212251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //fail fast if any rules already exist for this interface 3222251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (mUidMarkMap->anyRulesForMark(mark)) { 3232251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker errno = EBUSY; 3242251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return -1; 3252251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } 3262251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3272251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(mark_str, sizeof(mark_str), "%d", mark); 3282251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //add the catch all route to the tun. Route rules will make sure the right packets hit the table 3292251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker const char *route_cmd[] = { 3302251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker IP_PATH, 3312251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "route", 3322251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker add ? "add" : "del", 3332251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "default", 3342251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "dev", 3352251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker iface, 3362251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "table", 3372251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str 3382251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker }; 3392251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = runCmd(ARRAY_SIZE(route_cmd), route_cmd); 3402251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3412251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker const char *fwmark_cmd[] = { 3422251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker IP_PATH, 3432251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "rule", 3442251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker add ? "add" : "del", 3452349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "prio", 3462349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker RULE_PRIO, 3472251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "fwmark", 3482251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 3492251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "table", 3502251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str 3512251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker }; 3522251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = runCmd(ARRAY_SIZE(fwmark_cmd), fwmark_cmd); 3532251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (ret) return ret; 3542251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3552251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //add rules for v6 3562251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker const char *route6_cmd[] = { 3572251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker IP_PATH, 3582251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-6", 3592251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "route", 3602251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker add ? "add" : "del", 3612251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "default", 3622251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "dev", 3632251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker iface, 3642251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "table", 3652251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str 3662251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker }; 3672251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = runCmd(ARRAY_SIZE(route6_cmd), route6_cmd); 3682251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3692251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker const char *fwmark6_cmd[] = { 3707a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker IP_PATH, 3712251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-6", 3727a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "rule", 3737a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker add ? "add" : "del", 3742349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "prio", 3752349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker RULE_PRIO, 3767a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "fwmark", 3772251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 3787a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "table", 3792251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str 3807a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker }; 3812251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = runCmd(ARRAY_SIZE(fwmark6_cmd), fwmark6_cmd); 3822251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3832251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 3847a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker if (ret) return ret; 3857a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker 3862251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //create the route rule chain 3872251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char chain_str[IFNAMSIZ + 18]; 3882251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(chain_str, sizeof(chain_str), LOCAL_MANGLE_IFACE_FORMAT, iface); 3892251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //code split due to ordering requirements 3902251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (add) { 3912251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = execIptables(V4V6, 3922251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 3932251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 3942251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-N", 3952251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 3962251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 3972251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //set up the rule for sending premarked packets to the VPN chain 3982251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //Insert these at the top of the chain so they trigger before any UID rules 3992251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret |= execIptables(V4V6, 4002251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 4012251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 4022251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-I", 4032251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_MANGLE_OUTPUT, 4042251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "3", 4052251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-m", 4062251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mark", 4072251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--mark", 4082251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 4092251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-g", 4102251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 4112251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 4122251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //add a rule to clear the mark in the VPN chain 4132251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //packets marked with SO_MARK already have the iface's mark set but unless they match a 4142251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //route they should hit the network instead of the VPN 4152251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret |= execIptables(V4V6, 4162251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 4172251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 4182251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-A", 4192251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 4202251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-j", 4212251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "MARK", 4222251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--set-mark", 4232251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "0", 4242251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 4252251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 426ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall /* Best effort, because some kernels might not have the needed TCPMSS */ 427ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall execIptables(V4V6, 428ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-t", 429ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "mangle", 430ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-A", 431ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall LOCAL_MANGLE_POSTROUTING, 432ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-p", "tcp", "-o", iface, "--tcp-flags", "SYN,RST", "SYN", 433ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-j", 434ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "TCPMSS", 435ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "--clamp-mss-to-pmtu", 436ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall NULL); 437ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall 4382251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } else { 4392251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = execIptables(V4V6, 4402251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 4412251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 4422251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-D", 4432251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_MANGLE_OUTPUT, 4442251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-m", 4452251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mark", 4462251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--mark", 4472251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 4482251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-g", 4492251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 4502251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 4512251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 4522251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //clear and delete the chain 4532251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret |= execIptables(V4V6, 4542251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 4552251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 4562251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-F", 4572251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 4582251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 4592251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 4602251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret |= execIptables(V4V6, 4612251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 4622251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 4632251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-X", 4642251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 4652251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 466ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall 467ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall /* Best effort, because some kernels might not have the needed TCPMSS */ 468ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall execIptables(V4V6, 469ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-t", 470ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "mangle", 471ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-D", 472ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall LOCAL_MANGLE_POSTROUTING, 473ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-p", "tcp", "-o", iface, "--tcp-flags", "SYN,RST", "SYN", 474ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "-j", 475ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "TCPMSS", 476ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall "--clamp-mss-to-pmtu", 477ca5b4e8d0d8219273ecf0961ed6e8c47ab5d798aJP Abgrall NULL); 4782251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } 4792251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 4807a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker //set up the needed source IP rewriting 4817a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker //NOTE: Without ipv6 NAT in the kernel <3.7 only support V4 NAT 4822251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = execIptables(V4, 4837a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "-t", 4847a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "nat", 4857a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker add ? "-A" : "-D", 4867a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker LOCAL_NAT_POSTROUTING, 4877a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "-o", 4887a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker iface, 4897a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "-m", 4907a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "mark", 4917a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "--mark", 4922251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 4937a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "-j", 4947a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker "MASQUERADE", 4957a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker NULL); 4967a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker 4972251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (ret) return ret; 4982251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 4992251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //try and set up for ipv6. ipv6 nat came in the kernel only in 3.7, so this can fail 5002251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = execIptables(V6, 5012251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 5022251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "nat", 5032251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker add ? "-A" : "-D", 5042251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_NAT_POSTROUTING, 5052251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-o", 5062251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker iface, 5072251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-m", 5082251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mark", 5092251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--mark", 5102251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 5112251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-j", 5122251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "MASQUERADE", 5132251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 5142251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (ret) { 5152251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker //Without V6 NAT we can't do V6 over VPNs. 5162251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker ret = execIptables(V6, 5172251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 5182251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "filter", 5192251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker add ? "-A" : "-D", 5202251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker LOCAL_FILTER_OUTPUT, 5212251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-m", 5222251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mark", 5232251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--mark", 5242251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 5252251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-j", 5262251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "REJECT", 5272251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 5282251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } 5292251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return ret; 5302251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 5312251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker} 5322251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 5332251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubakerint SecondaryTableController::addFwmarkRoute(const char* iface, const char *dest, int prefix) { 5342251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return setFwmarkRoute(iface, dest, prefix, true); 5352251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker} 5362251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 5372251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubakerint SecondaryTableController::removeFwmarkRoute(const char* iface, const char *dest, int prefix) { 5382251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return setFwmarkRoute(iface, dest, prefix, true); 5392251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker} 5402251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 5412251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubakerint SecondaryTableController::setFwmarkRoute(const char* iface, const char *dest, int prefix, 5422251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker bool add) { 5432251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker int tableIndex = findTableNumber(iface); 5442251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker if (tableIndex == -1) { 5452251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker errno = EINVAL; 5462251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return -1; 5472251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker } 5482251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker int mark = tableIndex + BASE_TABLE_NUMBER; 5492251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char mark_str[11] = {0}; 5502251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char chain_str[IFNAMSIZ + 18]; 5512251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char dest_str[44]; // enough to store an IPv6 address + 3 character bitmask 5522251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker 5532251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(mark_str, sizeof(mark_str), "%d", mark); 5542251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(chain_str, sizeof(chain_str), LOCAL_MANGLE_IFACE_FORMAT, iface); 5552251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(dest_str, sizeof(dest_str), "%s/%d", dest, prefix); 5562251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker return execIptables(getIptablesTarget(dest), 5572251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-t", 5582251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "mangle", 5592251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker add ? "-A" : "-D", 5602251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 5612251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-d", 5622251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker dest_str, 5632251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-j", 5642251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "MARK", 5652251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "--set-mark", 5662251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker mark_str, 5672251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker NULL); 5687a6ce4bed8569745798bcc26f51d6f306ebdba94Chad Brubaker} 569c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 5708830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubakerint SecondaryTableController::addUidRule(const char *iface, int uid_start, int uid_end) { 5718830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubaker return setUidRule(iface, uid_start, uid_end, true); 5729a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker} 5739a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker 5748830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubakerint SecondaryTableController::removeUidRule(const char *iface, int uid_start, int uid_end) { 5758830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubaker return setUidRule(iface, uid_start, uid_end, false); 5769a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker} 5779a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker 5788830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubakerint SecondaryTableController::setUidRule(const char *iface, int uid_start, int uid_end, bool add) { 5799a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker int tableIndex = findTableNumber(iface); 5809a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker if (tableIndex == -1) { 581d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker errno = EINVAL; 5829a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker return -1; 5839a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker } 584d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker int mark = tableIndex + BASE_TABLE_NUMBER; 585d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker if (add) { 586d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker if (!mUidMarkMap->add(uid_start, uid_end, mark)) { 587d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker errno = EINVAL; 588d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker return -1; 589d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker } 590d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker } else { 591d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker if (!mUidMarkMap->remove(uid_start, uid_end, mark)) { 592d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker errno = EINVAL; 593d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker return -1; 594d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker } 595d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker } 5968830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubaker char uid_str[24] = {0}; 5972251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker char chain_str[IFNAMSIZ + 18]; 5988830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubaker snprintf(uid_str, sizeof(uid_str), "%d-%d", uid_start, uid_end); 5992251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker snprintf(chain_str, sizeof(chain_str), LOCAL_MANGLE_IFACE_FORMAT, iface); 6009a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker return execIptables(V4V6, 6019a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker "-t", 6029a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker "mangle", 6039a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker add ? "-A" : "-D", 6049a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker LOCAL_MANGLE_OUTPUT, 6059a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker "-m", 6069a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker "owner", 6079a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker "--uid-owner", 6088830b94cf4824e5a6c738d39d3015c8eec976352Chad Brubaker uid_str, 6092251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker "-g", 6102251c0fbcf24a9c8fd77b23851f60304087bab2bChad Brubaker chain_str, 6119a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker NULL); 6129a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker} 6139a50889a22c1d93c9e1a14873cde8fc1508f66fdChad Brubaker 6144a946095dad15548ae399665be111be9cb1d9aa6Chad Brubakerint SecondaryTableController::addHostExemption(const char *host) { 6154a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker return setHostExemption(host, true); 6164a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker} 6174a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker 6184a946095dad15548ae399665be111be9cb1d9aa6Chad Brubakerint SecondaryTableController::removeHostExemption(const char *host) { 6194a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker return setHostExemption(host, false); 6204a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker} 6214a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker 6224a946095dad15548ae399665be111be9cb1d9aa6Chad Brubakerint SecondaryTableController::setHostExemption(const char *host, bool add) { 6234a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker IptablesTarget target = !strcmp(getVersion(host), "-4") ? V4 : V6; 6244a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker char protect_mark_str[11]; 6254a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker snprintf(protect_mark_str, sizeof(protect_mark_str), "%d", PROTECT_MARK); 6262349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker int ret = execIptables(target, 6274a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "-t", 6284a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "mangle", 6294a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker add ? "-A" : "-D", 6304a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker LOCAL_MANGLE_EXEMPT, 6314a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "-d", 6324a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker host, 6334a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "-j", 6344a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "MARK", 6354a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker "--set-mark", 6364a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker protect_mark_str, 6374a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker NULL); 6382349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker const char *cmd[] = { 6392349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker IP_PATH, 6402349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker getVersion(host), 6412349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "rule", 6422349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker add ? "add" : "del", 6432349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "prio", 6442349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker EXEMPT_PRIO, 6452349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "to", 6462349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker host, 6472349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "table", 6482349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker "main" 6492349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker }; 6502349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker ret |= runCmd(ARRAY_SIZE(cmd), cmd); 6512349aa60771baae85b1f5fc96e653ac2ef95034bChad Brubaker return ret; 6524a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker} 6534a946095dad15548ae399665be111be9cb1d9aa6Chad Brubaker 654da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubakervoid SecondaryTableController::getUidMark(SocketClient *cli, int uid) { 655da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker int mark = mUidMarkMap->getMark(uid); 656da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker char mark_str[11]; 657da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker snprintf(mark_str, sizeof(mark_str), "%d", mark); 658da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker cli->sendMsg(ResponseCode::GetMarkResult, mark_str, false); 659da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker} 660da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker 661da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubakervoid SecondaryTableController::getProtectMark(SocketClient *cli) { 662da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker char protect_mark_str[11]; 663da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker snprintf(protect_mark_str, sizeof(protect_mark_str), "%d", PROTECT_MARK); 664da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker cli->sendMsg(ResponseCode::GetMarkResult, protect_mark_str, false); 665da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker} 666da7df7c8f009f014486343cfbbaaae2a766f3a2bChad Brubaker 667001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchandint SecondaryTableController::runCmd(int argc, const char **argv) { 668fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int ret = 0; 669001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 670001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand ret = android_fork_execvp(argc, (char **)argv, NULL, false, false); 671fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return ret; 672fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 673