blob: 58c732d00d1b2cc2de2cca21e78bd133ed1c3add [file] [log] [blame]
San Mehat9ff78fb2010-01-19 12:59:15 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
JP Abgrallbaeccc42013-06-25 09:44:10 -070017#define LOG_NDEBUG 0
JP Abgrall0031cea2012-04-17 16:38:23 -070018
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090019#include <string>
20#include <vector>
21
San Mehat9ff78fb2010-01-19 12:59:15 -080022#include <errno.h>
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090023#include <fcntl.h>
24#include <stdlib.h>
25#include <string.h>
26#include <arpa/inet.h>
27#include <linux/in.h>
28#include <netinet/in.h>
San Mehat9ff78fb2010-01-19 12:59:15 -080029#include <sys/socket.h>
30#include <sys/stat.h>
Rom Lemarchand001f0a42013-01-31 12:41:03 -080031#include <sys/wait.h>
San Mehat9ff78fb2010-01-19 12:59:15 -080032
33#define LOG_TAG "NatController"
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090034#include <android-base/strings.h>
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090035#include <android-base/stringprintf.h>
San Mehat9ff78fb2010-01-19 12:59:15 -080036#include <cutils/log.h>
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090037#include <cutils/properties.h>
Rom Lemarchand001f0a42013-01-31 12:41:03 -080038#include <logwrap/logwrap.h>
San Mehat9ff78fb2010-01-19 12:59:15 -080039
40#include "NatController.h"
Robert Greenwaltc4621772012-01-31 12:46:45 -080041#include "NetdConstants.h"
Sreeram Ramachandran87475a12014-07-15 16:20:28 -070042#include "RouteController.h"
San Mehat9ff78fb2010-01-19 12:59:15 -080043
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090044using android::base::Join;
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090045using android::base::StringPrintf;
46
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070047const char* NatController::LOCAL_FORWARD = "natctrl_FORWARD";
Lorenzo Colittie8164dd2014-10-02 20:46:23 +090048const char* NatController::LOCAL_MANGLE_FORWARD = "natctrl_mangle_FORWARD";
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070049const char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING";
Lorenzo Colitti8917e452016-08-01 16:47:50 +090050const char* NatController::LOCAL_RAW_PREROUTING = "natctrl_raw_PREROUTING";
JP Abgrallbaeccc42013-06-25 09:44:10 -070051const char* NatController::LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters";
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070052
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +090053auto NatController::execFunction = android_fork_execvp;
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090054auto NatController::iptablesRestoreFunction = execIptablesRestore;
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +090055
Sreeram Ramachandran87475a12014-07-15 16:20:28 -070056NatController::NatController() {
San Mehat9ff78fb2010-01-19 12:59:15 -080057}
58
59NatController::~NatController() {
60}
61
JP Abgrall4ae80de2013-03-14 20:06:20 -070062struct CommandsAndArgs {
63 /* The array size doesn't really matter as the compiler will barf if too many initializers are specified. */
64 const char *cmd[32];
65 bool checkRes;
66};
67
JP Abgrall0031cea2012-04-17 16:38:23 -070068int NatController::setupIptablesHooks() {
JP Abgrallbaeccc42013-06-25 09:44:10 -070069 int res;
70 res = setDefaults();
71 if (res < 0) {
72 return res;
73 }
74
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090075 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large
76 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA.
77 // This is no longer optional and tethering will fail to start if it fails.
78 std::string mssRewriteCommand = StringPrintf(
79 "*mangle\n"
80 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n"
81 "COMMIT\n", LOCAL_MANGLE_FORWARD);
Lorenzo Colitti05cfd252016-07-10 23:15:46 +090082
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090083 // This is for tethering counters. This chain is reached via --goto, and then RETURNS.
84 std::string defaultCommands = StringPrintf(
85 "*filter\n"
86 ":%s -\n"
87 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN);
88
89 res = iptablesRestoreFunction(V4, mssRewriteCommand);
90 if (res < 0) {
91 return res;
JP Abgrallbaeccc42013-06-25 09:44:10 -070092 }
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090093
94 res = iptablesRestoreFunction(V4V6, defaultCommands);
95 if (res < 0) {
96 return res;
97 }
98
JP Abgrallf3cc83f2013-09-11 20:01:59 -070099 ifacePairList.clear();
JP Abgrallbaeccc42013-06-25 09:44:10 -0700100
JP Abgrall0031cea2012-04-17 16:38:23 -0700101 return 0;
102}
103
104int NatController::setDefaults() {
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +0900105 std::string v4Cmd = StringPrintf(
106 "*filter\n"
107 ":%s -\n"
108 "-A %s -j DROP\n"
109 "COMMIT\n"
110 "*nat\n"
111 ":%s -\n"
112 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
113
114 std::string v6Cmd = StringPrintf(
115 "*filter\n"
116 ":%s -\n"
117 "COMMIT\n"
118 "*raw\n"
119 ":%s -\n"
120 "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
121
122 int res = iptablesRestoreFunction(V4, v4Cmd);
123 if (res < 0) {
124 return res;
125 }
126
127 res = iptablesRestoreFunction(V6, v6Cmd);
128 if (res < 0) {
129 return res;
JP Abgrall4ae80de2013-03-14 20:06:20 -0700130 }
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700131
132 natCount = 0;
Kazuhiro Ondo4ab46852012-01-12 16:15:06 -0600133
San Mehat9ff78fb2010-01-19 12:59:15 -0800134 return 0;
135}
136
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700137int NatController::enableNat(const char* intIface, const char* extIface) {
JP Abgrallbaeccc42013-06-25 09:44:10 -0700138 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
139
JP Abgrall69261cb2014-06-19 18:35:24 -0700140 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
San Mehat9ff78fb2010-01-19 12:59:15 -0800141 errno = ENODEV;
142 return -1;
143 }
144
JP Abgrallbaeccc42013-06-25 09:44:10 -0700145 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
146 if (!strcmp(intIface, extIface)) {
147 ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
148 errno = EINVAL;
149 return -1;
150 }
151
JP Abgrall659692a2013-03-14 20:07:17 -0700152 // add this if we are the first added nat
153 if (natCount == 0) {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900154 std::vector<std::string> v4Cmds = {
155 "*nat",
156 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface),
157 "COMMIT\n"
JP Abgrall659692a2013-03-14 20:07:17 -0700158 };
Lorenzo Colitti05cfd252016-07-10 23:15:46 +0900159
160 /*
161 * IPv6 tethering doesn't need the state-based conntrack rules, so
162 * it unconditionally jumps to the tether counters chain all the time.
163 */
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900164 std::vector<std::string> v6Cmds = {
165 "*filter",
166 StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN),
167 "COMMIT\n"
168 };
Lorenzo Colitti05cfd252016-07-10 23:15:46 +0900169
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900170 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n')) ||
171 iptablesRestoreFunction(V6, Join(v6Cmds, '\n'))) {
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700172 ALOGE("Error setting postroute rule: iface=%s", extIface);
JP Abgrall659692a2013-03-14 20:07:17 -0700173 // unwind what's been done, but don't care about success - what more could we do?
JP Abgrall659692a2013-03-14 20:07:17 -0700174 setDefaults();
175 return -1;
176 }
177 }
178
JP Abgrall659692a2013-03-14 20:07:17 -0700179 if (setForwardRules(true, intIface, extIface) != 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000180 ALOGE("Error setting forward rules");
JP Abgrall659692a2013-03-14 20:07:17 -0700181 if (natCount == 0) {
182 setDefaults();
183 }
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700184 errno = ENODEV;
185 return -1;
186 }
187
188 natCount++;
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700189 return 0;
190}
191
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900192bool NatController::checkTetherCountingRuleExist(const std::string& pair_name) {
193 return std::find(ifacePairList.begin(), ifacePairList.end(), pair_name) != ifacePairList.end();
JP Abgrallf3cc83f2013-09-11 20:01:59 -0700194}
195
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900196/* static */
197std::string NatController::makeTetherCountingRule(const char *if1, const char *if2) {
198 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2);
JP Abgrallbaeccc42013-06-25 09:44:10 -0700199}
200
201int NatController::setForwardRules(bool add, const char *intIface, const char *extIface) {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900202 const char *op = add ? "-A" : "-D";
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700203
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900204 std::string rpfilterCmd = StringPrintf(
205 "*raw\n"
206 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
207 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface);
208 if (iptablesRestoreFunction(V6, rpfilterCmd) == -1 && add) {
San Mehat9ff78fb2010-01-19 12:59:15 -0800209 return -1;
210 }
211
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900212 std::vector<std::string> v4 = {
213 "*filter",
214 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s",
215 op, LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN),
216 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP",
217 op, LOCAL_FORWARD, intIface, extIface),
218 StringPrintf("%s %s -i %s -o %s -g %s",
219 op, LOCAL_FORWARD, intIface, extIface, LOCAL_TETHER_COUNTERS_CHAIN),
Rom Lemarchand001f0a42013-01-31 12:41:03 -0800220 };
221
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900222 std::vector<std::string> v6 = {
223 "*filter",
Rom Lemarchand001f0a42013-01-31 12:41:03 -0800224 };
225
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900226 /* We only ever add tethering quota rules so that they stick. */
227 std::string pair1 = StringPrintf("%s_%s", intIface, extIface);
228 if (add && !checkTetherCountingRuleExist(pair1)) {
229 v4.push_back(makeTetherCountingRule(intIface, extIface));
230 v6.push_back(makeTetherCountingRule(intIface, extIface));
231 }
232 std::string pair2 = StringPrintf("%s_%s", extIface, intIface);
233 if (add && !checkTetherCountingRuleExist(pair2)) {
234 v4.push_back(makeTetherCountingRule(extIface, intIface));
235 v6.push_back(makeTetherCountingRule(extIface, intIface));
Robert Greenwaltddb9f6e2011-08-02 13:00:11 -0700236 }
237
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900238 // Always make sure the drop rule is at the end.
239 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch
240 // every time, starting with ":natctrl_FORWARD -\n". This method would likely be a bit simpler.
241 if (add) {
242 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD));
243 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD));
244 }
245
246 v4.push_back("COMMIT\n");
247 v6.push_back("COMMIT\n");
248
249 // We only add IPv6 rules here, never remove them.
250 if (iptablesRestoreFunction(V4, Join(v4, '\n')) == -1 ||
251 (add && iptablesRestoreFunction(V6, Join(v6, '\n')) == -1)) {
Robert Greenwalt210b9772010-03-25 14:54:45 -0700252 // unwind what's been done, but don't care about success - what more could we do?
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900253 if (add) {
254 setForwardRules(false, intIface, extIface);
255 }
256 return -1;
San Mehat9ff78fb2010-01-19 12:59:15 -0800257 }
JP Abgrall0031cea2012-04-17 16:38:23 -0700258
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900259 if (add && !checkTetherCountingRuleExist(pair1)) {
260 ifacePairList.push_front(pair1);
Lorenzo Colitti8917e452016-08-01 16:47:50 +0900261 }
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900262 if (add && !checkTetherCountingRuleExist(pair2)) {
263 ifacePairList.push_front(pair2);
JP Abgrallbaeccc42013-06-25 09:44:10 -0700264 }
265
San Mehat9ff78fb2010-01-19 12:59:15 -0800266 return 0;
267}
268
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700269int NatController::disableNat(const char* intIface, const char* extIface) {
JP Abgrall69261cb2014-06-19 18:35:24 -0700270 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700271 errno = ENODEV;
272 return -1;
273 }
274
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700275 setForwardRules(false, intIface, extIface);
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700276 if (--natCount <= 0) {
Kazuhiro Ondo4ab46852012-01-12 16:15:06 -0600277 // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
278 setDefaults();
Robert Greenwaltfc97b822011-11-02 16:48:36 -0700279 }
280 return 0;
San Mehat9ff78fb2010-01-19 12:59:15 -0800281}