blob: 1913f4170daee3f075c7cc550511ae70c06f80a7 [file] [log] [blame]
Garrick Evansf0ab7132019-06-18 14:50:42 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/datapath.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +09006
Garrick Evansc7ae82c2019-09-04 16:25:10 +09007#include <linux/if_tun.h>
Hugo Benichiaba7e2e2021-02-22 14:47:11 +09008#include <linux/sockios.h>
Taoyu Li90c13912019-11-26 17:56:54 +09009#include <net/if.h>
Garrick Evansc7ae82c2019-09-04 16:25:10 +090010#include <sys/ioctl.h>
11
Garrick Evansf0ab7132019-06-18 14:50:42 +090012#include <utility>
13#include <vector>
14
Garrick Evansc7ae82c2019-09-04 16:25:10 +090015#include <base/bind.h>
hscham4ce3c992021-02-19 16:37:23 +090016#include <base/callback_helpers.h>
Hugo Benichic72b07e2021-01-22 22:55:05 +090017#include <base/strings/string_split.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090018#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090019#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090020#include <gtest/gtest.h>
21
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090022#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090023#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090024
Garrick Evans8e8e3472020-01-23 14:03:50 +090025using testing::_;
26using testing::ElementsAre;
Hugo Benichic72b07e2021-01-22 22:55:05 +090027using testing::ElementsAreArray;
Garrick Evans8e8e3472020-01-23 14:03:50 +090028using testing::Return;
29using testing::StrEq;
30
Garrick Evans3388a032020-03-24 11:25:55 +090031namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090032namespace {
33
Hugo Benichi76675592020-04-08 14:29:57 +090034// TODO(hugobenichi) Centralize this constant definition
35constexpr pid_t kTestPID = -2;
36
Hugo Benichie8758b52020-04-03 14:49:01 +090037std::vector<ioctl_req_t> ioctl_reqs;
38std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Hugo Benichiaba7e2e2021-02-22 14:47:11 +090039std::vector<std::pair<std::string, struct ifreq>> ioctl_ifreq_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090040
41// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090042int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090043 ioctl_reqs.push_back(req);
44 return 0;
45}
46
47// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
48int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
49 ioctl_reqs.push_back(req);
50 ioctl_rtentry_args.push_back({"", *arg});
51 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
52 // this value to ioctl() on the stack.
53 if (arg->rt_dev) {
54 auto& cap = ioctl_rtentry_args.back();
55 cap.first = std::string(arg->rt_dev);
56 cap.second.rt_dev = (char*)cap.first.c_str();
57 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090058 return 0;
59}
60
Hugo Benichiaba7e2e2021-02-22 14:47:11 +090061// Capture ifreq ioctls operations and succeed.
62int ioctl_ifreq_cap(int fd, ioctl_req_t req, void* arg) {
63 ioctl_reqs.push_back(req);
64 switch (req) {
65 case SIOCBRADDBR:
66 case SIOCBRDELBR: {
67 ioctl_ifreq_args.push_back({std::string(static_cast<char*>(arg)), {}});
68 break;
69 }
70 case SIOCBRADDIF: {
71 struct ifreq* ifr = static_cast<struct ifreq*>(arg);
72 ioctl_ifreq_args.push_back({std::string(ifr->ifr_name), *ifr});
73 break;
74 }
75 }
76 return 0;
77}
78
Hugo Benichi1e3bab52021-01-25 22:41:58 +090079std::vector<std::string> SplitCommand(const std::string& command) {
80 return base::SplitString(command, " ",
81 base::WhitespaceHandling::TRIM_WHITESPACE,
82 base::SplitResult::SPLIT_WANT_NONEMPTY);
83}
84
Garrick Evansc7ae82c2019-09-04 16:25:10 +090085} // namespace
86
Hugo Benichic72b07e2021-01-22 22:55:05 +090087using IpFamily::Dual;
88using IpFamily::IPv4;
89using IpFamily::IPv6;
90
Garrick Evans8e8e3472020-01-23 14:03:50 +090091class MockProcessRunner : public MinijailedProcessRunner {
92 public:
93 MockProcessRunner() = default;
94 ~MockProcessRunner() = default;
95
Garrick Evans8e8e3472020-01-23 14:03:50 +090096 MOCK_METHOD4(ip,
97 int(const std::string& obj,
98 const std::string& cmd,
99 const std::vector<std::string>& args,
100 bool log_failures));
101 MOCK_METHOD4(ip6,
102 int(const std::string& obj,
103 const std::string& cmd,
104 const std::vector<std::string>& args,
105 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900106 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +0900107 int(const std::string& table,
108 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900109 bool log_failures,
110 std::string* output));
111 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +0900112 int(const std::string& table,
113 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900114 bool log_failures,
115 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900116 MOCK_METHOD3(sysctl_w,
117 int(const std::string& key,
118 const std::string& value,
119 bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900120 MOCK_METHOD3(ip_netns_attach,
121 int(const std::string& netns_name,
122 pid_t netns_pid,
123 bool log_failures));
124 MOCK_METHOD2(ip_netns_delete,
125 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900126};
127
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900128void Verify_ip(MockProcessRunner& runner, const std::string& command) {
129 auto args = SplitCommand(command);
130 const auto object = args[0];
131 const auto action = args[1];
132 args.erase(args.begin());
133 args.erase(args.begin());
134 EXPECT_CALL(runner,
135 ip(StrEq(object), StrEq(action), ElementsAreArray(args), _));
136}
137
138void Verify_ip6(MockProcessRunner& runner, const std::string& command) {
139 auto args = SplitCommand(command);
140 const auto object = args[0];
141 const auto action = args[1];
142 args.erase(args.begin());
143 args.erase(args.begin());
144 EXPECT_CALL(runner,
145 ip6(StrEq(object), StrEq(action), ElementsAreArray(args), _));
146}
147
Hugo Benichic72b07e2021-01-22 22:55:05 +0900148void Verify_iptables(MockProcessRunner& runner,
149 IpFamily family,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900150 const std::string& command,
151 int call_count = 1) {
Hugo Benichic72b07e2021-01-22 22:55:05 +0900152 auto args =
153 base::SplitString(command, " ", base::WhitespaceHandling::TRIM_WHITESPACE,
154 base::SplitResult::SPLIT_WANT_NONEMPTY);
155 const auto table = args[0];
156 args.erase(args.begin());
157 if (family & IPv4)
158 EXPECT_CALL(runner,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900159 iptables(StrEq(table), ElementsAreArray(args), _, nullptr))
160 .Times(call_count);
Hugo Benichic72b07e2021-01-22 22:55:05 +0900161 if (family & IPv6)
162 EXPECT_CALL(runner,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900163 ip6tables(StrEq(table), ElementsAreArray(args), _, nullptr))
164 .Times(call_count);
Hugo Benichic72b07e2021-01-22 22:55:05 +0900165}
166
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900167void Verify_sysctl_w(MockProcessRunner& runner,
168 const std::string& key,
169 const std::string& value) {
170 EXPECT_CALL(runner, sysctl_w(StrEq(key), StrEq(value), _));
171}
172
173void Verify_ip_netns_attach(MockProcessRunner& runner,
174 const std::string& netns_name,
175 pid_t pid) {
176 EXPECT_CALL(runner, ip_netns_attach(StrEq(netns_name), pid, _));
177}
178
179void Verify_ip_netns_delete(MockProcessRunner& runner,
180 const std::string& netns_name) {
181 EXPECT_CALL(runner, ip_netns_delete(StrEq(netns_name), _));
182}
183
Hugo Benichid82d8832020-08-14 10:05:03 +0900184TEST(DatapathTest, IpFamily) {
Hugo Benichic72b07e2021-01-22 22:55:05 +0900185 EXPECT_EQ(Dual, IPv4 | IPv6);
186 EXPECT_EQ(Dual & IPv4, IPv4);
187 EXPECT_EQ(Dual & IPv6, IPv6);
188 EXPECT_NE(Dual, IPv4);
189 EXPECT_NE(Dual, IPv6);
190 EXPECT_NE(IPv4, IPv6);
Hugo Benichid82d8832020-08-14 10:05:03 +0900191}
192
Hugo Benichibf811c62020-09-07 17:30:45 +0900193TEST(DatapathTest, Start) {
194 MockProcessRunner runner;
195 MockFirewall firewall;
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900196
Hugo Benichibf811c62020-09-07 17:30:45 +0900197 // Asserts for sysctl modifications
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900198 Verify_sysctl_w(runner, "net.ipv4.ip_forward", "1");
199 Verify_sysctl_w(runner, "net.ipv4.ip_local_port_range", "32768 47103");
200 Verify_sysctl_w(runner, "net.ipv6.conf.all.forwarding", "1");
Hugo Benichic72b07e2021-01-22 22:55:05 +0900201
202 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
203 // Asserts for iptables chain reset.
204 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
205 {Dual, "filter -F FORWARD -w"},
206 {Dual, "mangle -F FORWARD -w"},
207 {Dual, "mangle -F INPUT -w"},
208 {Dual, "mangle -F OUTPUT -w"},
209 {Dual, "mangle -F POSTROUTING -w"},
210 {Dual, "mangle -F PREROUTING -w"},
211 {Dual, "mangle -L apply_local_source_mark -w"},
212 {Dual, "mangle -F apply_local_source_mark -w"},
213 {Dual, "mangle -X apply_local_source_mark -w"},
214 {Dual, "mangle -L apply_vpn_mark -w"},
215 {Dual, "mangle -F apply_vpn_mark -w"},
216 {Dual, "mangle -X apply_vpn_mark -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900217 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
218 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
219 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900220 {IPv4, "nat -L redirect_dns -w"},
221 {IPv4, "nat -F redirect_dns -w"},
222 {IPv4, "nat -X redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900223 {IPv4, "nat -F POSTROUTING -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900224 {IPv4, "nat -F OUTPUT -w"},
Hugo Benichi7a066242021-04-07 23:47:32 +0900225 // Asserts for SNAT rules of traffic forwarded from downstream interfaces.
Hugo Benichic72b07e2021-01-22 22:55:05 +0900226 {IPv4,
Hugo Benichi7a066242021-04-07 23:47:32 +0900227 "filter -A FORWARD -m mark --mark 0x00000001/0x00000001 -m state "
228 "--state INVALID -j DROP "
Hugo Benichic72b07e2021-01-22 22:55:05 +0900229 "-w"},
Hugo Benichi7a066242021-04-07 23:47:32 +0900230 {IPv4,
231 "nat -A POSTROUTING -m mark --mark 0x00000001/0x00000001 -j MASQUERADE "
232 "-w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900233 // Asserts for AddForwardEstablishedRule
234 {IPv4,
235 "filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT -w"},
Hugo Benichiac799a82021-03-25 00:16:16 +0900236 {IPv4, "filter -A FORWARD -i arc+ -j ACCEPT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900237 // Asserts for AddSourceIPv4DropRule() calls.
238 {IPv4, "filter -N drop_guest_ipv4_prefix -w"},
239 {IPv4, "filter -I OUTPUT -j drop_guest_ipv4_prefix -w"},
240 {IPv4,
241 "filter -I drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/23 -j DROP "
242 "-w"},
243 {IPv4,
244 "filter -I drop_guest_ipv4_prefix -o wlan+ -s 100.115.92.0/23 -j DROP "
245 "-w"},
246 {IPv4,
247 "filter -I drop_guest_ipv4_prefix -o mlan+ -s 100.115.92.0/23 -j DROP "
248 "-w"},
249 {IPv4,
250 "filter -I drop_guest_ipv4_prefix -o usb+ -s 100.115.92.0/23 -j DROP "
251 "-w"},
252 {IPv4,
253 "filter -I drop_guest_ipv4_prefix -o wwan+ -s 100.115.92.0/23 -j DROP "
254 "-w"},
255 {IPv4,
256 "filter -I drop_guest_ipv4_prefix -o rmnet+ -s 100.115.92.0/23 -j DROP "
257 "-w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900258 // Asserts for OUTPUT ndp connmark bypass rule
259 {IPv6,
260 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT "
261 "-w"},
262 {IPv6,
263 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-advertisement -j "
264 "ACCEPT -w"},
265 {IPv6,
266 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j "
267 "ACCEPT -w"},
268 {IPv6,
269 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j "
270 "ACCEPT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900271 // Asserts for OUTPUT CONNMARK restore rule
272 {Dual,
273 "mangle -A OUTPUT -j CONNMARK --restore-mark --mask 0xffff0000 -w"},
274 // Asserts for apply_local_source_mark chain
275 {Dual, "mangle -N apply_local_source_mark -w"},
276 {Dual, "mangle -A OUTPUT -j apply_local_source_mark -w"},
277 {Dual,
278 "mangle -A apply_local_source_mark -m owner --uid-owner chronos -j MARK "
279 "--set-mark 0x00008100/0x0000ff00 -w"},
280 {Dual,
281 "mangle -A apply_local_source_mark -m owner --uid-owner debugd -j MARK "
282 "--set-mark 0x00008200/0x0000ff00 -w"},
283 {Dual,
284 "mangle -A apply_local_source_mark -m owner --uid-owner cups -j MARK "
285 "--set-mark 0x00008200/0x0000ff00 -w"},
286 {Dual,
287 "mangle -A apply_local_source_mark -m owner --uid-owner lpadmin -j MARK "
288 "--set-mark 0x00008200/0x0000ff00 -w"},
289 {Dual,
290 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd -j "
291 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
292 {Dual,
293 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd-exec "
294 "-j MARK --set-mark 0x00008400/0x0000ff00 -w"},
295 {Dual,
296 "mangle -A apply_local_source_mark -m owner --uid-owner tlsdate -j MARK "
297 "--set-mark 0x00008400/0x0000ff00 -w"},
298 {Dual,
299 "mangle -A apply_local_source_mark -m owner --uid-owner pluginvm -j "
300 "MARK --set-mark 0x00008200/0x0000ff00 -w"},
301 {Dual,
302 "mangle -A apply_local_source_mark -m owner --uid-owner fuse-smbfs -j "
303 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
304 {Dual,
305 "mangle -A apply_local_source_mark -m cgroup --cgroup 0x00010001 -j "
306 "MARK --set-mark 0x00000300/0x0000ff00 -w"},
307 {Dual,
308 "mangle -A apply_local_source_mark -m mark --mark 0x0/0x00003f00 -j "
309 "MARK --set-mark 0x00000400/0x00003f00 -w"},
310 // Asserts for apply_vpn_mark chain
311 {Dual, "mangle -N apply_vpn_mark -w"},
312 {Dual,
313 "mangle -A OUTPUT -m mark --mark 0x00008000/0x0000c000 -j "
314 "apply_vpn_mark -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900315 // Asserts for redirect_dns chain creation
316 {IPv4, "nat -N redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900317 };
318 for (const auto& c : iptables_commands) {
319 Verify_iptables(runner, c.first, c.second);
320 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900321
322 Datapath datapath(&runner, &firewall);
323 datapath.Start();
324}
325
326TEST(DatapathTest, Stop) {
327 MockProcessRunner runner;
328 MockFirewall firewall;
329 // Asserts for sysctl modifications
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900330 Verify_sysctl_w(runner, "net.ipv4.ip_local_port_range", "32768 61000");
331 Verify_sysctl_w(runner, "net.ipv6.conf.all.forwarding", "0");
332 Verify_sysctl_w(runner, "net.ipv4.ip_forward", "0");
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900333 // Asserts for iptables chain reset.
Hugo Benichic72b07e2021-01-22 22:55:05 +0900334 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
335 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
336 {Dual, "filter -F FORWARD -w"},
337 {Dual, "mangle -F FORWARD -w"},
338 {Dual, "mangle -F INPUT -w"},
339 {Dual, "mangle -F OUTPUT -w"},
340 {Dual, "mangle -F POSTROUTING -w"},
341 {Dual, "mangle -F PREROUTING -w"},
342 {Dual, "mangle -L apply_local_source_mark -w"},
343 {Dual, "mangle -F apply_local_source_mark -w"},
344 {Dual, "mangle -X apply_local_source_mark -w"},
345 {Dual, "mangle -L apply_vpn_mark -w"},
346 {Dual, "mangle -F apply_vpn_mark -w"},
347 {Dual, "mangle -X apply_vpn_mark -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900348 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
349 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
350 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900351 {IPv4, "nat -L redirect_dns -w"},
352 {IPv4, "nat -F redirect_dns -w"},
353 {IPv4, "nat -X redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900354 {IPv4, "nat -F POSTROUTING -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900355 {IPv4, "nat -F OUTPUT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900356 };
357 for (const auto& c : iptables_commands) {
358 Verify_iptables(runner, c.first, c.second);
359 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900360
361 Datapath datapath(&runner, &firewall);
362 datapath.Stop();
363}
364
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900365TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900366 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900367 MockFirewall firewall;
368 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900369 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900370 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900371 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900372 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900373 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900374 std::vector<ioctl_req_t> expected = {
375 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
376 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900377 EXPECT_EQ(ioctl_reqs, expected);
378 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900379 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900380}
381
382TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900383 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900384 MockFirewall firewall;
385 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900386 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900387 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900388 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900389 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900390 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900391 std::vector<ioctl_req_t> expected = {
392 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
393 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900394 EXPECT_EQ(ioctl_reqs, expected);
395 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900396 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900397}
398
Garrick Evans621ed262019-11-13 12:28:43 +0900399TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900400 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900401 MockFirewall firewall;
402 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900403 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900404 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900405 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
406 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900407 EXPECT_EQ(ioctl_reqs, expected);
408 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900409 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900410}
411
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900412TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900413 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900414 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900415 Verify_ip(runner, "tuntap del foo0 mode tap");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900416 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900417 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900418}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900419
Hugo Benichi33860d72020-07-09 16:34:01 +0900420TEST(DatapathTest, NetnsAttachName) {
421 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900422 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900423 Verify_ip_netns_delete(runner, "netns_foo");
424 Verify_ip_netns_attach(runner, "netns_foo", 1234);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900425 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900426 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
427}
428
429TEST(DatapathTest, NetnsDeleteName) {
430 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900431 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900432 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900433 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900434 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
435}
436
Garrick Evans8a949dc2019-07-18 16:17:53 +0900437TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900438 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900439 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900440 Verify_ip(runner, "addr add 1.1.1.1/30 brd 1.1.1.3 dev br");
441 Verify_ip(runner, "link set br up");
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900442
443 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900444 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900445
446 EXPECT_EQ(1, ioctl_reqs.size());
447 EXPECT_EQ(SIOCBRADDBR, ioctl_reqs[0]);
448 EXPECT_EQ("br", ioctl_ifreq_args[0].first);
449 ioctl_reqs.clear();
450 ioctl_ifreq_args.clear();
451}
452
453TEST(DatapathTest, RemoveBridge) {
454 MockProcessRunner runner;
455 MockFirewall firewall;
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900456 Verify_ip(runner, "link set br down");
457
458 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
459 datapath.RemoveBridge("br");
460
461 EXPECT_EQ(1, ioctl_reqs.size());
462 EXPECT_EQ(SIOCBRDELBR, ioctl_reqs[0]);
463 EXPECT_EQ("br", ioctl_ifreq_args[0].first);
464 ioctl_reqs.clear();
465 ioctl_ifreq_args.clear();
466}
467
468TEST(DatapathTest, AddToBridge) {
469 MockProcessRunner runner;
470 MockFirewall firewall;
471
472 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
473 datapath.SetIfnameIndex("vethwlan0", 5);
474 datapath.AddToBridge("arcbr0", "vethwlan0");
475
476 EXPECT_EQ(1, ioctl_reqs.size());
477 EXPECT_EQ(SIOCBRADDIF, ioctl_reqs[0]);
478 EXPECT_EQ("arcbr0", ioctl_ifreq_args[0].first);
479 EXPECT_EQ(5, ioctl_ifreq_args[0].second.ifr_ifindex);
480
481 ioctl_reqs.clear();
482 ioctl_ifreq_args.clear();
Garrick Evans8a949dc2019-07-18 16:17:53 +0900483}
484
Hugo Benichi76675592020-04-08 14:29:57 +0900485TEST(DatapathTest, ConnectVethPair) {
486 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900487 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900488 Verify_ip(runner,
489 "link add veth_foo type veth peer name peer_foo netns netns_foo");
490 Verify_ip(runner,
491 "addr add 100.115.92.169/30 brd 100.115.92.171 dev peer_foo");
492 Verify_ip(runner,
493 "link set dev peer_foo up addr 01:02:03:04:05:06 multicast on");
494 Verify_ip(runner, "link set veth_foo up");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900495 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900496 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
497 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900498 Ipv4Addr(100, 115, 92, 169), 30, true));
499}
500
Garrick Evans2470caa2020-03-04 14:15:41 +0900501TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900502 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900503 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900504 Verify_ip(runner,
505 "link add veth_foo type veth peer name peer_foo netns netns_foo");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900506 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900507 EXPECT_TRUE(
508 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900509}
510
511TEST(DatapathTest, ToggleInterface) {
512 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900513 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900514 Verify_ip(runner, "link set foo up");
515 Verify_ip(runner, "link set bar down");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900516 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900517 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
518 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
519}
520
521TEST(DatapathTest, ConfigureInterface) {
522 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900523 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900524 Verify_ip(runner, "addr add 1.1.1.1/30 brd 1.1.1.3 dev foo");
525 Verify_ip(runner, "link set dev foo up addr 02:02:02:02:02:02 multicast on");
Garrick Evans2470caa2020-03-04 14:15:41 +0900526
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900527 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900528 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
529 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
530 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900531}
532
533TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900534 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900535 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900536 Verify_ip(runner, "link delete foo");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900537 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900538 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900539}
540
Hugo Benichi321f23b2020-09-25 15:42:05 +0900541TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
542 MockProcessRunner runner;
543 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900544 Verify_iptables(
545 runner, IPv4,
546 "filter -I drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/24 -j DROP -w");
547 Verify_iptables(
548 runner, IPv4,
549 "filter -D drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/24 -j DROP -w");
Hugo Benichi321f23b2020-09-25 15:42:05 +0900550 Datapath datapath(&runner, &firewall);
551 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
552 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
553}
554
Hugo Benichi7c342672020-09-08 09:18:14 +0900555TEST(DatapathTest, StartRoutingNamespace) {
556 MockProcessRunner runner;
557 MockFirewall firewall;
558 MacAddress mac = {1, 2, 3, 4, 5, 6};
559
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900560 Verify_ip_netns_delete(runner, "netns_foo");
561 Verify_ip_netns_attach(runner, "netns_foo", kTestPID);
562 Verify_ip(runner,
563 "link add arc_ns0 type veth peer name veth0 netns netns_foo");
564 Verify_ip(runner, "addr add 100.115.92.130/30 brd 100.115.92.131 dev veth0");
565 Verify_ip(runner,
566 "link set dev veth0 up addr 01:02:03:04:05:06 multicast off");
567 Verify_ip(runner, "link set arc_ns0 up");
568 Verify_ip(runner,
569 "addr add 100.115.92.129/30 brd 100.115.92.131 dev arc_ns0");
570 Verify_ip(runner,
571 "link set dev arc_ns0 up addr 01:02:03:04:05:06 multicast off");
Hugo Benichi860ef532021-01-25 17:19:36 +0900572 Verify_iptables(runner, IPv4, "filter -A FORWARD -o arc_ns0 -j ACCEPT -w");
573 Verify_iptables(runner, IPv4, "filter -A FORWARD -i arc_ns0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900574 Verify_iptables(runner, Dual, "mangle -N PREROUTING_arc_ns0 -w");
575 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_ns0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900576 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900577 "mangle -A PREROUTING -i arc_ns0 -j PREROUTING_arc_ns0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900578 Verify_iptables(runner, IPv4,
579 "mangle -A PREROUTING_arc_ns0 -j MARK --set-mark "
580 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900581 Verify_iptables(runner, Dual,
582 "mangle -A PREROUTING_arc_ns0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900583 "0x00000200/0x00003f00 -w");
584 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900585 "mangle -A PREROUTING_arc_ns0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900586 "--restore-mark --mask 0xffff0000 -w");
587 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900588 "mangle -A PREROUTING_arc_ns0 -j apply_vpn_mark -w");
Hugo Benichi7c342672020-09-08 09:18:14 +0900589
Hugo Benichifcf81022020-12-04 11:01:37 +0900590 ConnectedNamespace nsinfo = {};
591 nsinfo.pid = kTestPID;
592 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900593 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900594 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900595 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900596 nsinfo.host_ifname = "arc_ns0";
597 nsinfo.peer_ifname = "veth0";
598 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
599 base::DoNothing());
600 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900601 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900602 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900603 ioctl_reqs.clear();
604 ioctl_rtentry_args.clear();
605}
606
607TEST(DatapathTest, StopRoutingNamespace) {
608 MockProcessRunner runner;
609 MockFirewall firewall;
610
Hugo Benichi860ef532021-01-25 17:19:36 +0900611 Verify_iptables(runner, IPv4, "filter -D FORWARD -o arc_ns0 -j ACCEPT -w");
612 Verify_iptables(runner, IPv4, "filter -D FORWARD -i arc_ns0 -j ACCEPT -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900613 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900614 "mangle -D PREROUTING -i arc_ns0 -j PREROUTING_arc_ns0 -w");
615 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_ns0 -w");
616 Verify_iptables(runner, Dual, "mangle -X PREROUTING_arc_ns0 -w");
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900617 Verify_ip_netns_delete(runner, "netns_foo");
618 Verify_ip(runner, "link delete arc_ns0");
Hugo Benichi7c342672020-09-08 09:18:14 +0900619
Hugo Benichifcf81022020-12-04 11:01:37 +0900620 ConnectedNamespace nsinfo = {};
621 nsinfo.pid = kTestPID;
622 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900623 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900624 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900625 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900626 nsinfo.host_ifname = "arc_ns0";
627 nsinfo.peer_ifname = "veth0";
628 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
629 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900630 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900631 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900632}
633
Hugo Benichi8d622b52020-08-13 15:24:12 +0900634TEST(DatapathTest, StartRoutingDevice_Arc) {
635 MockProcessRunner runner;
636 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900637 Verify_iptables(
638 runner, IPv4,
639 "nat -A PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
640 Verify_iptables(
641 runner, IPv4,
642 "nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
643 Verify_iptables(
644 runner, IPv4,
645 "nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
646 Verify_iptables(runner, IPv4,
647 "filter -A FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
648 Verify_iptables(runner, IPv4,
649 "filter -A FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900650 Verify_iptables(runner, Dual, "mangle -N PREROUTING_arc_eth0 -w");
651 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_eth0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900652 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900653 "mangle -A PREROUTING -i arc_eth0 -j PREROUTING_arc_eth0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900654 Verify_iptables(runner, IPv4,
655 "mangle -A PREROUTING_arc_eth0 -j MARK --set-mark "
656 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900657 Verify_iptables(runner, Dual,
658 "mangle -A PREROUTING_arc_eth0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900659 "0x00002000/0x00003f00 -w");
660 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900661 "mangle -A PREROUTING_arc_eth0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900662 "0x03ea0000/0xffff0000 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900663
664 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900665 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900666 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900667 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900668}
669
670TEST(DatapathTest, StartRoutingDevice_CrosVM) {
671 MockProcessRunner runner;
672 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900673 Verify_iptables(runner, IPv4, "filter -A FORWARD -o vmtap0 -j ACCEPT -w");
674 Verify_iptables(runner, IPv4, "filter -A FORWARD -i vmtap0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900675 Verify_iptables(runner, Dual, "mangle -N PREROUTING_vmtap0 -w");
676 Verify_iptables(runner, Dual, "mangle -F PREROUTING_vmtap0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900677 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900678 "mangle -A PREROUTING -i vmtap0 -j PREROUTING_vmtap0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900679 Verify_iptables(runner, IPv4,
680 "mangle -A PREROUTING_vmtap0 -j MARK --set-mark "
681 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900682 Verify_iptables(runner, Dual,
683 "mangle -A PREROUTING_vmtap0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900684 "0x00002100/0x00003f00 -w");
685 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900686 "mangle -A PREROUTING_vmtap0 -j CONNMARK --restore-mark "
687 "--mask 0xffff0000 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900688 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900689 "mangle -A PREROUTING_vmtap0 -j apply_vpn_mark -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900690
691 Datapath datapath(&runner, &firewall);
692 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900693 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900694}
695
696TEST(DatapathTest, StopRoutingDevice_Arc) {
697 MockProcessRunner runner;
698 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900699 Verify_iptables(
700 runner, IPv4,
701 "nat -D PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
702 Verify_iptables(
703 runner, IPv4,
704 "nat -D PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
705 Verify_iptables(
706 runner, IPv4,
707 "nat -D PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
708 Verify_iptables(runner, IPv4,
709 "filter -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
710 Verify_iptables(runner, IPv4,
711 "filter -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
712 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900713 "mangle -D PREROUTING -i arc_eth0 -j PREROUTING_arc_eth0 -w");
714 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_eth0 -w");
715 Verify_iptables(runner, Dual, "mangle -X PREROUTING_arc_eth0 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900716
717 Datapath datapath(&runner, &firewall);
718 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900719 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900720}
721
722TEST(DatapathTest, StopRoutingDevice_CrosVM) {
723 MockProcessRunner runner;
724 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900725 Verify_iptables(runner, IPv4, "filter -D FORWARD -o vmtap0 -j ACCEPT -w");
726 Verify_iptables(runner, IPv4, "filter -D FORWARD -i vmtap0 -j ACCEPT -w");
727 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900728 "mangle -D PREROUTING -i vmtap0 -j PREROUTING_vmtap0 -w");
729 Verify_iptables(runner, Dual, "mangle -F PREROUTING_vmtap0 -w");
730 Verify_iptables(runner, Dual, "mangle -X PREROUTING_vmtap0 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900731
732 Datapath datapath(&runner, &firewall);
733 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900734 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900735}
736
Hugo Benichid82d8832020-08-14 10:05:03 +0900737TEST(DatapathTest, StartStopIpForwarding) {
738 struct {
739 IpFamily family;
740 std::string iif;
741 std::string oif;
Hugo Benichi860ef532021-01-25 17:19:36 +0900742 std::string start_args;
743 std::string stop_args;
Hugo Benichid82d8832020-08-14 10:05:03 +0900744 bool result;
745 } testcases[] = {
Hugo Benichi860ef532021-01-25 17:19:36 +0900746 {IPv4, "", "", {}, {}, false},
747 {NONE, "foo", "bar", {}, {}, false},
748 {IPv4, "foo", "bar", "filter -A FORWARD -i foo -o bar -j ACCEPT -w",
749 "filter -D FORWARD -i foo -o bar -j ACCEPT -w", true},
750 {IPv4, "", "bar", "filter -A FORWARD -o bar -j ACCEPT -w",
751 "filter -D FORWARD -o bar -j ACCEPT -w", true},
752 {IPv4, "foo", "", "filter -A FORWARD -i foo -j ACCEPT -w",
753 "filter -D FORWARD -i foo -j ACCEPT -w", true},
754 {IPv6, "foo", "bar", "filter -A FORWARD -i foo -o bar -j ACCEPT -w",
755 "filter -D FORWARD -i foo -o bar -j ACCEPT -w", true},
756 {IPv6, "", "bar", "filter -A FORWARD -o bar -j ACCEPT -w",
757 "filter -D FORWARD -o bar -j ACCEPT -w", true},
758 {IPv6, "foo", "", "filter -A FORWARD -i foo -j ACCEPT -w",
759 "filter -D FORWARD -i foo -j ACCEPT -w", true},
760 {Dual, "foo", "bar", "filter -A FORWARD -i foo -o bar -j ACCEPT -w",
761 "filter -D FORWARD -i foo -o bar -j ACCEPT -w", true},
762 {Dual, "", "bar", "filter -A FORWARD -o bar -j ACCEPT -w",
763 "filter -D FORWARD -o bar -j ACCEPT -w", true},
764 {Dual, "foo", "", "filter -A FORWARD -i foo -j ACCEPT -w",
765 "filter -D FORWARD -i foo -j ACCEPT -w", true},
Hugo Benichid82d8832020-08-14 10:05:03 +0900766 };
767
768 for (const auto& tt : testcases) {
769 MockProcessRunner runner;
770 MockFirewall firewall;
771 if (tt.result) {
Hugo Benichi860ef532021-01-25 17:19:36 +0900772 Verify_iptables(runner, tt.family, tt.start_args);
773 Verify_iptables(runner, tt.family, tt.stop_args);
Hugo Benichid82d8832020-08-14 10:05:03 +0900774 }
775 Datapath datapath(&runner, &firewall);
776
777 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
778 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
779 }
780}
781
Hugo Benichi76be34a2020-08-26 22:35:54 +0900782TEST(DatapathTest, StartStopConnectionPinning) {
783 MockProcessRunner runner;
784 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +0900785
786 // Setup
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900787 Verify_iptables(runner, Dual, "mangle -N POSTROUTING_eth0 -w");
788 Verify_iptables(runner, Dual, "mangle -F POSTROUTING_eth0 -w",
789 2 /* Start and Stop */);
Hugo Benichi860ef532021-01-25 17:19:36 +0900790 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900791 "mangle -A POSTROUTING -o eth0 -j POSTROUTING_eth0 -w");
792 Verify_iptables(runner, Dual,
793 "mangle -A POSTROUTING_eth0 -j CONNMARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900794 "0x03eb0000/0xffff0000 -w");
795 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900796 "mangle -A POSTROUTING_eth0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900797 "--save-mark --mask 0x00003f00 -w");
798 Verify_iptables(runner, Dual,
799 "mangle -A PREROUTING -i eth0 -j CONNMARK "
800 "--restore-mark --mask 0x00003f00 -w");
Hugo Benichi155de002021-01-19 16:45:46 +0900801
Hugo Benichi1af52392020-11-27 18:09:32 +0900802 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900803 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900804 "mangle -D POSTROUTING -o eth0 -j POSTROUTING_eth0 -w");
805 Verify_iptables(runner, Dual, "mangle -X POSTROUTING_eth0 -w");
806 Verify_iptables(runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900807 "mangle -D PREROUTING -i eth0 -j CONNMARK "
808 "--restore-mark --mask 0x00003f00 -w");
Hugo Benichi1af52392020-11-27 18:09:32 +0900809
Hugo Benichi76be34a2020-08-26 22:35:54 +0900810 Datapath datapath(&runner, &firewall);
811 datapath.SetIfnameIndex("eth0", 3);
812 datapath.StartConnectionPinning("eth0");
813 datapath.StopConnectionPinning("eth0");
814}
815
Hugo Benichibfc49112020-12-14 12:54:44 +0900816TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +0900817 MockProcessRunner runner;
818 MockFirewall firewall;
819
820 // Setup
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900821 Verify_iptables(runner, Dual, "mangle -N POSTROUTING_arcbr0 -w");
822 Verify_iptables(runner, Dual, "mangle -F POSTROUTING_arcbr0 -w",
823 2 /* Start and Stop */);
824 Verify_iptables(runner, Dual,
825 "mangle -A POSTROUTING -o arcbr0 -j POSTROUTING_arcbr0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900826 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900827 "mangle -A POSTROUTING_arcbr0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900828 "--set-mark 0x03ed0000/0xffff0000 -w");
829 Verify_iptables(
830 runner, Dual,
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900831 "mangle -A apply_vpn_mark -m mark ! --mark 0x0/0xffff0000 -j ACCEPT -w");
832 Verify_iptables(
833 runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900834 "mangle -A apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
835 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900836 "mangle -A POSTROUTING_arcbr0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900837 "--save-mark --mask 0x00003f00 -w");
838 Verify_iptables(runner, Dual,
839 "mangle -A PREROUTING -i arcbr0 -j CONNMARK "
840 "--restore-mark --mask 0x00003f00 -w");
841 Verify_iptables(runner, IPv4,
842 "nat -A POSTROUTING -o arcbr0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900843 Verify_iptables(runner, IPv4,
844 "nat -A OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
845 "redirect_dns -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900846
Hugo Benichi2a940542020-10-26 18:50:49 +0900847 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900848 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900849 "mangle -D POSTROUTING -o arcbr0 -j POSTROUTING_arcbr0 -w");
850 Verify_iptables(runner, Dual, "mangle -X POSTROUTING_arcbr0 -w");
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900851 Verify_iptables(runner, Dual, "mangle -F apply_vpn_mark -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900852 Verify_iptables(runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900853 "mangle -D PREROUTING -i arcbr0 -j CONNMARK "
854 "--restore-mark --mask 0x00003f00 -w");
855 Verify_iptables(runner, IPv4,
856 "nat -D POSTROUTING -o arcbr0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900857 Verify_iptables(runner, IPv4,
858 "nat -D OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
859 "redirect_dns -w");
Hugo Benichi2a940542020-10-26 18:50:49 +0900860
861 Datapath datapath(&runner, &firewall);
862 datapath.SetIfnameIndex("arcbr0", 5);
863 datapath.StartVpnRouting("arcbr0");
864 datapath.StopVpnRouting("arcbr0");
865}
866
Hugo Benichibfc49112020-12-14 12:54:44 +0900867TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
868 MockProcessRunner runner;
869 MockFirewall firewall;
870
871 // Setup
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900872 Verify_iptables(runner, Dual, "mangle -N POSTROUTING_tun0 -w");
873 Verify_iptables(runner, Dual, "mangle -F POSTROUTING_tun0 -w",
874 2 /* Start and Stop */);
875 Verify_iptables(runner, Dual,
876 "mangle -A POSTROUTING -o tun0 -j POSTROUTING_tun0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900877 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900878 "mangle -A POSTROUTING_tun0 -j CONNMARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900879 "0x03ed0000/0xffff0000 -w");
880 Verify_iptables(
881 runner, Dual,
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900882 "mangle -A apply_vpn_mark -m mark ! --mark 0x0/0xffff0000 -j ACCEPT -w");
883 Verify_iptables(
884 runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900885 "mangle -A apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
886 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900887 "mangle -A POSTROUTING_tun0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900888 "--save-mark --mask 0x00003f00 -w");
889 Verify_iptables(runner, Dual,
890 "mangle -A PREROUTING -i tun0 -j CONNMARK "
891 "--restore-mark --mask 0x00003f00 -w");
892 Verify_iptables(runner, IPv4, "nat -A POSTROUTING -o tun0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900893 Verify_iptables(runner, IPv4,
894 "nat -A OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
895 "redirect_dns -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900896 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900897 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900898 "mangle -D POSTROUTING -o tun0 -j POSTROUTING_tun0 -w");
899 Verify_iptables(runner, Dual, "mangle -X POSTROUTING_tun0 -w");
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900900 Verify_iptables(runner, Dual, "mangle -F apply_vpn_mark -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900901 Verify_iptables(runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900902 "mangle -D PREROUTING -i tun0 -j CONNMARK "
903 "--restore-mark --mask 0x00003f00 -w");
904 Verify_iptables(runner, IPv4, "nat -D POSTROUTING -o tun0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900905 Verify_iptables(runner, IPv4,
906 "nat -D OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
907 "redirect_dns -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900908 // Start tun0 <-> arcbr0 routing
Hugo Benichi860ef532021-01-25 17:19:36 +0900909 Verify_iptables(runner, IPv4,
910 "filter -A FORWARD -i tun0 -o arcbr0 -j ACCEPT -w");
911 Verify_iptables(runner, IPv4,
912 "filter -A FORWARD -i arcbr0 -o tun0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900913 Verify_iptables(runner, Dual, "mangle -N PREROUTING_arcbr0 -w");
914 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arcbr0 -w",
915 2 /* Start and Stop */);
Hugo Benichi860ef532021-01-25 17:19:36 +0900916 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900917 "mangle -A PREROUTING -i arcbr0 -j PREROUTING_arcbr0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900918 Verify_iptables(runner, IPv4,
919 "mangle -A PREROUTING_arcbr0 -j MARK --set-mark "
920 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900921 Verify_iptables(runner, Dual,
922 "mangle -A PREROUTING_arcbr0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900923 "0x00002000/0x00003f00 -w");
924 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900925 "mangle -A PREROUTING_arcbr0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900926 "0x03ed0000/0xffff0000 -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900927 // Stop tun0 <-> arcbr0 routing
Hugo Benichi860ef532021-01-25 17:19:36 +0900928 Verify_iptables(runner, IPv4,
929 "filter -D FORWARD -i tun0 -o arcbr0 -j ACCEPT -w");
930 Verify_iptables(runner, IPv4,
931 "filter -D FORWARD -i arcbr0 -o tun0 -j ACCEPT -w");
932 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900933 "mangle -D PREROUTING -i arcbr0 -j PREROUTING_arcbr0 -w");
934 Verify_iptables(runner, Dual, "mangle -X PREROUTING_arcbr0 -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900935
936 Datapath datapath(&runner, &firewall);
937 datapath.SetIfnameIndex("tun0", 5);
938 datapath.StartVpnRouting("tun0");
939 datapath.StopVpnRouting("tun0");
940}
941
Garrick Evansf0ab7132019-06-18 14:50:42 +0900942TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900943 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900944 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900945 Verify_iptables(
946 runner, IPv4,
947 "nat -A PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
948 Verify_iptables(
949 runner, IPv4,
950 "nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
951 Verify_iptables(
952 runner, IPv4,
953 "nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
954
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900955 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900956 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900957}
958
959TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900960 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900961 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900962 Verify_iptables(
963 runner, IPv4,
964 "nat -D PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
965 Verify_iptables(
966 runner, IPv4,
967 "nat -D PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
968 Verify_iptables(
969 runner, IPv4,
970 "nat -D PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
971
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900972 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900973 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900974}
975
Garrick Evans664a82f2019-12-17 12:18:05 +0900976TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900977 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900978 MockFirewall firewall;
979 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +0900980
Garrick Evans664a82f2019-12-17 12:18:05 +0900981 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +0900982 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +0900983 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +0900984 EXPECT_EQ(ioctl_reqs, expected);
985 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900986 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +0900987}
988
989TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900990 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900991 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +0900992 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +0900993 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
994 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
995 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900996 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +0900997 .WillOnce(Return(1));
998 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
999 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1000 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001001 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001002 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1003 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1004 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001005 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001006 .WillOnce(Return(1));
1007 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1008 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1009 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001010 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001011 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001012 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001013}
1014
Taoyu Lica49c832019-12-06 17:56:43 +09001015TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001016 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001017 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001018 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1019 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1020 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001021 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001022 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1023 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1024 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001025 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001026 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001027 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001028}
1029
Taoyu Li90c13912019-11-26 17:56:54 +09001030TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001031 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001032 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +09001033 Verify_iptables(runner, IPv6,
1034 "filter -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
1035 Verify_iptables(runner, IPv6,
1036 "filter -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001037 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001038 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001039}
1040
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001041TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001042 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001043 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +09001044 Verify_ip6(runner, "route replace 2001:da8:e00::1234/128 dev eth0");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001045 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001046 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001047}
1048
Hugo Benichie8758b52020-04-03 14:49:01 +09001049TEST(DatapathTest, AddIPv4Route) {
1050 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001051 MockFirewall firewall;
1052 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001053
1054 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1055 Ipv4Addr(255, 255, 255, 0));
1056 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1057 Ipv4Addr(255, 255, 255, 0));
1058 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1059 Ipv4Addr(255, 255, 255, 252));
1060 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1061 Ipv4Addr(255, 255, 255, 252));
1062
1063 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1064 SIOCDELRT};
1065 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001066
1067 std::string route1 =
1068 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1069 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1070 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1071 "RTF_GATEWAY}";
1072 std::string route2 =
1073 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1074 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1075 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1076 std::vector<std::string> captured_routes;
1077 for (const auto& route : ioctl_rtentry_args) {
1078 std::ostringstream stream;
1079 stream << route.second;
1080 captured_routes.emplace_back(stream.str());
1081 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001082 EXPECT_EQ(route1, captured_routes[0]);
1083 EXPECT_EQ(route1, captured_routes[1]);
1084 EXPECT_EQ(route2, captured_routes[2]);
1085 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001086 ioctl_reqs.clear();
1087 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001088}
1089
Hugo Benichi1e0656f2021-02-15 15:43:38 +09001090TEST(DatapathTest, RedirectDnsRules) {
1091 MockProcessRunner runner;
1092 MockFirewall firewall;
1093
1094 Verify_iptables(runner, IPv4,
1095 "nat -I redirect_dns -p tcp --dport 53 -o eth0 -j DNAT "
1096 "--to-destination 192.168.1.1 -w");
1097 Verify_iptables(runner, IPv4,
1098 "nat -I redirect_dns -p udp --dport 53 -o eth0 -j DNAT "
1099 "--to-destination 192.168.1.1 -w");
1100 Verify_iptables(runner, IPv4,
1101 "nat -I redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1102 "--to-destination 1.1.1.1 -w");
1103 Verify_iptables(runner, IPv4,
1104 "nat -I redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1105 "--to-destination 1.1.1.1 -w");
1106 Verify_iptables(runner, IPv4,
1107 "nat -D redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1108 "--to-destination 1.1.1.1 -w");
1109 Verify_iptables(runner, IPv4,
1110 "nat -D redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1111 "--to-destination 1.1.1.1 -w");
1112 Verify_iptables(runner, IPv4,
1113 "nat -I redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1114 "--to-destination 8.8.8.8 -w");
1115 Verify_iptables(runner, IPv4,
1116 "nat -I redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1117 "--to-destination 8.8.8.8 -w");
1118 Verify_iptables(runner, IPv4,
1119 "nat -D redirect_dns -p tcp --dport 53 -o eth0 -j DNAT "
1120 "--to-destination 192.168.1.1 -w");
1121 Verify_iptables(runner, IPv4,
1122 "nat -D redirect_dns -p udp --dport 53 -o eth0 -j DNAT "
1123 "--to-destination 192.168.1.1 -w");
1124 Verify_iptables(runner, IPv4,
1125 "nat -D redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1126 "--to-destination 8.8.8.8 -w");
1127 Verify_iptables(runner, IPv4,
1128 "nat -D redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1129 "--to-destination 8.8.8.8 -w");
1130
1131 Datapath datapath(&runner, &firewall);
1132 datapath.RemoveRedirectDnsRule("wlan0");
1133 datapath.RemoveRedirectDnsRule("unknown");
1134 datapath.AddRedirectDnsRule("eth0", "192.168.1.1");
1135 datapath.AddRedirectDnsRule("wlan0", "1.1.1.1");
1136 datapath.AddRedirectDnsRule("wlan0", "8.8.8.8");
1137 datapath.RemoveRedirectDnsRule("eth0");
1138 datapath.RemoveRedirectDnsRule("wlan0");
1139}
1140
Garrick Evans2f581a02020-05-11 10:43:35 +09001141TEST(DatapathTest, ArcVethHostName) {
1142 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1143 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1144 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1145 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1146 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1147 EXPECT_EQ("vethexceeds_ify", ifname);
1148 EXPECT_LT(ifname.length(), IFNAMSIZ);
1149}
1150
Garrick Evans8a067562020-05-11 12:47:30 +09001151TEST(DatapathTest, ArcBridgeName) {
1152 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1153 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1154 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1155 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1156 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1157 EXPECT_EQ("arc_exceeds_ify", ifname);
1158 EXPECT_LT(ifname.length(), IFNAMSIZ);
1159}
1160
Garrick Evans3388a032020-03-24 11:25:55 +09001161} // namespace patchpanel