blob: ce018d0ec74f96bde5766a492cddc809cdca5010 [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>
Taoyu Li90c13912019-11-26 17:56:54 +09008#include <net/if.h>
Garrick Evansc7ae82c2019-09-04 16:25:10 +09009#include <sys/ioctl.h>
10
Garrick Evansf0ab7132019-06-18 14:50:42 +090011#include <utility>
12#include <vector>
13
Garrick Evansc7ae82c2019-09-04 16:25:10 +090014#include <base/bind.h>
Qijiang Fane90b8792020-03-09 16:15:41 +090015#include <base/bind_helpers.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090016#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090017#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090018#include <gtest/gtest.h>
19
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090020#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090021#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090022
Garrick Evans8e8e3472020-01-23 14:03:50 +090023using testing::_;
24using testing::ElementsAre;
25using testing::Return;
26using testing::StrEq;
27
Garrick Evans3388a032020-03-24 11:25:55 +090028namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090029namespace {
30
Hugo Benichi76675592020-04-08 14:29:57 +090031// TODO(hugobenichi) Centralize this constant definition
32constexpr pid_t kTestPID = -2;
33
Hugo Benichie8758b52020-04-03 14:49:01 +090034std::vector<ioctl_req_t> ioctl_reqs;
35std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090036
37// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090038int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090039 ioctl_reqs.push_back(req);
40 return 0;
41}
42
43// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
44int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
45 ioctl_reqs.push_back(req);
46 ioctl_rtentry_args.push_back({"", *arg});
47 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
48 // this value to ioctl() on the stack.
49 if (arg->rt_dev) {
50 auto& cap = ioctl_rtentry_args.back();
51 cap.first = std::string(arg->rt_dev);
52 cap.second.rt_dev = (char*)cap.first.c_str();
53 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090054 return 0;
55}
56
57} // namespace
58
Garrick Evans8e8e3472020-01-23 14:03:50 +090059class MockProcessRunner : public MinijailedProcessRunner {
60 public:
61 MockProcessRunner() = default;
62 ~MockProcessRunner() = default;
63
Garrick Evans2470caa2020-03-04 14:15:41 +090064 MOCK_METHOD1(WriteSentinelToContainer, int(pid_t pid));
Garrick Evans8e8e3472020-01-23 14:03:50 +090065 MOCK_METHOD3(brctl,
66 int(const std::string& cmd,
67 const std::vector<std::string>& argv,
68 bool log_failures));
69 MOCK_METHOD4(chown,
70 int(const std::string& uid,
71 const std::string& gid,
72 const std::string& file,
73 bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +090074 MOCK_METHOD4(ip,
75 int(const std::string& obj,
76 const std::string& cmd,
77 const std::vector<std::string>& args,
78 bool log_failures));
79 MOCK_METHOD4(ip6,
80 int(const std::string& obj,
81 const std::string& cmd,
82 const std::vector<std::string>& args,
83 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090084 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090085 int(const std::string& table,
86 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090087 bool log_failures,
88 std::string* output));
89 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090090 int(const std::string& table,
91 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090092 bool log_failures,
93 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +090094 MOCK_METHOD2(modprobe_all,
95 int(const std::vector<std::string>& modules, bool log_failures));
96 MOCK_METHOD3(sysctl_w,
97 int(const std::string& key,
98 const std::string& value,
99 bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900100 MOCK_METHOD3(ip_netns_attach,
101 int(const std::string& netns_name,
102 pid_t netns_pid,
103 bool log_failures));
104 MOCK_METHOD2(ip_netns_delete,
105 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900106};
107
Hugo Benichid82d8832020-08-14 10:05:03 +0900108TEST(DatapathTest, IpFamily) {
109 EXPECT_EQ(IpFamily::Dual, IpFamily::IPv4 | IpFamily::IPv6);
110 EXPECT_EQ(IpFamily::Dual & IpFamily::IPv4, IpFamily::IPv4);
111 EXPECT_EQ(IpFamily::Dual & IpFamily::IPv6, IpFamily::IPv6);
112 EXPECT_NE(IpFamily::Dual, IpFamily::IPv4);
113 EXPECT_NE(IpFamily::Dual, IpFamily::IPv6);
114 EXPECT_NE(IpFamily::IPv4, IpFamily::IPv6);
115}
116
Hugo Benichibf811c62020-09-07 17:30:45 +0900117TEST(DatapathTest, Start) {
118 MockProcessRunner runner;
119 MockFirewall firewall;
120 // Asserts for sysctl modifications
121 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("1"), true));
122 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
123 StrEq("32768 47103"), true));
124 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
125 StrEq("1"), true));
Hugo Benichi561fae42021-01-22 15:28:40 +0900126 // Asserts for SNAT rules.
Hugo Benichibf811c62020-09-07 17:30:45 +0900127 EXPECT_CALL(
128 runner,
129 iptables(StrEq("filter"),
130 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
131 "state", "--state", "INVALID", "-j", "DROP", "-w"),
132 true, nullptr));
133 EXPECT_CALL(runner,
Hugo Benichibf811c62020-09-07 17:30:45 +0900134 iptables(StrEq("nat"),
135 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
136 "1/1", "-j", "MASQUERADE", "-w"),
137 true, nullptr));
138 // Asserts for AddForwardEstablishedRule
139 EXPECT_CALL(runner,
140 iptables(StrEq("filter"),
141 ElementsAre("-A", "FORWARD", "-m", "state", "--state",
142 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
143 true, nullptr));
144 // Asserts for AddSourceIPv4DropRule() calls.
145 EXPECT_CALL(runner,
146 iptables(StrEq("filter"),
147 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
148 "100.115.92.0/23", "-j", "DROP", "-w"),
149 true, nullptr));
150 EXPECT_CALL(runner,
151 iptables(StrEq("filter"),
152 ElementsAre("-I", "OUTPUT", "-o", "wlan+", "-s",
153 "100.115.92.0/23", "-j", "DROP", "-w"),
154 true, nullptr));
155 EXPECT_CALL(runner,
156 iptables(StrEq("filter"),
157 ElementsAre("-I", "OUTPUT", "-o", "mlan+", "-s",
158 "100.115.92.0/23", "-j", "DROP", "-w"),
159 true, nullptr));
160 EXPECT_CALL(runner,
161 iptables(StrEq("filter"),
162 ElementsAre("-I", "OUTPUT", "-o", "usb+", "-s",
163 "100.115.92.0/23", "-j", "DROP", "-w"),
164 true, nullptr));
165 EXPECT_CALL(runner,
166 iptables(StrEq("filter"),
167 ElementsAre("-I", "OUTPUT", "-o", "wwan+", "-s",
168 "100.115.92.0/23", "-j", "DROP", "-w"),
169 true, nullptr));
170 EXPECT_CALL(runner,
171 iptables(StrEq("filter"),
172 ElementsAre("-I", "OUTPUT", "-o", "rmnet+", "-s",
173 "100.115.92.0/23", "-j", "DROP", "-w"),
174 true, nullptr));
175 // Asserts for AddOutboundIPv4SNATMark("vmtap+")
176 EXPECT_CALL(runner,
177 iptables(StrEq("mangle"),
178 ElementsAre("-A", "PREROUTING", "-i", "vmtap+", "-j",
179 "MARK", "--set-mark", "1/1", "-w"),
180 true, nullptr));
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900181 // Asserts for OUTPUT ndp connmark bypass rule
182 EXPECT_CALL(
183 runner,
184 ip6tables(StrEq("mangle"),
Hugo Benichi52a64992021-01-28 17:47:33 +0900185 ElementsAre("-I", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900186 "router-solicitation", "-j", "ACCEPT", "-w"),
187 true, nullptr));
188 EXPECT_CALL(
189 runner,
190 ip6tables(StrEq("mangle"),
Hugo Benichi52a64992021-01-28 17:47:33 +0900191 ElementsAre("-I", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900192 "router-advertisement", "-j", "ACCEPT", "-w"),
193 true, nullptr));
194 EXPECT_CALL(
195 runner,
196 ip6tables(StrEq("mangle"),
Hugo Benichi52a64992021-01-28 17:47:33 +0900197 ElementsAre("-I", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900198 "neighbour-solicitation", "-j", "ACCEPT", "-w"),
199 true, nullptr));
200 EXPECT_CALL(
201 runner,
202 ip6tables(StrEq("mangle"),
Hugo Benichi52a64992021-01-28 17:47:33 +0900203 ElementsAre("-I", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900204 "neighbour-advertisement", "-j", "ACCEPT", "-w"),
205 true, nullptr));
Hugo Benichi52a64992021-01-28 17:47:33 +0900206 EXPECT_CALL(runner,
207 ip6tables(StrEq("mangle"),
208 ElementsAre("-I", "check_routing_mark", "-p", "icmpv6",
209 "--icmpv6-type", "router-solicitation",
210 "-j", "RETURN", "-w"),
211 true, nullptr));
212 EXPECT_CALL(runner,
213 ip6tables(StrEq("mangle"),
214 ElementsAre("-I", "check_routing_mark", "-p", "icmpv6",
215 "--icmpv6-type", "router-advertisement",
216 "-j", "RETURN", "-w"),
217 true, nullptr));
218 EXPECT_CALL(runner,
219 ip6tables(StrEq("mangle"),
220 ElementsAre("-I", "check_routing_mark", "-p", "icmpv6",
221 "--icmpv6-type", "neighbour-solicitation",
222 "-j", "RETURN", "-w"),
223 true, nullptr));
224 EXPECT_CALL(runner,
225 ip6tables(StrEq("mangle"),
226 ElementsAre("-I", "check_routing_mark", "-p", "icmpv6",
227 "--icmpv6-type", "neighbour-advertisement",
228 "-j", "RETURN", "-w"),
229 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900230 // Asserts for OUTPUT CONNMARK restore rule
231 EXPECT_CALL(runner, iptables(StrEq("mangle"),
232 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
233 "--restore-mark", "--mask",
234 "0xffff0000", "-w"),
235 true, nullptr));
236 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
237 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
238 "--restore-mark", "--mask",
239 "0xffff0000", "-w"),
240 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900241 // Asserts for apply_local_source_mark chain
242 EXPECT_CALL(runner,
243 iptables(StrEq("mangle"),
244 ElementsAre("-N", "apply_local_source_mark", "-w"), true,
245 nullptr));
246 EXPECT_CALL(runner,
247 iptables(StrEq("mangle"),
248 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
249 nullptr));
250 EXPECT_CALL(runner, iptables(StrEq("mangle"),
251 ElementsAre("-A", "OUTPUT", "-j",
252 "apply_local_source_mark", "-w"),
253 true, nullptr));
254 EXPECT_CALL(
255 runner,
256 iptables(StrEq("mangle"),
257 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
258 "--uid-owner", "chronos", "-j", "MARK", "--set-mark",
259 "0x00008100/0x0000ff00", "-w"),
260 true, nullptr));
261 EXPECT_CALL(runner, iptables(StrEq("mangle"),
262 ElementsAre("-A", "apply_local_source_mark",
263 "-m", "owner", "--uid-owner",
264 "debugd", "-j", "MARK", "--set-mark",
265 "0x00008200/0x0000ff00", "-w"),
266 true, nullptr));
267 EXPECT_CALL(runner,
268 iptables(StrEq("mangle"),
269 ElementsAre("-A", "apply_local_source_mark", "-m",
270 "owner", "--uid-owner", "cups", "-j", "MARK",
271 "--set-mark", "0x00008200/0x0000ff00", "-w"),
272 true, nullptr));
273 EXPECT_CALL(
274 runner,
275 iptables(StrEq("mangle"),
276 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi9c5516b2021-01-29 09:26:21 +0900277 "--uid-owner", "lpadmin", "-j", "MARK", "--set-mark",
278 "0x00008200/0x0000ff00", "-w"),
279 true, nullptr));
280 EXPECT_CALL(
281 runner,
282 iptables(StrEq("mangle"),
283 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900284 "--uid-owner", "kerberosd", "-j", "MARK",
285 "--set-mark", "0x00008400/0x0000ff00", "-w"),
286 true, nullptr));
287 EXPECT_CALL(
288 runner,
289 iptables(StrEq("mangle"),
290 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
291 "--uid-owner", "kerberosd-exec", "-j", "MARK",
292 "--set-mark", "0x00008400/0x0000ff00", "-w"),
293 true, nullptr));
294 EXPECT_CALL(
295 runner,
296 iptables(StrEq("mangle"),
297 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
298 "--uid-owner", "tlsdate", "-j", "MARK", "--set-mark",
299 "0x00008400/0x0000ff00", "-w"),
300 true, nullptr));
301 EXPECT_CALL(
302 runner,
303 iptables(StrEq("mangle"),
304 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
305 "--uid-owner", "pluginvm", "-j", "MARK",
306 "--set-mark", "0x00008200/0x0000ff00", "-w"),
307 true, nullptr));
308 EXPECT_CALL(
309 runner,
310 iptables(StrEq("mangle"),
311 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
312 "--uid-owner", "fuse-smbfs", "-j", "MARK",
313 "--set-mark", "0x00008400/0x0000ff00", "-w"),
314 true, nullptr));
315 EXPECT_CALL(
316 runner,
317 iptables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900318 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
319 "--cgroup", "0x00010001", "-j", "MARK", "--set-mark",
320 "0x00000300/0x0000ff00", "-w"),
321 true, nullptr));
322 EXPECT_CALL(
323 runner,
324 iptables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900325 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
326 "--mark", "0x0/0x00003f00", "-j", "MARK",
327 "--set-mark", "0x00000400/0x00003f00", "-w"),
328 true, nullptr));
329 EXPECT_CALL(runner,
330 ip6tables(StrEq("mangle"),
331 ElementsAre("-N", "apply_local_source_mark", "-w"),
332 true, nullptr));
333 EXPECT_CALL(runner,
334 ip6tables(StrEq("mangle"),
335 ElementsAre("-F", "apply_local_source_mark", "-w"),
336 true, nullptr));
337 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
338 ElementsAre("-A", "OUTPUT", "-j",
339 "apply_local_source_mark", "-w"),
340 true, nullptr));
341 EXPECT_CALL(
342 runner,
343 ip6tables(StrEq("mangle"),
344 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
345 "--uid-owner", "debugd", "-j", "MARK", "--set-mark",
346 "0x00008200/0x0000ff00", "-w"),
347 true, nullptr));
348 EXPECT_CALL(
349 runner,
350 ip6tables(StrEq("mangle"),
351 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
352 "--uid-owner", "chronos", "-j", "MARK",
353 "--set-mark", "0x00008100/0x0000ff00", "-w"),
354 true, nullptr));
355 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
356 ElementsAre("-A", "apply_local_source_mark",
357 "-m", "owner", "--uid-owner",
358 "cups", "-j", "MARK", "--set-mark",
359 "0x00008200/0x0000ff00", "-w"),
360 true, nullptr));
361 EXPECT_CALL(
362 runner,
363 ip6tables(StrEq("mangle"),
364 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi9c5516b2021-01-29 09:26:21 +0900365 "--uid-owner", "lpadmin", "-j", "MARK",
366 "--set-mark", "0x00008200/0x0000ff00", "-w"),
367 true, nullptr));
368 EXPECT_CALL(
369 runner,
370 ip6tables(StrEq("mangle"),
371 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900372 "--uid-owner", "kerberosd", "-j", "MARK",
373 "--set-mark", "0x00008400/0x0000ff00", "-w"),
374 true, nullptr));
375 EXPECT_CALL(
376 runner,
377 ip6tables(StrEq("mangle"),
378 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
379 "--uid-owner", "kerberosd-exec", "-j", "MARK",
380 "--set-mark", "0x00008400/0x0000ff00", "-w"),
381 true, nullptr));
382 EXPECT_CALL(
383 runner,
384 ip6tables(StrEq("mangle"),
385 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
386 "--uid-owner", "tlsdate", "-j", "MARK",
387 "--set-mark", "0x00008400/0x0000ff00", "-w"),
388 true, nullptr));
389 EXPECT_CALL(
390 runner,
391 ip6tables(StrEq("mangle"),
392 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
393 "--uid-owner", "pluginvm", "-j", "MARK",
394 "--set-mark", "0x00008200/0x0000ff00", "-w"),
395 true, nullptr));
396 EXPECT_CALL(
397 runner,
398 ip6tables(StrEq("mangle"),
399 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
400 "--uid-owner", "fuse-smbfs", "-j", "MARK",
401 "--set-mark", "0x00008400/0x0000ff00", "-w"),
402 true, nullptr));
403 EXPECT_CALL(
404 runner,
405 ip6tables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900406 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
407 "--cgroup", "0x00010001", "-j", "MARK",
408 "--set-mark", "0x00000300/0x0000ff00", "-w"),
409 true, nullptr));
410 EXPECT_CALL(
411 runner,
412 ip6tables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900413 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
414 "--mark", "0x0/0x00003f00", "-j", "MARK",
415 "--set-mark", "0x00000400/0x00003f00", "-w"),
416 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900417 // Asserts for apply_vpn_mark chain
418 EXPECT_CALL(runner, iptables(StrEq("mangle"),
419 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
420 nullptr));
421 EXPECT_CALL(runner, iptables(StrEq("mangle"),
422 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
423 nullptr));
424 EXPECT_CALL(runner, iptables(StrEq("mangle"),
425 ElementsAre("-A", "OUTPUT", "-m", "mark",
426 "--mark", "0x00008000/0x0000c000",
427 "-j", "apply_vpn_mark", "-w"),
428 true, nullptr));
429 EXPECT_CALL(runner, iptables(StrEq("mangle"),
430 ElementsAre("-A", "apply_vpn_mark", "-m", "mark",
431 "!", "--mark", "0x0/0xffff0000",
432 "-j", "ACCEPT", "-w"),
433 true, nullptr));
434 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
435 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
436 nullptr));
437 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
438 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
439 nullptr));
440 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
441 ElementsAre("-A", "OUTPUT", "-m", "mark",
442 "--mark", "0x00008000/0x0000c000",
443 "-j", "apply_vpn_mark", "-w"),
444 true, nullptr));
445 EXPECT_CALL(
446 runner,
447 ip6tables(StrEq("mangle"),
448 ElementsAre("-A", "apply_vpn_mark", "-m", "mark", "!", "--mark",
449 "0x0/0xffff0000", "-j", "ACCEPT", "-w"),
450 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900451 // Asserts for check_routing_mark chain
452 EXPECT_CALL(runner, iptables(StrEq("mangle"),
453 ElementsAre("-N", "check_routing_mark", "-w"),
454 true, nullptr));
455 EXPECT_CALL(runner, iptables(StrEq("mangle"),
456 ElementsAre("-F", "check_routing_mark", "-w"),
457 true, nullptr));
458 EXPECT_CALL(runner, iptables(StrEq("mangle"),
459 ElementsAre("-A", "POSTROUTING", "-j",
460 "CONNMARK", "--restore-mark",
461 "--mask", "0xffff0000", "-w"),
462 true, nullptr));
463 EXPECT_CALL(runner, iptables(StrEq("mangle"),
464 ElementsAre("-A", "POSTROUTING", "-m", "mark",
465 "!", "--mark", "0x0/0xffff0000",
466 "-j", "check_routing_mark", "-w"),
467 true, nullptr));
468 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
469 ElementsAre("-N", "check_routing_mark", "-w"),
470 true, nullptr));
471 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
472 ElementsAre("-F", "check_routing_mark", "-w"),
473 true, nullptr));
474 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
475 ElementsAre("-A", "POSTROUTING", "-j",
476 "CONNMARK", "--restore-mark",
477 "--mask", "0xffff0000", "-w"),
478 true, nullptr));
479 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
480 ElementsAre("-A", "POSTROUTING", "-m", "mark",
481 "!", "--mark", "0x0/0xffff0000",
482 "-j", "check_routing_mark", "-w"),
483 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900484
485 Datapath datapath(&runner, &firewall);
486 datapath.Start();
487}
488
489TEST(DatapathTest, Stop) {
490 MockProcessRunner runner;
491 MockFirewall firewall;
492 // Asserts for sysctl modifications
493 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
494 StrEq("32768 61000"), true));
495 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
496 StrEq("0"), true));
497 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
498 // Asserts for RemoveOutboundIPv4SNATMark("vmtap+")
499 EXPECT_CALL(runner,
500 iptables(StrEq("mangle"),
501 ElementsAre("-D", "PREROUTING", "-i", "vmtap+", "-j",
502 "MARK", "--set-mark", "1/1", "-w"),
503 true, nullptr));
504 // Asserts for RemoveForwardEstablishedRule
505 EXPECT_CALL(runner,
506 iptables(StrEq("filter"),
507 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
508 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
509 true, nullptr));
Hugo Benichi561fae42021-01-22 15:28:40 +0900510 // Asserts for SNAT rules.
Hugo Benichibf811c62020-09-07 17:30:45 +0900511 EXPECT_CALL(
512 runner,
513 iptables(StrEq("filter"),
514 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
515 "state", "--state", "INVALID", "-j", "DROP", "-w"),
516 true, nullptr));
517 EXPECT_CALL(runner,
Hugo Benichibf811c62020-09-07 17:30:45 +0900518 iptables(StrEq("nat"),
519 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
520 "1/1", "-j", "MASQUERADE", "-w"),
521 true, nullptr));
522 // Asserts for RemoveSourceIPv4DropRule() calls.
523 EXPECT_CALL(runner,
524 iptables(StrEq("filter"),
525 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
526 "100.115.92.0/23", "-j", "DROP", "-w"),
527 true, nullptr));
528 EXPECT_CALL(runner,
529 iptables(StrEq("filter"),
530 ElementsAre("-D", "OUTPUT", "-o", "wlan+", "-s",
531 "100.115.92.0/23", "-j", "DROP", "-w"),
532 true, nullptr));
533 EXPECT_CALL(runner,
534 iptables(StrEq("filter"),
535 ElementsAre("-D", "OUTPUT", "-o", "mlan+", "-s",
536 "100.115.92.0/23", "-j", "DROP", "-w"),
537 true, nullptr));
538 EXPECT_CALL(runner,
539 iptables(StrEq("filter"),
540 ElementsAre("-D", "OUTPUT", "-o", "usb+", "-s",
541 "100.115.92.0/23", "-j", "DROP", "-w"),
542 true, nullptr));
543 EXPECT_CALL(runner,
544 iptables(StrEq("filter"),
545 ElementsAre("-D", "OUTPUT", "-o", "wwan+", "-s",
546 "100.115.92.0/23", "-j", "DROP", "-w"),
547 true, nullptr));
548 EXPECT_CALL(runner,
549 iptables(StrEq("filter"),
550 ElementsAre("-D", "OUTPUT", "-o", "rmnet+", "-s",
551 "100.115.92.0/23", "-j", "DROP", "-w"),
552 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900553 // Asserts for apply_local_source_mark chain
554 EXPECT_CALL(runner, iptables(StrEq("mangle"),
555 ElementsAre("-D", "OUTPUT", "-j",
556 "apply_local_source_mark", "-w"),
557 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900558 // Asserts for OUTPUT CONNMARK restore rule
559 EXPECT_CALL(runner, iptables(StrEq("mangle"),
560 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
561 "--restore-mark", "--mask",
562 "0xffff0000", "-w"),
563 true, nullptr));
564 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
565 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
566 "--restore-mark", "--mask",
567 "0xffff0000", "-w"),
568 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900569 EXPECT_CALL(runner,
570 iptables(StrEq("mangle"),
571 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
572 nullptr));
573 EXPECT_CALL(runner,
574 iptables(StrEq("mangle"),
575 ElementsAre("-X", "apply_local_source_mark", "-w"), true,
576 nullptr));
577 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
578 ElementsAre("-D", "OUTPUT", "-j",
579 "apply_local_source_mark", "-w"),
580 true, nullptr));
581 EXPECT_CALL(runner,
582 ip6tables(StrEq("mangle"),
583 ElementsAre("-F", "apply_local_source_mark", "-w"),
584 true, nullptr));
585 EXPECT_CALL(runner,
586 ip6tables(StrEq("mangle"),
587 ElementsAre("-X", "apply_local_source_mark", "-w"),
588 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900589 // Asserts for apply_vpn_mark chain
590 EXPECT_CALL(runner, iptables(StrEq("mangle"),
591 ElementsAre("-D", "OUTPUT", "-m", "mark",
592 "--mark", "0x00008000/0x0000c000",
593 "-j", "apply_vpn_mark", "-w"),
594 true, nullptr));
595 EXPECT_CALL(runner, iptables(StrEq("mangle"),
596 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
597 nullptr));
598 EXPECT_CALL(runner, iptables(StrEq("mangle"),
599 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
600 nullptr));
601 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
602 ElementsAre("-D", "OUTPUT", "-m", "mark",
603 "--mark", "0x00008000/0x0000c000",
604 "-j", "apply_vpn_mark", "-w"),
605 true, nullptr));
606 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
607 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
608 nullptr));
609 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
610 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
611 nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900612 // Asserts for check_routing_mark chain
613 EXPECT_CALL(runner, iptables(StrEq("mangle"),
614 ElementsAre("-D", "POSTROUTING", "-j",
615 "CONNMARK", "--restore-mark",
616 "--mask", "0xffff0000", "-w"),
617 true, nullptr));
618 EXPECT_CALL(runner, iptables(StrEq("mangle"),
619 ElementsAre("-D", "POSTROUTING", "-m", "mark",
620 "!", "--mark", "0x0/0xffff0000",
621 "-j", "check_routing_mark", "-w"),
622 true, nullptr));
623 EXPECT_CALL(runner, iptables(StrEq("mangle"),
624 ElementsAre("-F", "check_routing_mark", "-w"),
625 true, nullptr));
626 EXPECT_CALL(runner, iptables(StrEq("mangle"),
627 ElementsAre("-X", "check_routing_mark", "-w"),
628 true, nullptr));
629 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
630 ElementsAre("-D", "POSTROUTING", "-j",
631 "CONNMARK", "--restore-mark",
632 "--mask", "0xffff0000", "-w"),
633 true, nullptr));
634 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
635 ElementsAre("-D", "POSTROUTING", "-m", "mark",
636 "!", "--mark", "0x0/0xffff0000",
637 "-j", "check_routing_mark", "-w"),
638 true, nullptr));
639 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
640 ElementsAre("-F", "check_routing_mark", "-w"),
641 true, nullptr));
642 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
643 ElementsAre("-X", "check_routing_mark", "-w"),
644 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900645
646 Datapath datapath(&runner, &firewall);
647 datapath.Stop();
648}
649
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900650TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900651 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900652 MockFirewall firewall;
653 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900654 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900655 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900656 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900657 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900658 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900659 std::vector<ioctl_req_t> expected = {
660 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
661 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900662 EXPECT_EQ(ioctl_reqs, expected);
663 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900664 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900665}
666
667TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900668 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900669 MockFirewall firewall;
670 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900671 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900672 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900673 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900674 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900675 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900676 std::vector<ioctl_req_t> expected = {
677 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
678 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900679 EXPECT_EQ(ioctl_reqs, expected);
680 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900681 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900682}
683
Garrick Evans621ed262019-11-13 12:28:43 +0900684TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900685 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900686 MockFirewall firewall;
687 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900688 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900689 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900690 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
691 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900692 EXPECT_EQ(ioctl_reqs, expected);
693 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900694 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900695}
696
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900697TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900698 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900699 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900700 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
701 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900702 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900703 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900704}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900705
Hugo Benichi33860d72020-07-09 16:34:01 +0900706TEST(DatapathTest, NetnsAttachName) {
707 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900708 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900709 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
710 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900711 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900712 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
713}
714
715TEST(DatapathTest, NetnsDeleteName) {
716 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900717 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900718 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900719 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900720 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
721}
722
Garrick Evans8a949dc2019-07-18 16:17:53 +0900723TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900724 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900725 MockFirewall firewall;
726 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900727 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900728 EXPECT_CALL(
729 runner,
730 ip(StrEq("addr"), StrEq("add"),
731 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900732 EXPECT_CALL(runner,
733 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900734 EXPECT_CALL(runner, iptables(StrEq("mangle"),
735 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900736 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900737 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900738 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900739}
740
Hugo Benichi76675592020-04-08 14:29:57 +0900741TEST(DatapathTest, ConnectVethPair) {
742 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900743 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900744 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
745 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900746 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900747 true));
748 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
749 ElementsAre("100.115.92.169/30", "brd",
750 "100.115.92.171", "dev", "peer_foo"),
751 true))
752 .WillOnce(Return(0));
753 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
754 ElementsAre("dev", "peer_foo", "up", "addr",
755 "01:02:03:04:05:06", "multicast", "on"),
756 true))
757 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900758 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
759 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900760 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900761 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
762 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900763 Ipv4Addr(100, 115, 92, 169), 30, true));
764}
765
Garrick Evans2470caa2020-03-04 14:15:41 +0900766TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900767 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900768 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900769 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
770 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900771 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900772 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900773 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900774 EXPECT_TRUE(
775 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900776}
777
778TEST(DatapathTest, ToggleInterface) {
779 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900780 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900781 EXPECT_CALL(runner,
782 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900783 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900784 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900785 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900786 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
787 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
788}
789
790TEST(DatapathTest, ConfigureInterface) {
791 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900792 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900793 EXPECT_CALL(
794 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900795 ip(StrEq("addr"), StrEq("add"),
796 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
797 .WillOnce(Return(0));
798 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
799 ElementsAre("dev", "foo", "up", "addr",
800 "02:02:02:02:02:02", "multicast", "on"),
801 true))
802 .WillOnce(Return(0));
803
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900804 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900805 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
806 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
807 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900808}
809
810TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900811 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900812 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900813 EXPECT_CALL(runner,
814 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900815 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900816 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900817}
818
Garrick Evans8a949dc2019-07-18 16:17:53 +0900819TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900820 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900821 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900822 EXPECT_CALL(runner, iptables(StrEq("mangle"),
823 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900824 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900825 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900826 EXPECT_CALL(runner,
827 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900828 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900829 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900830 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900831}
832
Hugo Benichi321f23b2020-09-25 15:42:05 +0900833TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
834 MockProcessRunner runner;
835 MockFirewall firewall;
836 EXPECT_CALL(runner,
837 iptables(StrEq("filter"),
838 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
839 "100.115.92.0/24", "-j", "DROP", "-w"),
840 true, nullptr));
841 EXPECT_CALL(runner,
842 iptables(StrEq("filter"),
843 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
844 "100.115.92.0/24", "-j", "DROP", "-w"),
845 true, nullptr));
846 Datapath datapath(&runner, &firewall);
847 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
848 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
849}
850
Hugo Benichi7c342672020-09-08 09:18:14 +0900851TEST(DatapathTest, StartRoutingNamespace) {
852 MockProcessRunner runner;
853 MockFirewall firewall;
854 MacAddress mac = {1, 2, 3, 4, 5, 6};
855
856 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
857 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
858 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
859 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
860 "veth0", "netns", "netns_foo"),
861 true));
862 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
863 ElementsAre("100.115.92.130/30", "brd",
864 "100.115.92.131", "dev", "veth0"),
865 true))
866 .WillOnce(Return(0));
867 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
868 ElementsAre("dev", "veth0", "up", "addr",
869 "01:02:03:04:05:06", "multicast", "off"),
870 true))
871 .WillOnce(Return(0));
872 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
873 ElementsAre("arc_ns0", "up"), true));
874 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
875 ElementsAre("100.115.92.129/30", "brd",
876 "100.115.92.131", "dev", "arc_ns0"),
877 true))
878 .WillOnce(Return(0));
879 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
880 ElementsAre("dev", "arc_ns0", "up", "addr",
881 "01:02:03:04:05:06", "multicast", "off"),
882 true))
883 .WillOnce(Return(0));
884 EXPECT_CALL(runner, iptables(StrEq("filter"),
885 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
886 "-j", "ACCEPT", "-w"),
887 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900888 EXPECT_CALL(runner, iptables(StrEq("filter"),
889 ElementsAre("-A", "FORWARD", "-i", "arc_ns0",
890 "-j", "ACCEPT", "-w"),
891 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900892 EXPECT_CALL(runner,
893 iptables(StrEq("mangle"),
894 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
895 "MARK", "--set-mark", "1/1", "-w"),
896 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900897 EXPECT_CALL(runner, iptables(StrEq("mangle"),
898 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
899 "-j", "MARK", "--set-mark",
900 "0x00000200/0x00003f00", "-w"),
901 true, nullptr));
902 EXPECT_CALL(runner, iptables(StrEq("mangle"),
903 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
904 "-j", "CONNMARK", "--restore-mark",
905 "--mask", "0xffff0000", "-w"),
906 true, nullptr));
907 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
908 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
909 "-j", "MARK", "--set-mark",
910 "0x00000200/0x00003f00", "-w"),
911 true, nullptr));
912 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
913 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
914 "-j", "CONNMARK", "--restore-mark",
915 "--mask", "0xffff0000", "-w"),
916 true, nullptr));
917 EXPECT_CALL(runner, iptables(StrEq("mangle"),
918 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
919 "-j", "apply_vpn_mark", "-w"),
920 true, nullptr));
921 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
922 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
923 "-j", "apply_vpn_mark", "-w"),
924 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900925
Hugo Benichifcf81022020-12-04 11:01:37 +0900926 ConnectedNamespace nsinfo = {};
927 nsinfo.pid = kTestPID;
928 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900929 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900930 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900931 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900932 nsinfo.host_ifname = "arc_ns0";
933 nsinfo.peer_ifname = "veth0";
934 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
935 base::DoNothing());
936 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900937 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900938 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900939 ioctl_reqs.clear();
940 ioctl_rtentry_args.clear();
941}
942
943TEST(DatapathTest, StopRoutingNamespace) {
944 MockProcessRunner runner;
945 MockFirewall firewall;
946
947 EXPECT_CALL(runner, iptables(StrEq("filter"),
948 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
949 "-j", "ACCEPT", "-w"),
950 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900951 EXPECT_CALL(runner, iptables(StrEq("filter"),
952 ElementsAre("-D", "FORWARD", "-i", "arc_ns0",
953 "-j", "ACCEPT", "-w"),
954 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900955 EXPECT_CALL(runner,
956 iptables(StrEq("mangle"),
957 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
958 "MARK", "--set-mark", "1/1", "-w"),
959 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900960 EXPECT_CALL(runner, iptables(StrEq("mangle"),
961 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
962 "-j", "MARK", "--set-mark",
963 "0x00000200/0x00003f00", "-w"),
964 true, nullptr));
965 EXPECT_CALL(runner, iptables(StrEq("mangle"),
966 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
967 "-j", "CONNMARK", "--restore-mark",
968 "--mask", "0xffff0000", "-w"),
969 true, nullptr));
970 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
971 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
972 "-j", "MARK", "--set-mark",
973 "0x00000200/0x00003f00", "-w"),
974 true, nullptr));
975 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
976 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
977 "-j", "CONNMARK", "--restore-mark",
978 "--mask", "0xffff0000", "-w"),
979 true, nullptr));
980 EXPECT_CALL(runner, iptables(StrEq("mangle"),
981 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
982 "-j", "apply_vpn_mark", "-w"),
983 true, nullptr));
984 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
985 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
986 "-j", "apply_vpn_mark", "-w"),
987 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900988 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
989 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
990 false));
991
Hugo Benichifcf81022020-12-04 11:01:37 +0900992 ConnectedNamespace nsinfo = {};
993 nsinfo.pid = kTestPID;
994 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900995 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900996 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900997 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900998 nsinfo.host_ifname = "arc_ns0";
999 nsinfo.peer_ifname = "veth0";
1000 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
1001 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +09001002 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +09001003 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +09001004}
1005
Hugo Benichi8d622b52020-08-13 15:24:12 +09001006TEST(DatapathTest, StartRoutingDevice_Arc) {
1007 MockProcessRunner runner;
1008 MockFirewall firewall;
1009 EXPECT_CALL(runner, iptables(StrEq("nat"),
1010 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1011 "-m", "socket", "--nowildcard", "-j",
1012 "ACCEPT", "-w"),
1013 true, nullptr));
1014 EXPECT_CALL(runner, iptables(StrEq("nat"),
1015 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1016 "-p", "tcp", "-j", "DNAT",
1017 "--to-destination", "1.2.3.4", "-w"),
1018 true, nullptr));
1019 EXPECT_CALL(runner, iptables(StrEq("nat"),
1020 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1021 "-p", "udp", "-j", "DNAT",
1022 "--to-destination", "1.2.3.4", "-w"),
1023 true, nullptr));
1024 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001025 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1026 "arc_eth0", "-j", "ACCEPT", "-w"),
1027 true, nullptr));
1028 EXPECT_CALL(runner, iptables(StrEq("filter"),
1029 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1030 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001031 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001032 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1033 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1034 "-j", "MARK", "--set-mark",
1035 "0x00002000/0x00003f00", "-w"),
1036 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001037 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1038 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1039 "-j", "MARK", "--set-mark",
1040 "0x03ea0000/0xffff0000", "-w"),
1041 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001042 EXPECT_CALL(
1043 runner,
1044 ip6tables(StrEq("mangle"),
1045 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1046 "--set-mark", "0x00002000/0x00003f00", "-w"),
1047 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001048 EXPECT_CALL(
1049 runner,
1050 ip6tables(StrEq("mangle"),
1051 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1052 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1053 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001054
1055 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001056 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001057 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001058 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001059}
1060
1061TEST(DatapathTest, StartRoutingDevice_CrosVM) {
1062 MockProcessRunner runner;
1063 MockFirewall firewall;
1064 EXPECT_CALL(runner, iptables(StrEq("filter"),
1065 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
1066 "-j", "ACCEPT", "-w"),
1067 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001068 EXPECT_CALL(runner, iptables(StrEq("filter"),
1069 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
1070 "-j", "ACCEPT", "-w"),
1071 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001072 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1073 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1074 "-j", "MARK", "--set-mark",
1075 "0x00002100/0x00003f00", "-w"),
1076 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001077 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1078 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1079 "-j", "CONNMARK", "--restore-mark",
1080 "--mask", "0xffff0000", "-w"),
1081 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001082 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1083 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1084 "-j", "MARK", "--set-mark",
1085 "0x00002100/0x00003f00", "-w"),
1086 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001087 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1088 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1089 "-j", "CONNMARK", "--restore-mark",
1090 "--mask", "0xffff0000", "-w"),
1091 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001092 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1093 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1094 "-j", "apply_vpn_mark", "-w"),
1095 true, nullptr));
1096 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1097 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1098 "-j", "apply_vpn_mark", "-w"),
1099 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001100
1101 Datapath datapath(&runner, &firewall);
1102 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001103 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001104}
1105
1106TEST(DatapathTest, StopRoutingDevice_Arc) {
1107 MockProcessRunner runner;
1108 MockFirewall firewall;
1109 EXPECT_CALL(runner, iptables(StrEq("nat"),
1110 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1111 "-m", "socket", "--nowildcard", "-j",
1112 "ACCEPT", "-w"),
1113 true, nullptr));
1114 EXPECT_CALL(runner, iptables(StrEq("nat"),
1115 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1116 "-p", "tcp", "-j", "DNAT",
1117 "--to-destination", "1.2.3.4", "-w"),
1118 true, nullptr));
1119 EXPECT_CALL(runner, iptables(StrEq("nat"),
1120 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1121 "-p", "udp", "-j", "DNAT",
1122 "--to-destination", "1.2.3.4", "-w"),
1123 true, nullptr));
1124 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001125 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1126 "arc_eth0", "-j", "ACCEPT", "-w"),
1127 true, nullptr));
1128 EXPECT_CALL(runner, iptables(StrEq("filter"),
1129 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1130 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001131 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001132 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1133 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1134 "-j", "MARK", "--set-mark",
1135 "0x00002000/0x00003f00", "-w"),
1136 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001137 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1138 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1139 "-j", "MARK", "--set-mark",
1140 "0x03ea0000/0xffff0000", "-w"),
1141 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001142 EXPECT_CALL(
1143 runner,
1144 ip6tables(StrEq("mangle"),
1145 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1146 "--set-mark", "0x00002000/0x00003f00", "-w"),
1147 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001148 EXPECT_CALL(
1149 runner,
1150 ip6tables(StrEq("mangle"),
1151 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1152 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1153 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001154
1155 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001156 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001157 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001158 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001159}
1160
1161TEST(DatapathTest, StopRoutingDevice_CrosVM) {
1162 MockProcessRunner runner;
1163 MockFirewall firewall;
1164 EXPECT_CALL(runner, iptables(StrEq("filter"),
1165 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
1166 "-j", "ACCEPT", "-w"),
1167 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001168 EXPECT_CALL(runner, iptables(StrEq("filter"),
1169 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
1170 "-j", "ACCEPT", "-w"),
1171 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001172 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1173 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1174 "-j", "MARK", "--set-mark",
1175 "0x00002100/0x00003f00", "-w"),
1176 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001177 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1178 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1179 "-j", "CONNMARK", "--restore-mark",
1180 "--mask", "0xffff0000", "-w"),
1181 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001182 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1183 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1184 "-j", "MARK", "--set-mark",
1185 "0x00002100/0x00003f00", "-w"),
1186 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001187 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1188 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1189 "-j", "CONNMARK", "--restore-mark",
1190 "--mask", "0xffff0000", "-w"),
1191 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001192 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1193 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1194 "-j", "apply_vpn_mark", "-w"),
1195 true, nullptr));
1196 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1197 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1198 "-j", "apply_vpn_mark", "-w"),
1199 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001200
1201 Datapath datapath(&runner, &firewall);
1202 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001203 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001204}
1205
Hugo Benichid82d8832020-08-14 10:05:03 +09001206TEST(DatapathTest, StartStopIpForwarding) {
1207 struct {
1208 IpFamily family;
1209 std::string iif;
1210 std::string oif;
1211 std::vector<std::string> start_args;
1212 std::vector<std::string> stop_args;
1213 bool result;
1214 } testcases[] = {
1215 {IpFamily::IPv4, "", "", {}, {}, false},
1216 {IpFamily::NONE, "foo", "bar", {}, {}, false},
1217 {IpFamily::IPv4,
1218 "foo",
1219 "bar",
1220 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1221 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1222 true},
1223 {IpFamily::IPv4,
1224 "",
1225 "bar",
1226 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1227 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1228 true},
1229 {IpFamily::IPv4,
1230 "foo",
1231 "",
1232 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1233 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1234 true},
1235 {IpFamily::IPv6,
1236 "foo",
1237 "bar",
1238 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1239 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1240 true},
1241 {IpFamily::IPv6,
1242 "",
1243 "bar",
1244 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1245 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1246 true},
1247 {IpFamily::IPv6,
1248 "foo",
1249 "",
1250 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1251 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1252 true},
1253 {IpFamily::Dual,
1254 "foo",
1255 "bar",
1256 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1257 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1258 true},
1259 {IpFamily::Dual,
1260 "",
1261 "bar",
1262 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1263 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1264 true},
1265 {IpFamily::Dual,
1266 "foo",
1267 "",
1268 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1269 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1270 true},
1271 };
1272
1273 for (const auto& tt : testcases) {
1274 MockProcessRunner runner;
1275 MockFirewall firewall;
1276 if (tt.result) {
1277 if (tt.family & IpFamily::IPv4) {
1278 EXPECT_CALL(runner,
1279 iptables(StrEq("filter"), tt.start_args, true, nullptr))
1280 .WillOnce(Return(0));
1281 EXPECT_CALL(runner,
1282 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
1283 .WillOnce(Return(0));
1284 }
1285 if (tt.family & IpFamily::IPv6) {
1286 EXPECT_CALL(runner,
1287 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
1288 .WillOnce(Return(0));
1289 EXPECT_CALL(runner,
1290 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
1291 .WillOnce(Return(0));
1292 }
1293 }
1294 Datapath datapath(&runner, &firewall);
1295
1296 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
1297 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
1298 }
1299}
1300
Hugo Benichi76be34a2020-08-26 22:35:54 +09001301TEST(DatapathTest, StartStopConnectionPinning) {
1302 MockProcessRunner runner;
1303 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +09001304
1305 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001306 EXPECT_CALL(runner,
1307 iptables(StrEq("mangle"),
1308 ElementsAre("-A", "check_routing_mark", "-o", "eth0",
1309 "-m", "mark", "!", "--mark",
1310 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1311 true, nullptr));
1312 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1313 ElementsAre("-A", "check_routing_mark", "-o",
1314 "eth0", "-m", "mark", "!", "--mark",
1315 "0x03eb0000/0xffff0000", "-j",
1316 "DROP", "-w"),
1317 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001318 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1319 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1320 "-j", "CONNMARK", "--set-mark",
1321 "0x03eb0000/0xffff0000", "-w"),
1322 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001323 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1324 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1325 "-j", "CONNMARK", "--set-mark",
1326 "0x03eb0000/0xffff0000", "-w"),
1327 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001328 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1329 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1330 "-j", "CONNMARK", "--save-mark",
1331 "--mask", "0x00003f00", "-w"),
1332 true, nullptr));
1333 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1334 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1335 "-j", "CONNMARK", "--save-mark",
1336 "--mask", "0x00003f00", "-w"),
1337 true, nullptr));
1338 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1339 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1340 "-j", "CONNMARK", "--restore-mark",
1341 "--mask", "0x00003f00", "-w"),
1342 true, nullptr));
1343 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1344 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1345 "-j", "CONNMARK", "--restore-mark",
1346 "--mask", "0x00003f00", "-w"),
1347 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +09001348
Hugo Benichi1af52392020-11-27 18:09:32 +09001349 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001350 EXPECT_CALL(runner,
1351 iptables(StrEq("mangle"),
1352 ElementsAre("-D", "check_routing_mark", "-o", "eth0",
1353 "-m", "mark", "!", "--mark",
1354 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1355 true, nullptr));
1356 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1357 ElementsAre("-D", "check_routing_mark", "-o",
1358 "eth0", "-m", "mark", "!", "--mark",
1359 "0x03eb0000/0xffff0000", "-j",
1360 "DROP", "-w"),
1361 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001362 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1363 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1364 "-j", "CONNMARK", "--set-mark",
1365 "0x03eb0000/0xffff0000", "-w"),
1366 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001367 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1368 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1369 "-j", "CONNMARK", "--set-mark",
1370 "0x03eb0000/0xffff0000", "-w"),
1371 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001372 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1373 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1374 "-j", "CONNMARK", "--save-mark",
1375 "--mask", "0x00003f00", "-w"),
1376 true, nullptr));
1377 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1378 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1379 "-j", "CONNMARK", "--save-mark",
1380 "--mask", "0x00003f00", "-w"),
1381 true, nullptr));
1382 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1383 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1384 "-j", "CONNMARK", "--restore-mark",
1385 "--mask", "0x00003f00", "-w"),
1386 true, nullptr));
1387 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1388 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1389 "-j", "CONNMARK", "--restore-mark",
1390 "--mask", "0x00003f00", "-w"),
1391 true, nullptr));
1392
Hugo Benichi76be34a2020-08-26 22:35:54 +09001393 Datapath datapath(&runner, &firewall);
1394 datapath.SetIfnameIndex("eth0", 3);
1395 datapath.StartConnectionPinning("eth0");
1396 datapath.StopConnectionPinning("eth0");
1397}
1398
Hugo Benichibfc49112020-12-14 12:54:44 +09001399TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +09001400 MockProcessRunner runner;
1401 MockFirewall firewall;
1402
1403 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001404 EXPECT_CALL(runner,
1405 iptables(StrEq("mangle"),
1406 ElementsAre("-A", "check_routing_mark", "-o", "arcbr0",
1407 "-m", "mark", "!", "--mark",
1408 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1409 true, nullptr));
1410 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1411 ElementsAre("-A", "check_routing_mark", "-o",
1412 "arcbr0", "-m", "mark", "!",
1413 "--mark", "0x03ed0000/0xffff0000",
1414 "-j", "DROP", "-w"),
1415 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001416 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1417 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1418 "-j", "CONNMARK", "--set-mark",
1419 "0x03ed0000/0xffff0000", "-w"),
1420 true, nullptr));
1421 EXPECT_CALL(runner,
1422 iptables(StrEq("mangle"),
1423 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1424 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1425 true, nullptr));
1426 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1427 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1428 "-j", "CONNMARK", "--set-mark",
1429 "0x03ed0000/0xffff0000", "-w"),
1430 true, nullptr));
1431 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1432 ElementsAre("-A", "apply_vpn_mark", "-j",
1433 "MARK", "--set-mark",
1434 "0x03ed0000/0xffff0000", "-w"),
1435 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001436 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1437 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1438 "-j", "CONNMARK", "--save-mark",
1439 "--mask", "0x00003f00", "-w"),
1440 true, nullptr));
1441 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1442 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1443 "-j", "CONNMARK", "--save-mark",
1444 "--mask", "0x00003f00", "-w"),
1445 true, nullptr));
1446 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1447 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1448 "-j", "CONNMARK", "--restore-mark",
1449 "--mask", "0x00003f00", "-w"),
1450 true, nullptr));
1451 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1452 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1453 "-j", "CONNMARK", "--restore-mark",
1454 "--mask", "0x00003f00", "-w"),
1455 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001456 EXPECT_CALL(runner, iptables(StrEq("nat"),
1457 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1458 "-j", "MASQUERADE", "-w"),
1459 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001460 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001461 EXPECT_CALL(runner,
1462 iptables(StrEq("mangle"),
1463 ElementsAre("-D", "check_routing_mark", "-o", "arcbr0",
1464 "-m", "mark", "!", "--mark",
1465 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1466 true, nullptr));
1467 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1468 ElementsAre("-D", "check_routing_mark", "-o",
1469 "arcbr0", "-m", "mark", "!",
1470 "--mark", "0x03ed0000/0xffff0000",
1471 "-j", "DROP", "-w"),
1472 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001473 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1474 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1475 "-j", "CONNMARK", "--set-mark",
1476 "0x03ed0000/0xffff0000", "-w"),
1477 true, nullptr));
1478 EXPECT_CALL(runner,
1479 iptables(StrEq("mangle"),
1480 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1481 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1482 true, nullptr));
1483 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1484 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1485 "-j", "CONNMARK", "--set-mark",
1486 "0x03ed0000/0xffff0000", "-w"),
1487 true, nullptr));
1488 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1489 ElementsAre("-D", "apply_vpn_mark", "-j",
1490 "MARK", "--set-mark",
1491 "0x03ed0000/0xffff0000", "-w"),
1492 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001493 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1494 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1495 "-j", "CONNMARK", "--save-mark",
1496 "--mask", "0x00003f00", "-w"),
1497 true, nullptr));
1498 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1499 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1500 "-j", "CONNMARK", "--save-mark",
1501 "--mask", "0x00003f00", "-w"),
1502 true, nullptr));
1503 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1504 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1505 "-j", "CONNMARK", "--restore-mark",
1506 "--mask", "0x00003f00", "-w"),
1507 true, nullptr));
1508 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1509 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1510 "-j", "CONNMARK", "--restore-mark",
1511 "--mask", "0x00003f00", "-w"),
1512 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001513 EXPECT_CALL(runner, iptables(StrEq("nat"),
1514 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1515 "-j", "MASQUERADE", "-w"),
1516 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001517
1518 Datapath datapath(&runner, &firewall);
1519 datapath.SetIfnameIndex("arcbr0", 5);
1520 datapath.StartVpnRouting("arcbr0");
1521 datapath.StopVpnRouting("arcbr0");
1522}
1523
Hugo Benichibfc49112020-12-14 12:54:44 +09001524TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
1525 MockProcessRunner runner;
1526 MockFirewall firewall;
1527
1528 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001529 EXPECT_CALL(runner,
1530 iptables(StrEq("mangle"),
1531 ElementsAre("-A", "check_routing_mark", "-o", "tun0",
1532 "-m", "mark", "!", "--mark",
1533
1534 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1535 true, nullptr));
1536 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1537 ElementsAre("-A", "check_routing_mark", "-o",
1538 "tun0", "-m", "mark", "!", "--mark",
1539
1540 "0x03ed0000/0xffff0000", "-j",
1541 "DROP", "-w"),
1542 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001543 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1544 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1545 "-j", "CONNMARK", "--set-mark",
1546 "0x03ed0000/0xffff0000", "-w"),
1547 true, nullptr));
1548 EXPECT_CALL(runner,
1549 iptables(StrEq("mangle"),
1550 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1551 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1552 true, nullptr));
1553 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1554 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1555 "-j", "CONNMARK", "--set-mark",
1556 "0x03ed0000/0xffff0000", "-w"),
1557 true, nullptr));
1558 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1559 ElementsAre("-A", "apply_vpn_mark", "-j",
1560 "MARK", "--set-mark",
1561 "0x03ed0000/0xffff0000", "-w"),
1562 true, nullptr));
1563 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1564 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1565 "-j", "CONNMARK", "--save-mark",
1566 "--mask", "0x00003f00", "-w"),
1567 true, nullptr));
1568 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1569 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1570 "-j", "CONNMARK", "--save-mark",
1571 "--mask", "0x00003f00", "-w"),
1572 true, nullptr));
1573 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1574 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1575 "-j", "CONNMARK", "--restore-mark",
1576 "--mask", "0x00003f00", "-w"),
1577 true, nullptr));
1578 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1579 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1580 "-j", "CONNMARK", "--restore-mark",
1581 "--mask", "0x00003f00", "-w"),
1582 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001583 EXPECT_CALL(runner, iptables(StrEq("nat"),
1584 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1585 "-j", "MASQUERADE", "-w"),
1586 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001587 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001588 EXPECT_CALL(runner,
1589 iptables(StrEq("mangle"),
1590 ElementsAre("-D", "check_routing_mark", "-o", "tun0",
1591 "-m", "mark", "!", "--mark",
1592
1593 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1594 true, nullptr));
1595 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1596 ElementsAre("-D", "check_routing_mark", "-o",
1597 "tun0", "-m", "mark", "!", "--mark",
1598
1599 "0x03ed0000/0xffff0000", "-j",
1600 "DROP", "-w"),
1601 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001602 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1603 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1604 "-j", "CONNMARK", "--set-mark",
1605 "0x03ed0000/0xffff0000", "-w"),
1606 true, nullptr));
1607 EXPECT_CALL(runner,
1608 iptables(StrEq("mangle"),
1609 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1610 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1611 true, nullptr));
1612 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1613 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1614 "-j", "CONNMARK", "--set-mark",
1615 "0x03ed0000/0xffff0000", "-w"),
1616 true, nullptr));
1617 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1618 ElementsAre("-D", "apply_vpn_mark", "-j",
1619 "MARK", "--set-mark",
1620 "0x03ed0000/0xffff0000", "-w"),
1621 true, nullptr));
1622 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1623 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1624 "-j", "CONNMARK", "--save-mark",
1625 "--mask", "0x00003f00", "-w"),
1626 true, nullptr));
1627 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1628 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1629 "-j", "CONNMARK", "--save-mark",
1630 "--mask", "0x00003f00", "-w"),
1631 true, nullptr));
1632 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1633 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1634 "-j", "CONNMARK", "--restore-mark",
1635 "--mask", "0x00003f00", "-w"),
1636 true, nullptr));
1637 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1638 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1639 "-j", "CONNMARK", "--restore-mark",
1640 "--mask", "0x00003f00", "-w"),
1641 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001642 EXPECT_CALL(runner, iptables(StrEq("nat"),
1643 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1644 "-j", "MASQUERADE", "-w"),
1645 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001646 // Start tun0 <-> arcbr0 routing
1647 EXPECT_CALL(runner, iptables(StrEq("filter"),
1648 ElementsAre("-A", "FORWARD", "-i", "tun0", "-o",
1649 "arcbr0", "-j", "ACCEPT", "-w"),
1650 true, nullptr));
1651 EXPECT_CALL(runner, iptables(StrEq("filter"),
1652 ElementsAre("-A", "FORWARD", "-i", "arcbr0",
1653 "-o", "tun0", "-j", "ACCEPT", "-w"),
1654 true, nullptr));
1655 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1656 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1657 "-j", "MARK", "--set-mark",
1658 "0x00002000/0x00003f00", "-w"),
1659 true, nullptr));
1660 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1661 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1662 "-j", "MARK", "--set-mark",
1663 "0x03ed0000/0xffff0000", "-w"),
1664 true, nullptr));
1665 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1666 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1667 "-j", "MARK", "--set-mark",
1668 "0x00002000/0x00003f00", "-w"),
1669 true, nullptr));
1670 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1671 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1672 "-j", "MARK", "--set-mark",
1673 "0x03ed0000/0xffff0000", "-w"),
1674 true, nullptr));
1675 // Stop tun0 <-> arcbr0 routing
1676 EXPECT_CALL(runner, iptables(StrEq("filter"),
1677 ElementsAre("-D", "FORWARD", "-i", "tun0", "-o",
1678 "arcbr0", "-j", "ACCEPT", "-w"),
1679 true, nullptr));
1680 EXPECT_CALL(runner, iptables(StrEq("filter"),
1681 ElementsAre("-D", "FORWARD", "-i", "arcbr0",
1682 "-o", "tun0", "-j", "ACCEPT", "-w"),
1683 true, nullptr));
1684 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1685 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1686 "-j", "MARK", "--set-mark",
1687 "0x00002000/0x00003f00", "-w"),
1688 true, nullptr));
1689 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1690 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1691 "-j", "MARK", "--set-mark",
1692 "0x03ed0000/0xffff0000", "-w"),
1693 true, nullptr));
1694 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1695 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1696 "-j", "MARK", "--set-mark",
1697 "0x00002000/0x00003f00", "-w"),
1698 true, nullptr));
1699 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1700 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1701 "-j", "MARK", "--set-mark",
1702 "0x03ed0000/0xffff0000", "-w"),
1703 true, nullptr));
1704
1705 Datapath datapath(&runner, &firewall);
1706 datapath.SetIfnameIndex("tun0", 5);
1707 datapath.StartVpnRouting("tun0");
1708 datapath.StopVpnRouting("tun0");
1709}
1710
Garrick Evansf0ab7132019-06-18 14:50:42 +09001711TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001712 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001713 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001714 EXPECT_CALL(runner, iptables(StrEq("nat"),
1715 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1716 "-m", "socket", "--nowildcard", "-j",
1717 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001718 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001719 EXPECT_CALL(runner, iptables(StrEq("nat"),
1720 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1721 "-p", "tcp", "-j", "DNAT",
1722 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001723 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001724 EXPECT_CALL(runner, iptables(StrEq("nat"),
1725 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1726 "-p", "udp", "-j", "DNAT",
1727 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001728 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001729 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001730 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001731}
1732
1733TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001734 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001735 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001736 EXPECT_CALL(runner, iptables(StrEq("nat"),
1737 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1738 "-m", "socket", "--nowildcard", "-j",
1739 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001740 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001741 EXPECT_CALL(runner, iptables(StrEq("nat"),
1742 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1743 "-p", "tcp", "-j", "DNAT",
1744 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001745 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001746 EXPECT_CALL(runner, iptables(StrEq("nat"),
1747 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1748 "-p", "udp", "-j", "DNAT",
1749 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001750 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001751 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001752 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001753}
1754
Garrick Evans664a82f2019-12-17 12:18:05 +09001755TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001756 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001757 MockFirewall firewall;
1758 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001759
Garrick Evans664a82f2019-12-17 12:18:05 +09001760 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001761 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001762 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001763 EXPECT_EQ(ioctl_reqs, expected);
1764 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001765 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001766}
1767
1768TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001769 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001770 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001771 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001772 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1773 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1774 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001775 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001776 .WillOnce(Return(1));
1777 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1778 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1779 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001780 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001781 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1782 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1783 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001784 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001785 .WillOnce(Return(1));
1786 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1787 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1788 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001789 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001790 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001791 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001792}
1793
Taoyu Lica49c832019-12-06 17:56:43 +09001794TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001795 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001796 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001797 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1798 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1799 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001800 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001801 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1802 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1803 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001804 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001805 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001806 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001807}
1808
Taoyu Li90c13912019-11-26 17:56:54 +09001809TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001810 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001811 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001812 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1813 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1814 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001815 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001816 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1817 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1818 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001819 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001820 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001821 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001822}
1823
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001824TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001825 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001826 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001827 EXPECT_CALL(runner,
1828 ip6(StrEq("route"), StrEq("replace"),
1829 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001830 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001831 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001832}
1833
Hugo Benichie8758b52020-04-03 14:49:01 +09001834TEST(DatapathTest, AddIPv4Route) {
1835 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001836 MockFirewall firewall;
1837 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001838
1839 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1840 Ipv4Addr(255, 255, 255, 0));
1841 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1842 Ipv4Addr(255, 255, 255, 0));
1843 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1844 Ipv4Addr(255, 255, 255, 252));
1845 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1846 Ipv4Addr(255, 255, 255, 252));
1847
1848 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1849 SIOCDELRT};
1850 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001851
1852 std::string route1 =
1853 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1854 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1855 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1856 "RTF_GATEWAY}";
1857 std::string route2 =
1858 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1859 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1860 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1861 std::vector<std::string> captured_routes;
1862 for (const auto& route : ioctl_rtentry_args) {
1863 std::ostringstream stream;
1864 stream << route.second;
1865 captured_routes.emplace_back(stream.str());
1866 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001867 EXPECT_EQ(route1, captured_routes[0]);
1868 EXPECT_EQ(route1, captured_routes[1]);
1869 EXPECT_EQ(route2, captured_routes[2]);
1870 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001871 ioctl_reqs.clear();
1872 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001873}
1874
Garrick Evans2f581a02020-05-11 10:43:35 +09001875TEST(DatapathTest, ArcVethHostName) {
1876 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1877 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1878 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1879 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1880 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1881 EXPECT_EQ("vethexceeds_ify", ifname);
1882 EXPECT_LT(ifname.length(), IFNAMSIZ);
1883}
1884
Garrick Evans8a067562020-05-11 12:47:30 +09001885TEST(DatapathTest, ArcBridgeName) {
1886 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1887 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1888 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1889 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1890 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1891 EXPECT_EQ("arc_exceeds_ify", ifname);
1892 EXPECT_LT(ifname.length(), IFNAMSIZ);
1893}
1894
Garrick Evans3388a032020-03-24 11:25:55 +09001895} // namespace patchpanel