blob: c24322a4c7c3c6c1b784805d248ab511fea99e2a [file] [log] [blame]
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +09001/*
2 * Copyright 2016 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 * NatControllerTest.cpp - unit tests for NatController.cpp
17 */
18
19#include <string>
20#include <vector>
21
22#include <fcntl.h>
23#include <unistd.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26
27#include <gtest/gtest.h>
28
29#include <android-base/stringprintf.h>
30#include <android-base/strings.h>
31
32#include "NatController.h"
33#include "IptablesBaseTest.h"
34
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090035using android::base::Join;
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +090036using android::base::StringPrintf;
37
38class NatControllerTest : public IptablesBaseTest {
39public:
40 NatControllerTest() {
41 NatController::execFunction = fake_android_fork_exec;
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090042 NatController::iptablesRestoreFunction = fakeExecIptablesRestore;
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +090043 }
44
45protected:
46 NatController mNatCtrl;
47
48 int setDefaults() {
49 return mNatCtrl.setDefaults();
50 }
51
52 const ExpectedIptablesCommands FLUSH_COMMANDS = {
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090053 { V4, "*filter\n"
54 ":natctrl_FORWARD -\n"
55 "-A natctrl_FORWARD -j DROP\n"
56 "COMMIT\n"
57 "*nat\n"
58 ":natctrl_nat_POSTROUTING -\n"
59 "COMMIT\n" },
60 { V6, "*filter\n"
61 ":natctrl_FORWARD -\n"
62 "COMMIT\n"
63 "*raw\n"
64 ":natctrl_raw_PREROUTING -\n"
65 "COMMIT\n" },
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +090066 };
67
68 const ExpectedIptablesCommands SETUP_COMMANDS = {
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +090069 { V4, "*filter\n"
70 ":natctrl_FORWARD -\n"
71 "-A natctrl_FORWARD -j DROP\n"
72 "COMMIT\n"
73 "*nat\n"
74 ":natctrl_nat_POSTROUTING -\n"
75 "COMMIT\n" },
76 { V6, "*filter\n"
77 ":natctrl_FORWARD -\n"
78 "COMMIT\n"
79 "*raw\n"
80 ":natctrl_raw_PREROUTING -\n"
81 "COMMIT\n" },
82 { V4, "*mangle\n"
83 "-A natctrl_mangle_FORWARD -p tcp --tcp-flags SYN SYN "
84 "-j TCPMSS --clamp-mss-to-pmtu\n"
85 "COMMIT\n" },
86 { V4V6, "*filter\n"
87 ":natctrl_tether_counters -\n"
88 "COMMIT\n" },
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +090089 };
90
Lorenzo Colitti05cfd252016-07-10 23:15:46 +090091 ExpectedIptablesCommands firstNatCommands(const char *extIf) {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +090092 std::string v4Cmd = StringPrintf(
93 "*nat\n"
94 "-A natctrl_nat_POSTROUTING -o %s -j MASQUERADE\n"
95 "COMMIT\n", extIf);
96 std::string v6Cmd =
97 "*filter\n"
98 "-A natctrl_FORWARD -g natctrl_tether_counters\n"
99 "COMMIT\n";
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900100 return {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900101 { V4, v4Cmd },
102 { V6, v6Cmd },
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900103 };
104 }
105
106 ExpectedIptablesCommands startNatCommands(const char *intIf, const char *extIf) {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900107 std::string rpfilterCmd = StringPrintf(
108 "*raw\n"
109 "-A natctrl_raw_PREROUTING -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
110 "COMMIT\n", intIf);
111
112 std::vector<std::string> v4Cmds = {
113 "*filter",
114 StringPrintf("-A natctrl_FORWARD -i %s -o %s -m state --state"
115 " ESTABLISHED,RELATED -g natctrl_tether_counters", extIf, intIf),
116 StringPrintf("-A natctrl_FORWARD -i %s -o %s -m state --state INVALID -j DROP",
117 intIf, extIf),
118 StringPrintf("-A natctrl_FORWARD -i %s -o %s -g natctrl_tether_counters",
119 intIf, extIf),
120 StringPrintf("-A natctrl_tether_counters -i %s -o %s -j RETURN", intIf, extIf),
121 StringPrintf("-A natctrl_tether_counters -i %s -o %s -j RETURN", extIf, intIf),
122 "-D natctrl_FORWARD -j DROP",
123 "-A natctrl_FORWARD -j DROP",
124 "COMMIT\n",
125 };
126
127 std::vector<std::string> v6Cmds = {
128 "*filter",
129 StringPrintf("-A natctrl_tether_counters -i %s -o %s -j RETURN", intIf, extIf),
130 StringPrintf("-A natctrl_tether_counters -i %s -o %s -j RETURN", extIf, intIf),
131 "COMMIT\n",
132 };
133
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900134 return {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900135 { V6, rpfilterCmd },
136 { V4, Join(v4Cmds, '\n') },
137 { V6, Join(v6Cmds, '\n') },
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900138 };
139 }
140
141 ExpectedIptablesCommands stopNatCommands(const char *intIf, const char *extIf) {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900142 std::string rpfilterCmd = StringPrintf(
143 "*raw\n"
144 "-D natctrl_raw_PREROUTING -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
145 "COMMIT\n", intIf);
146
147 std::vector<std::string> v4Cmds = {
148 "*filter",
149 StringPrintf("-D natctrl_FORWARD -i %s -o %s -m state --state"
150 " ESTABLISHED,RELATED -g natctrl_tether_counters", extIf, intIf),
151 StringPrintf("-D natctrl_FORWARD -i %s -o %s -m state --state INVALID -j DROP",
152 intIf, extIf),
153 StringPrintf("-D natctrl_FORWARD -i %s -o %s -g natctrl_tether_counters",
154 intIf, extIf),
155 "COMMIT\n",
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900156 };
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900157
158 return {
159 { V6, rpfilterCmd },
160 { V4, Join(v4Cmds, '\n') },
161 };
162
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900163 }
164};
165
166TEST_F(NatControllerTest, TestSetupIptablesHooks) {
167 mNatCtrl.setupIptablesHooks();
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +0900168 expectIptablesRestoreCommands(SETUP_COMMANDS);
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900169}
170
171TEST_F(NatControllerTest, TestSetDefaults) {
172 setDefaults();
Lorenzo Colitti4fcb4a02017-02-03 14:08:37 +0900173 expectIptablesRestoreCommands(FLUSH_COMMANDS);
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900174}
175
176TEST_F(NatControllerTest, TestAddAndRemoveNat) {
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900177 ExpectedIptablesCommands expected;
178 ExpectedIptablesCommands setupFirstNatCommands = firstNatCommands("rmnet0");
179 ExpectedIptablesCommands startFirstNatCommands = startNatCommands("wlan0", "rmnet0");
180 expected.insert(expected.end(), setupFirstNatCommands.begin(), setupFirstNatCommands.end());
181 expected.insert(expected.end(), startFirstNatCommands.begin(), startFirstNatCommands.end());
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900182 mNatCtrl.enableNat("wlan0", "rmnet0");
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900183 expectIptablesRestoreCommands(expected);
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900184
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900185 ExpectedIptablesCommands startOtherNat = startNatCommands("usb0", "rmnet0");
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900186 mNatCtrl.enableNat("usb0", "rmnet0");
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900187 expectIptablesRestoreCommands(startOtherNat);
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900188
189 ExpectedIptablesCommands stopOtherNat = stopNatCommands("wlan0", "rmnet0");
190 mNatCtrl.disableNat("wlan0", "rmnet0");
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900191 expectIptablesRestoreCommands(stopOtherNat);
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900192
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900193 expected = stopNatCommands("usb0", "rmnet0");
194 expected.insert(expected.end(), FLUSH_COMMANDS.begin(), FLUSH_COMMANDS.end());
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900195 mNatCtrl.disableNat("usb0", "rmnet0");
Lorenzo Colittieb7eb3e2017-08-11 01:20:04 +0900196 expectIptablesRestoreCommands(expected);
Lorenzo Colitti8e1cee92016-07-09 14:24:08 +0900197}