blob: 21319170c8e95c1a18909104d1b4b239d015b995 [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"),
185 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
186 "router-solicitation", "-j", "ACCEPT", "-w"),
187 true, nullptr));
188 EXPECT_CALL(
189 runner,
190 ip6tables(StrEq("mangle"),
191 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
192 "router-advertisement", "-j", "ACCEPT", "-w"),
193 true, nullptr));
194 EXPECT_CALL(
195 runner,
196 ip6tables(StrEq("mangle"),
197 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
198 "neighbour-solicitation", "-j", "ACCEPT", "-w"),
199 true, nullptr));
200 EXPECT_CALL(
201 runner,
202 ip6tables(StrEq("mangle"),
203 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
204 "neighbour-advertisement", "-j", "ACCEPT", "-w"),
205 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900206 // Asserts for OUTPUT CONNMARK restore rule
207 EXPECT_CALL(runner, iptables(StrEq("mangle"),
208 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
209 "--restore-mark", "--mask",
210 "0xffff0000", "-w"),
211 true, nullptr));
212 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
213 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
214 "--restore-mark", "--mask",
215 "0xffff0000", "-w"),
216 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900217 // Asserts for apply_local_source_mark chain
218 EXPECT_CALL(runner,
219 iptables(StrEq("mangle"),
220 ElementsAre("-N", "apply_local_source_mark", "-w"), true,
221 nullptr));
222 EXPECT_CALL(runner,
223 iptables(StrEq("mangle"),
224 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
225 nullptr));
226 EXPECT_CALL(runner, iptables(StrEq("mangle"),
227 ElementsAre("-A", "OUTPUT", "-j",
228 "apply_local_source_mark", "-w"),
229 true, nullptr));
230 EXPECT_CALL(
231 runner,
232 iptables(StrEq("mangle"),
233 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
234 "--uid-owner", "chronos", "-j", "MARK", "--set-mark",
235 "0x00008100/0x0000ff00", "-w"),
236 true, nullptr));
237 EXPECT_CALL(runner, iptables(StrEq("mangle"),
238 ElementsAre("-A", "apply_local_source_mark",
239 "-m", "owner", "--uid-owner",
240 "debugd", "-j", "MARK", "--set-mark",
241 "0x00008200/0x0000ff00", "-w"),
242 true, nullptr));
243 EXPECT_CALL(runner,
244 iptables(StrEq("mangle"),
245 ElementsAre("-A", "apply_local_source_mark", "-m",
246 "owner", "--uid-owner", "cups", "-j", "MARK",
247 "--set-mark", "0x00008200/0x0000ff00", "-w"),
248 true, nullptr));
249 EXPECT_CALL(
250 runner,
251 iptables(StrEq("mangle"),
252 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi9c5516b2021-01-29 09:26:21 +0900253 "--uid-owner", "lpadmin", "-j", "MARK", "--set-mark",
254 "0x00008200/0x0000ff00", "-w"),
255 true, nullptr));
256 EXPECT_CALL(
257 runner,
258 iptables(StrEq("mangle"),
259 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900260 "--uid-owner", "kerberosd", "-j", "MARK",
261 "--set-mark", "0x00008400/0x0000ff00", "-w"),
262 true, nullptr));
263 EXPECT_CALL(
264 runner,
265 iptables(StrEq("mangle"),
266 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
267 "--uid-owner", "kerberosd-exec", "-j", "MARK",
268 "--set-mark", "0x00008400/0x0000ff00", "-w"),
269 true, nullptr));
270 EXPECT_CALL(
271 runner,
272 iptables(StrEq("mangle"),
273 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
274 "--uid-owner", "tlsdate", "-j", "MARK", "--set-mark",
275 "0x00008400/0x0000ff00", "-w"),
276 true, nullptr));
277 EXPECT_CALL(
278 runner,
279 iptables(StrEq("mangle"),
280 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
281 "--uid-owner", "pluginvm", "-j", "MARK",
282 "--set-mark", "0x00008200/0x0000ff00", "-w"),
283 true, nullptr));
284 EXPECT_CALL(
285 runner,
286 iptables(StrEq("mangle"),
287 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
288 "--uid-owner", "fuse-smbfs", "-j", "MARK",
289 "--set-mark", "0x00008400/0x0000ff00", "-w"),
290 true, nullptr));
291 EXPECT_CALL(
292 runner,
293 iptables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900294 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
295 "--cgroup", "0x00010001", "-j", "MARK", "--set-mark",
296 "0x00000300/0x0000ff00", "-w"),
297 true, nullptr));
298 EXPECT_CALL(
299 runner,
300 iptables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900301 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
302 "--mark", "0x0/0x00003f00", "-j", "MARK",
303 "--set-mark", "0x00000400/0x00003f00", "-w"),
304 true, nullptr));
305 EXPECT_CALL(runner,
306 ip6tables(StrEq("mangle"),
307 ElementsAre("-N", "apply_local_source_mark", "-w"),
308 true, nullptr));
309 EXPECT_CALL(runner,
310 ip6tables(StrEq("mangle"),
311 ElementsAre("-F", "apply_local_source_mark", "-w"),
312 true, nullptr));
313 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
314 ElementsAre("-A", "OUTPUT", "-j",
315 "apply_local_source_mark", "-w"),
316 true, nullptr));
317 EXPECT_CALL(
318 runner,
319 ip6tables(StrEq("mangle"),
320 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
321 "--uid-owner", "debugd", "-j", "MARK", "--set-mark",
322 "0x00008200/0x0000ff00", "-w"),
323 true, nullptr));
324 EXPECT_CALL(
325 runner,
326 ip6tables(StrEq("mangle"),
327 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
328 "--uid-owner", "chronos", "-j", "MARK",
329 "--set-mark", "0x00008100/0x0000ff00", "-w"),
330 true, nullptr));
331 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
332 ElementsAre("-A", "apply_local_source_mark",
333 "-m", "owner", "--uid-owner",
334 "cups", "-j", "MARK", "--set-mark",
335 "0x00008200/0x0000ff00", "-w"),
336 true, nullptr));
337 EXPECT_CALL(
338 runner,
339 ip6tables(StrEq("mangle"),
340 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi9c5516b2021-01-29 09:26:21 +0900341 "--uid-owner", "lpadmin", "-j", "MARK",
342 "--set-mark", "0x00008200/0x0000ff00", "-w"),
343 true, nullptr));
344 EXPECT_CALL(
345 runner,
346 ip6tables(StrEq("mangle"),
347 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900348 "--uid-owner", "kerberosd", "-j", "MARK",
349 "--set-mark", "0x00008400/0x0000ff00", "-w"),
350 true, nullptr));
351 EXPECT_CALL(
352 runner,
353 ip6tables(StrEq("mangle"),
354 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
355 "--uid-owner", "kerberosd-exec", "-j", "MARK",
356 "--set-mark", "0x00008400/0x0000ff00", "-w"),
357 true, nullptr));
358 EXPECT_CALL(
359 runner,
360 ip6tables(StrEq("mangle"),
361 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
362 "--uid-owner", "tlsdate", "-j", "MARK",
363 "--set-mark", "0x00008400/0x0000ff00", "-w"),
364 true, nullptr));
365 EXPECT_CALL(
366 runner,
367 ip6tables(StrEq("mangle"),
368 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
369 "--uid-owner", "pluginvm", "-j", "MARK",
370 "--set-mark", "0x00008200/0x0000ff00", "-w"),
371 true, nullptr));
372 EXPECT_CALL(
373 runner,
374 ip6tables(StrEq("mangle"),
375 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
376 "--uid-owner", "fuse-smbfs", "-j", "MARK",
377 "--set-mark", "0x00008400/0x0000ff00", "-w"),
378 true, nullptr));
379 EXPECT_CALL(
380 runner,
381 ip6tables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900382 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
383 "--cgroup", "0x00010001", "-j", "MARK",
384 "--set-mark", "0x00000300/0x0000ff00", "-w"),
385 true, nullptr));
386 EXPECT_CALL(
387 runner,
388 ip6tables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900389 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
390 "--mark", "0x0/0x00003f00", "-j", "MARK",
391 "--set-mark", "0x00000400/0x00003f00", "-w"),
392 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900393 // Asserts for apply_vpn_mark chain
394 EXPECT_CALL(runner, iptables(StrEq("mangle"),
395 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
396 nullptr));
397 EXPECT_CALL(runner, iptables(StrEq("mangle"),
398 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
399 nullptr));
400 EXPECT_CALL(runner, iptables(StrEq("mangle"),
401 ElementsAre("-A", "OUTPUT", "-m", "mark",
402 "--mark", "0x00008000/0x0000c000",
403 "-j", "apply_vpn_mark", "-w"),
404 true, nullptr));
405 EXPECT_CALL(runner, iptables(StrEq("mangle"),
406 ElementsAre("-A", "apply_vpn_mark", "-m", "mark",
407 "!", "--mark", "0x0/0xffff0000",
408 "-j", "ACCEPT", "-w"),
409 true, nullptr));
410 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
411 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
412 nullptr));
413 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
414 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
415 nullptr));
416 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
417 ElementsAre("-A", "OUTPUT", "-m", "mark",
418 "--mark", "0x00008000/0x0000c000",
419 "-j", "apply_vpn_mark", "-w"),
420 true, nullptr));
421 EXPECT_CALL(
422 runner,
423 ip6tables(StrEq("mangle"),
424 ElementsAre("-A", "apply_vpn_mark", "-m", "mark", "!", "--mark",
425 "0x0/0xffff0000", "-j", "ACCEPT", "-w"),
426 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900427 // Asserts for check_routing_mark chain
428 EXPECT_CALL(runner, iptables(StrEq("mangle"),
429 ElementsAre("-N", "check_routing_mark", "-w"),
430 true, nullptr));
431 EXPECT_CALL(runner, iptables(StrEq("mangle"),
432 ElementsAre("-F", "check_routing_mark", "-w"),
433 true, nullptr));
434 EXPECT_CALL(runner, iptables(StrEq("mangle"),
435 ElementsAre("-A", "POSTROUTING", "-j",
436 "CONNMARK", "--restore-mark",
437 "--mask", "0xffff0000", "-w"),
438 true, nullptr));
439 EXPECT_CALL(runner, iptables(StrEq("mangle"),
440 ElementsAre("-A", "POSTROUTING", "-m", "mark",
441 "!", "--mark", "0x0/0xffff0000",
442 "-j", "check_routing_mark", "-w"),
443 true, nullptr));
444 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
445 ElementsAre("-N", "check_routing_mark", "-w"),
446 true, nullptr));
447 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
448 ElementsAre("-F", "check_routing_mark", "-w"),
449 true, nullptr));
450 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
451 ElementsAre("-A", "POSTROUTING", "-j",
452 "CONNMARK", "--restore-mark",
453 "--mask", "0xffff0000", "-w"),
454 true, nullptr));
455 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
456 ElementsAre("-A", "POSTROUTING", "-m", "mark",
457 "!", "--mark", "0x0/0xffff0000",
458 "-j", "check_routing_mark", "-w"),
459 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900460
461 Datapath datapath(&runner, &firewall);
462 datapath.Start();
463}
464
465TEST(DatapathTest, Stop) {
466 MockProcessRunner runner;
467 MockFirewall firewall;
468 // Asserts for sysctl modifications
469 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
470 StrEq("32768 61000"), true));
471 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
472 StrEq("0"), true));
473 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
474 // Asserts for RemoveOutboundIPv4SNATMark("vmtap+")
475 EXPECT_CALL(runner,
476 iptables(StrEq("mangle"),
477 ElementsAre("-D", "PREROUTING", "-i", "vmtap+", "-j",
478 "MARK", "--set-mark", "1/1", "-w"),
479 true, nullptr));
480 // Asserts for RemoveForwardEstablishedRule
481 EXPECT_CALL(runner,
482 iptables(StrEq("filter"),
483 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
484 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
485 true, nullptr));
Hugo Benichi561fae42021-01-22 15:28:40 +0900486 // Asserts for SNAT rules.
Hugo Benichibf811c62020-09-07 17:30:45 +0900487 EXPECT_CALL(
488 runner,
489 iptables(StrEq("filter"),
490 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
491 "state", "--state", "INVALID", "-j", "DROP", "-w"),
492 true, nullptr));
493 EXPECT_CALL(runner,
Hugo Benichibf811c62020-09-07 17:30:45 +0900494 iptables(StrEq("nat"),
495 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
496 "1/1", "-j", "MASQUERADE", "-w"),
497 true, nullptr));
498 // Asserts for RemoveSourceIPv4DropRule() calls.
499 EXPECT_CALL(runner,
500 iptables(StrEq("filter"),
501 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
502 "100.115.92.0/23", "-j", "DROP", "-w"),
503 true, nullptr));
504 EXPECT_CALL(runner,
505 iptables(StrEq("filter"),
506 ElementsAre("-D", "OUTPUT", "-o", "wlan+", "-s",
507 "100.115.92.0/23", "-j", "DROP", "-w"),
508 true, nullptr));
509 EXPECT_CALL(runner,
510 iptables(StrEq("filter"),
511 ElementsAre("-D", "OUTPUT", "-o", "mlan+", "-s",
512 "100.115.92.0/23", "-j", "DROP", "-w"),
513 true, nullptr));
514 EXPECT_CALL(runner,
515 iptables(StrEq("filter"),
516 ElementsAre("-D", "OUTPUT", "-o", "usb+", "-s",
517 "100.115.92.0/23", "-j", "DROP", "-w"),
518 true, nullptr));
519 EXPECT_CALL(runner,
520 iptables(StrEq("filter"),
521 ElementsAre("-D", "OUTPUT", "-o", "wwan+", "-s",
522 "100.115.92.0/23", "-j", "DROP", "-w"),
523 true, nullptr));
524 EXPECT_CALL(runner,
525 iptables(StrEq("filter"),
526 ElementsAre("-D", "OUTPUT", "-o", "rmnet+", "-s",
527 "100.115.92.0/23", "-j", "DROP", "-w"),
528 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900529 // Asserts for apply_local_source_mark chain
530 EXPECT_CALL(runner, iptables(StrEq("mangle"),
531 ElementsAre("-D", "OUTPUT", "-j",
532 "apply_local_source_mark", "-w"),
533 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900534 // Asserts for OUTPUT CONNMARK restore rule
535 EXPECT_CALL(runner, iptables(StrEq("mangle"),
536 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
537 "--restore-mark", "--mask",
538 "0xffff0000", "-w"),
539 true, nullptr));
540 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
541 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
542 "--restore-mark", "--mask",
543 "0xffff0000", "-w"),
544 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900545 EXPECT_CALL(runner,
546 iptables(StrEq("mangle"),
547 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
548 nullptr));
549 EXPECT_CALL(runner,
550 iptables(StrEq("mangle"),
551 ElementsAre("-X", "apply_local_source_mark", "-w"), true,
552 nullptr));
553 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
554 ElementsAre("-D", "OUTPUT", "-j",
555 "apply_local_source_mark", "-w"),
556 true, nullptr));
557 EXPECT_CALL(runner,
558 ip6tables(StrEq("mangle"),
559 ElementsAre("-F", "apply_local_source_mark", "-w"),
560 true, nullptr));
561 EXPECT_CALL(runner,
562 ip6tables(StrEq("mangle"),
563 ElementsAre("-X", "apply_local_source_mark", "-w"),
564 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900565 // Asserts for apply_vpn_mark chain
566 EXPECT_CALL(runner, iptables(StrEq("mangle"),
567 ElementsAre("-D", "OUTPUT", "-m", "mark",
568 "--mark", "0x00008000/0x0000c000",
569 "-j", "apply_vpn_mark", "-w"),
570 true, nullptr));
571 EXPECT_CALL(runner, iptables(StrEq("mangle"),
572 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
573 nullptr));
574 EXPECT_CALL(runner, iptables(StrEq("mangle"),
575 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
576 nullptr));
577 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
578 ElementsAre("-D", "OUTPUT", "-m", "mark",
579 "--mark", "0x00008000/0x0000c000",
580 "-j", "apply_vpn_mark", "-w"),
581 true, nullptr));
582 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
583 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
584 nullptr));
585 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
586 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
587 nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900588 // Asserts for check_routing_mark chain
589 EXPECT_CALL(runner, iptables(StrEq("mangle"),
590 ElementsAre("-D", "POSTROUTING", "-j",
591 "CONNMARK", "--restore-mark",
592 "--mask", "0xffff0000", "-w"),
593 true, nullptr));
594 EXPECT_CALL(runner, iptables(StrEq("mangle"),
595 ElementsAre("-D", "POSTROUTING", "-m", "mark",
596 "!", "--mark", "0x0/0xffff0000",
597 "-j", "check_routing_mark", "-w"),
598 true, nullptr));
599 EXPECT_CALL(runner, iptables(StrEq("mangle"),
600 ElementsAre("-F", "check_routing_mark", "-w"),
601 true, nullptr));
602 EXPECT_CALL(runner, iptables(StrEq("mangle"),
603 ElementsAre("-X", "check_routing_mark", "-w"),
604 true, nullptr));
605 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
606 ElementsAre("-D", "POSTROUTING", "-j",
607 "CONNMARK", "--restore-mark",
608 "--mask", "0xffff0000", "-w"),
609 true, nullptr));
610 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
611 ElementsAre("-D", "POSTROUTING", "-m", "mark",
612 "!", "--mark", "0x0/0xffff0000",
613 "-j", "check_routing_mark", "-w"),
614 true, nullptr));
615 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
616 ElementsAre("-F", "check_routing_mark", "-w"),
617 true, nullptr));
618 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
619 ElementsAre("-X", "check_routing_mark", "-w"),
620 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900621
622 Datapath datapath(&runner, &firewall);
623 datapath.Stop();
624}
625
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900626TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900627 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900628 MockFirewall firewall;
629 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900630 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900631 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900632 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900633 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900634 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900635 std::vector<ioctl_req_t> expected = {
636 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
637 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900638 EXPECT_EQ(ioctl_reqs, expected);
639 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900640 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900641}
642
643TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900644 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900645 MockFirewall firewall;
646 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900647 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900648 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900649 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900650 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900651 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900652 std::vector<ioctl_req_t> expected = {
653 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
654 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900655 EXPECT_EQ(ioctl_reqs, expected);
656 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900657 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900658}
659
Garrick Evans621ed262019-11-13 12:28:43 +0900660TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900661 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900662 MockFirewall firewall;
663 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900664 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900665 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900666 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
667 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900668 EXPECT_EQ(ioctl_reqs, expected);
669 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900670 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900671}
672
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900673TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900674 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900675 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900676 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
677 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900678 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900679 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900680}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900681
Hugo Benichi33860d72020-07-09 16:34:01 +0900682TEST(DatapathTest, NetnsAttachName) {
683 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900684 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900685 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
686 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900687 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900688 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
689}
690
691TEST(DatapathTest, NetnsDeleteName) {
692 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900693 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900694 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900695 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900696 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
697}
698
Garrick Evans8a949dc2019-07-18 16:17:53 +0900699TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900700 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900701 MockFirewall firewall;
702 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900703 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900704 EXPECT_CALL(
705 runner,
706 ip(StrEq("addr"), StrEq("add"),
707 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900708 EXPECT_CALL(runner,
709 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900710 EXPECT_CALL(runner, iptables(StrEq("mangle"),
711 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900712 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900713 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900714 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900715}
716
Hugo Benichi76675592020-04-08 14:29:57 +0900717TEST(DatapathTest, ConnectVethPair) {
718 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900719 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900720 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
721 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900722 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900723 true));
724 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
725 ElementsAre("100.115.92.169/30", "brd",
726 "100.115.92.171", "dev", "peer_foo"),
727 true))
728 .WillOnce(Return(0));
729 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
730 ElementsAre("dev", "peer_foo", "up", "addr",
731 "01:02:03:04:05:06", "multicast", "on"),
732 true))
733 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900734 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
735 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900736 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900737 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
738 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900739 Ipv4Addr(100, 115, 92, 169), 30, true));
740}
741
Garrick Evans2470caa2020-03-04 14:15:41 +0900742TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900743 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900744 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900745 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
746 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900747 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900748 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900749 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900750 EXPECT_TRUE(
751 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900752}
753
754TEST(DatapathTest, ToggleInterface) {
755 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900756 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900757 EXPECT_CALL(runner,
758 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900759 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900760 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900761 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900762 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
763 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
764}
765
766TEST(DatapathTest, ConfigureInterface) {
767 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900768 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900769 EXPECT_CALL(
770 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900771 ip(StrEq("addr"), StrEq("add"),
772 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
773 .WillOnce(Return(0));
774 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
775 ElementsAre("dev", "foo", "up", "addr",
776 "02:02:02:02:02:02", "multicast", "on"),
777 true))
778 .WillOnce(Return(0));
779
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900780 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900781 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
782 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
783 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900784}
785
786TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900787 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900788 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900789 EXPECT_CALL(runner,
790 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900791 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900792 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900793}
794
Garrick Evans8a949dc2019-07-18 16:17:53 +0900795TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900796 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900797 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900798 EXPECT_CALL(runner, iptables(StrEq("mangle"),
799 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900800 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900801 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900802 EXPECT_CALL(runner,
803 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900804 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900805 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900806 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900807}
808
Hugo Benichi321f23b2020-09-25 15:42:05 +0900809TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
810 MockProcessRunner runner;
811 MockFirewall firewall;
812 EXPECT_CALL(runner,
813 iptables(StrEq("filter"),
814 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
815 "100.115.92.0/24", "-j", "DROP", "-w"),
816 true, nullptr));
817 EXPECT_CALL(runner,
818 iptables(StrEq("filter"),
819 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
820 "100.115.92.0/24", "-j", "DROP", "-w"),
821 true, nullptr));
822 Datapath datapath(&runner, &firewall);
823 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
824 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
825}
826
Hugo Benichi7c342672020-09-08 09:18:14 +0900827TEST(DatapathTest, StartRoutingNamespace) {
828 MockProcessRunner runner;
829 MockFirewall firewall;
830 MacAddress mac = {1, 2, 3, 4, 5, 6};
831
832 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
833 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
834 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
835 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
836 "veth0", "netns", "netns_foo"),
837 true));
838 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
839 ElementsAre("100.115.92.130/30", "brd",
840 "100.115.92.131", "dev", "veth0"),
841 true))
842 .WillOnce(Return(0));
843 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
844 ElementsAre("dev", "veth0", "up", "addr",
845 "01:02:03:04:05:06", "multicast", "off"),
846 true))
847 .WillOnce(Return(0));
848 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
849 ElementsAre("arc_ns0", "up"), true));
850 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
851 ElementsAre("100.115.92.129/30", "brd",
852 "100.115.92.131", "dev", "arc_ns0"),
853 true))
854 .WillOnce(Return(0));
855 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
856 ElementsAre("dev", "arc_ns0", "up", "addr",
857 "01:02:03:04:05:06", "multicast", "off"),
858 true))
859 .WillOnce(Return(0));
860 EXPECT_CALL(runner, iptables(StrEq("filter"),
861 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
862 "-j", "ACCEPT", "-w"),
863 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900864 EXPECT_CALL(runner, iptables(StrEq("filter"),
865 ElementsAre("-A", "FORWARD", "-i", "arc_ns0",
866 "-j", "ACCEPT", "-w"),
867 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900868 EXPECT_CALL(runner,
869 iptables(StrEq("mangle"),
870 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
871 "MARK", "--set-mark", "1/1", "-w"),
872 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900873 EXPECT_CALL(runner, iptables(StrEq("mangle"),
874 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
875 "-j", "MARK", "--set-mark",
876 "0x00000200/0x00003f00", "-w"),
877 true, nullptr));
878 EXPECT_CALL(runner, iptables(StrEq("mangle"),
879 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
880 "-j", "CONNMARK", "--restore-mark",
881 "--mask", "0xffff0000", "-w"),
882 true, nullptr));
883 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
884 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
885 "-j", "MARK", "--set-mark",
886 "0x00000200/0x00003f00", "-w"),
887 true, nullptr));
888 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
889 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
890 "-j", "CONNMARK", "--restore-mark",
891 "--mask", "0xffff0000", "-w"),
892 true, nullptr));
893 EXPECT_CALL(runner, iptables(StrEq("mangle"),
894 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
895 "-j", "apply_vpn_mark", "-w"),
896 true, nullptr));
897 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
898 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
899 "-j", "apply_vpn_mark", "-w"),
900 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900901
Hugo Benichifcf81022020-12-04 11:01:37 +0900902 ConnectedNamespace nsinfo = {};
903 nsinfo.pid = kTestPID;
904 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900905 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900906 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900907 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900908 nsinfo.host_ifname = "arc_ns0";
909 nsinfo.peer_ifname = "veth0";
910 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
911 base::DoNothing());
912 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900913 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900914 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900915 ioctl_reqs.clear();
916 ioctl_rtentry_args.clear();
917}
918
919TEST(DatapathTest, StopRoutingNamespace) {
920 MockProcessRunner runner;
921 MockFirewall firewall;
922
923 EXPECT_CALL(runner, iptables(StrEq("filter"),
924 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
925 "-j", "ACCEPT", "-w"),
926 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900927 EXPECT_CALL(runner, iptables(StrEq("filter"),
928 ElementsAre("-D", "FORWARD", "-i", "arc_ns0",
929 "-j", "ACCEPT", "-w"),
930 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900931 EXPECT_CALL(runner,
932 iptables(StrEq("mangle"),
933 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
934 "MARK", "--set-mark", "1/1", "-w"),
935 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900936 EXPECT_CALL(runner, iptables(StrEq("mangle"),
937 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
938 "-j", "MARK", "--set-mark",
939 "0x00000200/0x00003f00", "-w"),
940 true, nullptr));
941 EXPECT_CALL(runner, iptables(StrEq("mangle"),
942 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
943 "-j", "CONNMARK", "--restore-mark",
944 "--mask", "0xffff0000", "-w"),
945 true, nullptr));
946 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
947 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
948 "-j", "MARK", "--set-mark",
949 "0x00000200/0x00003f00", "-w"),
950 true, nullptr));
951 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
952 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
953 "-j", "CONNMARK", "--restore-mark",
954 "--mask", "0xffff0000", "-w"),
955 true, nullptr));
956 EXPECT_CALL(runner, iptables(StrEq("mangle"),
957 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
958 "-j", "apply_vpn_mark", "-w"),
959 true, nullptr));
960 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
961 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
962 "-j", "apply_vpn_mark", "-w"),
963 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900964 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
965 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
966 false));
967
Hugo Benichifcf81022020-12-04 11:01:37 +0900968 ConnectedNamespace nsinfo = {};
969 nsinfo.pid = kTestPID;
970 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900971 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900972 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900973 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900974 nsinfo.host_ifname = "arc_ns0";
975 nsinfo.peer_ifname = "veth0";
976 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
977 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900978 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900979 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900980}
981
Hugo Benichi8d622b52020-08-13 15:24:12 +0900982TEST(DatapathTest, StartRoutingDevice_Arc) {
983 MockProcessRunner runner;
984 MockFirewall firewall;
985 EXPECT_CALL(runner, iptables(StrEq("nat"),
986 ElementsAre("-A", "PREROUTING", "-i", "eth0",
987 "-m", "socket", "--nowildcard", "-j",
988 "ACCEPT", "-w"),
989 true, nullptr));
990 EXPECT_CALL(runner, iptables(StrEq("nat"),
991 ElementsAre("-A", "PREROUTING", "-i", "eth0",
992 "-p", "tcp", "-j", "DNAT",
993 "--to-destination", "1.2.3.4", "-w"),
994 true, nullptr));
995 EXPECT_CALL(runner, iptables(StrEq("nat"),
996 ElementsAre("-A", "PREROUTING", "-i", "eth0",
997 "-p", "udp", "-j", "DNAT",
998 "--to-destination", "1.2.3.4", "-w"),
999 true, nullptr));
1000 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001001 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1002 "arc_eth0", "-j", "ACCEPT", "-w"),
1003 true, nullptr));
1004 EXPECT_CALL(runner, iptables(StrEq("filter"),
1005 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1006 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001007 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001008 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1009 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1010 "-j", "MARK", "--set-mark",
1011 "0x00002000/0x00003f00", "-w"),
1012 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001013 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1014 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1015 "-j", "MARK", "--set-mark",
1016 "0x03ea0000/0xffff0000", "-w"),
1017 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001018 EXPECT_CALL(
1019 runner,
1020 ip6tables(StrEq("mangle"),
1021 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1022 "--set-mark", "0x00002000/0x00003f00", "-w"),
1023 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001024 EXPECT_CALL(
1025 runner,
1026 ip6tables(StrEq("mangle"),
1027 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1028 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1029 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001030
1031 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001032 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001033 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001034 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001035}
1036
1037TEST(DatapathTest, StartRoutingDevice_CrosVM) {
1038 MockProcessRunner runner;
1039 MockFirewall firewall;
1040 EXPECT_CALL(runner, iptables(StrEq("filter"),
1041 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
1042 "-j", "ACCEPT", "-w"),
1043 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001044 EXPECT_CALL(runner, iptables(StrEq("filter"),
1045 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
1046 "-j", "ACCEPT", "-w"),
1047 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001048 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1049 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1050 "-j", "MARK", "--set-mark",
1051 "0x00002100/0x00003f00", "-w"),
1052 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001053 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1054 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1055 "-j", "CONNMARK", "--restore-mark",
1056 "--mask", "0xffff0000", "-w"),
1057 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001058 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1059 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1060 "-j", "MARK", "--set-mark",
1061 "0x00002100/0x00003f00", "-w"),
1062 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001063 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1064 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1065 "-j", "CONNMARK", "--restore-mark",
1066 "--mask", "0xffff0000", "-w"),
1067 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001068 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1069 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1070 "-j", "apply_vpn_mark", "-w"),
1071 true, nullptr));
1072 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1073 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1074 "-j", "apply_vpn_mark", "-w"),
1075 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001076
1077 Datapath datapath(&runner, &firewall);
1078 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001079 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001080}
1081
1082TEST(DatapathTest, StopRoutingDevice_Arc) {
1083 MockProcessRunner runner;
1084 MockFirewall firewall;
1085 EXPECT_CALL(runner, iptables(StrEq("nat"),
1086 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1087 "-m", "socket", "--nowildcard", "-j",
1088 "ACCEPT", "-w"),
1089 true, nullptr));
1090 EXPECT_CALL(runner, iptables(StrEq("nat"),
1091 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1092 "-p", "tcp", "-j", "DNAT",
1093 "--to-destination", "1.2.3.4", "-w"),
1094 true, nullptr));
1095 EXPECT_CALL(runner, iptables(StrEq("nat"),
1096 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1097 "-p", "udp", "-j", "DNAT",
1098 "--to-destination", "1.2.3.4", "-w"),
1099 true, nullptr));
1100 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001101 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1102 "arc_eth0", "-j", "ACCEPT", "-w"),
1103 true, nullptr));
1104 EXPECT_CALL(runner, iptables(StrEq("filter"),
1105 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1106 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001107 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001108 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1109 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1110 "-j", "MARK", "--set-mark",
1111 "0x00002000/0x00003f00", "-w"),
1112 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001113 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1114 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1115 "-j", "MARK", "--set-mark",
1116 "0x03ea0000/0xffff0000", "-w"),
1117 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001118 EXPECT_CALL(
1119 runner,
1120 ip6tables(StrEq("mangle"),
1121 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1122 "--set-mark", "0x00002000/0x00003f00", "-w"),
1123 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001124 EXPECT_CALL(
1125 runner,
1126 ip6tables(StrEq("mangle"),
1127 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1128 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1129 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001130
1131 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001132 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001133 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001134 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001135}
1136
1137TEST(DatapathTest, StopRoutingDevice_CrosVM) {
1138 MockProcessRunner runner;
1139 MockFirewall firewall;
1140 EXPECT_CALL(runner, iptables(StrEq("filter"),
1141 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
1142 "-j", "ACCEPT", "-w"),
1143 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001144 EXPECT_CALL(runner, iptables(StrEq("filter"),
1145 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
1146 "-j", "ACCEPT", "-w"),
1147 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001148 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1149 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1150 "-j", "MARK", "--set-mark",
1151 "0x00002100/0x00003f00", "-w"),
1152 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001153 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1154 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1155 "-j", "CONNMARK", "--restore-mark",
1156 "--mask", "0xffff0000", "-w"),
1157 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001158 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1159 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1160 "-j", "MARK", "--set-mark",
1161 "0x00002100/0x00003f00", "-w"),
1162 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001163 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1164 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1165 "-j", "CONNMARK", "--restore-mark",
1166 "--mask", "0xffff0000", "-w"),
1167 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001168 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1169 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1170 "-j", "apply_vpn_mark", "-w"),
1171 true, nullptr));
1172 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1173 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1174 "-j", "apply_vpn_mark", "-w"),
1175 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001176
1177 Datapath datapath(&runner, &firewall);
1178 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001179 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001180}
1181
Hugo Benichid82d8832020-08-14 10:05:03 +09001182TEST(DatapathTest, StartStopIpForwarding) {
1183 struct {
1184 IpFamily family;
1185 std::string iif;
1186 std::string oif;
1187 std::vector<std::string> start_args;
1188 std::vector<std::string> stop_args;
1189 bool result;
1190 } testcases[] = {
1191 {IpFamily::IPv4, "", "", {}, {}, false},
1192 {IpFamily::NONE, "foo", "bar", {}, {}, false},
1193 {IpFamily::IPv4,
1194 "foo",
1195 "bar",
1196 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1197 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1198 true},
1199 {IpFamily::IPv4,
1200 "",
1201 "bar",
1202 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1203 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1204 true},
1205 {IpFamily::IPv4,
1206 "foo",
1207 "",
1208 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1209 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1210 true},
1211 {IpFamily::IPv6,
1212 "foo",
1213 "bar",
1214 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1215 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1216 true},
1217 {IpFamily::IPv6,
1218 "",
1219 "bar",
1220 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1221 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1222 true},
1223 {IpFamily::IPv6,
1224 "foo",
1225 "",
1226 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1227 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1228 true},
1229 {IpFamily::Dual,
1230 "foo",
1231 "bar",
1232 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1233 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1234 true},
1235 {IpFamily::Dual,
1236 "",
1237 "bar",
1238 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1239 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1240 true},
1241 {IpFamily::Dual,
1242 "foo",
1243 "",
1244 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1245 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1246 true},
1247 };
1248
1249 for (const auto& tt : testcases) {
1250 MockProcessRunner runner;
1251 MockFirewall firewall;
1252 if (tt.result) {
1253 if (tt.family & IpFamily::IPv4) {
1254 EXPECT_CALL(runner,
1255 iptables(StrEq("filter"), tt.start_args, true, nullptr))
1256 .WillOnce(Return(0));
1257 EXPECT_CALL(runner,
1258 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
1259 .WillOnce(Return(0));
1260 }
1261 if (tt.family & IpFamily::IPv6) {
1262 EXPECT_CALL(runner,
1263 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
1264 .WillOnce(Return(0));
1265 EXPECT_CALL(runner,
1266 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
1267 .WillOnce(Return(0));
1268 }
1269 }
1270 Datapath datapath(&runner, &firewall);
1271
1272 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
1273 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
1274 }
1275}
1276
Hugo Benichi76be34a2020-08-26 22:35:54 +09001277TEST(DatapathTest, StartStopConnectionPinning) {
1278 MockProcessRunner runner;
1279 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +09001280
1281 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001282 EXPECT_CALL(runner,
1283 iptables(StrEq("mangle"),
1284 ElementsAre("-A", "check_routing_mark", "-o", "eth0",
1285 "-m", "mark", "!", "--mark",
1286 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1287 true, nullptr));
1288 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1289 ElementsAre("-A", "check_routing_mark", "-o",
1290 "eth0", "-m", "mark", "!", "--mark",
1291 "0x03eb0000/0xffff0000", "-j",
1292 "DROP", "-w"),
1293 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001294 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1295 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1296 "-j", "CONNMARK", "--set-mark",
1297 "0x03eb0000/0xffff0000", "-w"),
1298 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001299 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1300 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1301 "-j", "CONNMARK", "--set-mark",
1302 "0x03eb0000/0xffff0000", "-w"),
1303 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001304 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1305 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1306 "-j", "CONNMARK", "--save-mark",
1307 "--mask", "0x00003f00", "-w"),
1308 true, nullptr));
1309 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1310 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1311 "-j", "CONNMARK", "--save-mark",
1312 "--mask", "0x00003f00", "-w"),
1313 true, nullptr));
1314 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1315 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1316 "-j", "CONNMARK", "--restore-mark",
1317 "--mask", "0x00003f00", "-w"),
1318 true, nullptr));
1319 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1320 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1321 "-j", "CONNMARK", "--restore-mark",
1322 "--mask", "0x00003f00", "-w"),
1323 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +09001324
Hugo Benichi1af52392020-11-27 18:09:32 +09001325 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001326 EXPECT_CALL(runner,
1327 iptables(StrEq("mangle"),
1328 ElementsAre("-D", "check_routing_mark", "-o", "eth0",
1329 "-m", "mark", "!", "--mark",
1330 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1331 true, nullptr));
1332 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1333 ElementsAre("-D", "check_routing_mark", "-o",
1334 "eth0", "-m", "mark", "!", "--mark",
1335 "0x03eb0000/0xffff0000", "-j",
1336 "DROP", "-w"),
1337 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001338 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1339 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1340 "-j", "CONNMARK", "--set-mark",
1341 "0x03eb0000/0xffff0000", "-w"),
1342 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001343 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1344 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1345 "-j", "CONNMARK", "--set-mark",
1346 "0x03eb0000/0xffff0000", "-w"),
1347 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001348 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1349 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1350 "-j", "CONNMARK", "--save-mark",
1351 "--mask", "0x00003f00", "-w"),
1352 true, nullptr));
1353 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1354 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1355 "-j", "CONNMARK", "--save-mark",
1356 "--mask", "0x00003f00", "-w"),
1357 true, nullptr));
1358 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1359 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1360 "-j", "CONNMARK", "--restore-mark",
1361 "--mask", "0x00003f00", "-w"),
1362 true, nullptr));
1363 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1364 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1365 "-j", "CONNMARK", "--restore-mark",
1366 "--mask", "0x00003f00", "-w"),
1367 true, nullptr));
1368
Hugo Benichi76be34a2020-08-26 22:35:54 +09001369 Datapath datapath(&runner, &firewall);
1370 datapath.SetIfnameIndex("eth0", 3);
1371 datapath.StartConnectionPinning("eth0");
1372 datapath.StopConnectionPinning("eth0");
1373}
1374
Hugo Benichibfc49112020-12-14 12:54:44 +09001375TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +09001376 MockProcessRunner runner;
1377 MockFirewall firewall;
1378
1379 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001380 EXPECT_CALL(runner,
1381 iptables(StrEq("mangle"),
1382 ElementsAre("-A", "check_routing_mark", "-o", "arcbr0",
1383 "-m", "mark", "!", "--mark",
1384 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1385 true, nullptr));
1386 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1387 ElementsAre("-A", "check_routing_mark", "-o",
1388 "arcbr0", "-m", "mark", "!",
1389 "--mark", "0x03ed0000/0xffff0000",
1390 "-j", "DROP", "-w"),
1391 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001392 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1393 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1394 "-j", "CONNMARK", "--set-mark",
1395 "0x03ed0000/0xffff0000", "-w"),
1396 true, nullptr));
1397 EXPECT_CALL(runner,
1398 iptables(StrEq("mangle"),
1399 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1400 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1401 true, nullptr));
1402 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1403 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1404 "-j", "CONNMARK", "--set-mark",
1405 "0x03ed0000/0xffff0000", "-w"),
1406 true, nullptr));
1407 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1408 ElementsAre("-A", "apply_vpn_mark", "-j",
1409 "MARK", "--set-mark",
1410 "0x03ed0000/0xffff0000", "-w"),
1411 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001412 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1413 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1414 "-j", "CONNMARK", "--save-mark",
1415 "--mask", "0x00003f00", "-w"),
1416 true, nullptr));
1417 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1418 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1419 "-j", "CONNMARK", "--save-mark",
1420 "--mask", "0x00003f00", "-w"),
1421 true, nullptr));
1422 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1423 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1424 "-j", "CONNMARK", "--restore-mark",
1425 "--mask", "0x00003f00", "-w"),
1426 true, nullptr));
1427 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1428 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1429 "-j", "CONNMARK", "--restore-mark",
1430 "--mask", "0x00003f00", "-w"),
1431 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001432 EXPECT_CALL(runner, iptables(StrEq("nat"),
1433 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1434 "-j", "MASQUERADE", "-w"),
1435 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001436 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001437 EXPECT_CALL(runner,
1438 iptables(StrEq("mangle"),
1439 ElementsAre("-D", "check_routing_mark", "-o", "arcbr0",
1440 "-m", "mark", "!", "--mark",
1441 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1442 true, nullptr));
1443 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1444 ElementsAre("-D", "check_routing_mark", "-o",
1445 "arcbr0", "-m", "mark", "!",
1446 "--mark", "0x03ed0000/0xffff0000",
1447 "-j", "DROP", "-w"),
1448 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001449 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1450 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1451 "-j", "CONNMARK", "--set-mark",
1452 "0x03ed0000/0xffff0000", "-w"),
1453 true, nullptr));
1454 EXPECT_CALL(runner,
1455 iptables(StrEq("mangle"),
1456 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1457 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1458 true, nullptr));
1459 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1460 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1461 "-j", "CONNMARK", "--set-mark",
1462 "0x03ed0000/0xffff0000", "-w"),
1463 true, nullptr));
1464 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1465 ElementsAre("-D", "apply_vpn_mark", "-j",
1466 "MARK", "--set-mark",
1467 "0x03ed0000/0xffff0000", "-w"),
1468 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001469 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1470 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1471 "-j", "CONNMARK", "--save-mark",
1472 "--mask", "0x00003f00", "-w"),
1473 true, nullptr));
1474 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1475 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1476 "-j", "CONNMARK", "--save-mark",
1477 "--mask", "0x00003f00", "-w"),
1478 true, nullptr));
1479 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1480 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1481 "-j", "CONNMARK", "--restore-mark",
1482 "--mask", "0x00003f00", "-w"),
1483 true, nullptr));
1484 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1485 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1486 "-j", "CONNMARK", "--restore-mark",
1487 "--mask", "0x00003f00", "-w"),
1488 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001489 EXPECT_CALL(runner, iptables(StrEq("nat"),
1490 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1491 "-j", "MASQUERADE", "-w"),
1492 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001493
1494 Datapath datapath(&runner, &firewall);
1495 datapath.SetIfnameIndex("arcbr0", 5);
1496 datapath.StartVpnRouting("arcbr0");
1497 datapath.StopVpnRouting("arcbr0");
1498}
1499
Hugo Benichibfc49112020-12-14 12:54:44 +09001500TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
1501 MockProcessRunner runner;
1502 MockFirewall firewall;
1503
1504 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001505 EXPECT_CALL(runner,
1506 iptables(StrEq("mangle"),
1507 ElementsAre("-A", "check_routing_mark", "-o", "tun0",
1508 "-m", "mark", "!", "--mark",
1509
1510 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1511 true, nullptr));
1512 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1513 ElementsAre("-A", "check_routing_mark", "-o",
1514 "tun0", "-m", "mark", "!", "--mark",
1515
1516 "0x03ed0000/0xffff0000", "-j",
1517 "DROP", "-w"),
1518 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001519 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1520 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1521 "-j", "CONNMARK", "--set-mark",
1522 "0x03ed0000/0xffff0000", "-w"),
1523 true, nullptr));
1524 EXPECT_CALL(runner,
1525 iptables(StrEq("mangle"),
1526 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1527 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1528 true, nullptr));
1529 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1530 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1531 "-j", "CONNMARK", "--set-mark",
1532 "0x03ed0000/0xffff0000", "-w"),
1533 true, nullptr));
1534 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1535 ElementsAre("-A", "apply_vpn_mark", "-j",
1536 "MARK", "--set-mark",
1537 "0x03ed0000/0xffff0000", "-w"),
1538 true, nullptr));
1539 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1540 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1541 "-j", "CONNMARK", "--save-mark",
1542 "--mask", "0x00003f00", "-w"),
1543 true, nullptr));
1544 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1545 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1546 "-j", "CONNMARK", "--save-mark",
1547 "--mask", "0x00003f00", "-w"),
1548 true, nullptr));
1549 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1550 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1551 "-j", "CONNMARK", "--restore-mark",
1552 "--mask", "0x00003f00", "-w"),
1553 true, nullptr));
1554 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1555 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1556 "-j", "CONNMARK", "--restore-mark",
1557 "--mask", "0x00003f00", "-w"),
1558 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001559 EXPECT_CALL(runner, iptables(StrEq("nat"),
1560 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1561 "-j", "MASQUERADE", "-w"),
1562 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001563 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001564 EXPECT_CALL(runner,
1565 iptables(StrEq("mangle"),
1566 ElementsAre("-D", "check_routing_mark", "-o", "tun0",
1567 "-m", "mark", "!", "--mark",
1568
1569 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1570 true, nullptr));
1571 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1572 ElementsAre("-D", "check_routing_mark", "-o",
1573 "tun0", "-m", "mark", "!", "--mark",
1574
1575 "0x03ed0000/0xffff0000", "-j",
1576 "DROP", "-w"),
1577 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001578 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1579 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1580 "-j", "CONNMARK", "--set-mark",
1581 "0x03ed0000/0xffff0000", "-w"),
1582 true, nullptr));
1583 EXPECT_CALL(runner,
1584 iptables(StrEq("mangle"),
1585 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1586 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1587 true, nullptr));
1588 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1589 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1590 "-j", "CONNMARK", "--set-mark",
1591 "0x03ed0000/0xffff0000", "-w"),
1592 true, nullptr));
1593 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1594 ElementsAre("-D", "apply_vpn_mark", "-j",
1595 "MARK", "--set-mark",
1596 "0x03ed0000/0xffff0000", "-w"),
1597 true, nullptr));
1598 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1599 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1600 "-j", "CONNMARK", "--save-mark",
1601 "--mask", "0x00003f00", "-w"),
1602 true, nullptr));
1603 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1604 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1605 "-j", "CONNMARK", "--save-mark",
1606 "--mask", "0x00003f00", "-w"),
1607 true, nullptr));
1608 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1609 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1610 "-j", "CONNMARK", "--restore-mark",
1611 "--mask", "0x00003f00", "-w"),
1612 true, nullptr));
1613 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1614 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1615 "-j", "CONNMARK", "--restore-mark",
1616 "--mask", "0x00003f00", "-w"),
1617 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001618 EXPECT_CALL(runner, iptables(StrEq("nat"),
1619 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1620 "-j", "MASQUERADE", "-w"),
1621 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001622 // Start tun0 <-> arcbr0 routing
1623 EXPECT_CALL(runner, iptables(StrEq("filter"),
1624 ElementsAre("-A", "FORWARD", "-i", "tun0", "-o",
1625 "arcbr0", "-j", "ACCEPT", "-w"),
1626 true, nullptr));
1627 EXPECT_CALL(runner, iptables(StrEq("filter"),
1628 ElementsAre("-A", "FORWARD", "-i", "arcbr0",
1629 "-o", "tun0", "-j", "ACCEPT", "-w"),
1630 true, nullptr));
1631 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1632 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1633 "-j", "MARK", "--set-mark",
1634 "0x00002000/0x00003f00", "-w"),
1635 true, nullptr));
1636 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1637 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1638 "-j", "MARK", "--set-mark",
1639 "0x03ed0000/0xffff0000", "-w"),
1640 true, nullptr));
1641 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1642 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1643 "-j", "MARK", "--set-mark",
1644 "0x00002000/0x00003f00", "-w"),
1645 true, nullptr));
1646 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1647 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1648 "-j", "MARK", "--set-mark",
1649 "0x03ed0000/0xffff0000", "-w"),
1650 true, nullptr));
1651 // Stop tun0 <-> arcbr0 routing
1652 EXPECT_CALL(runner, iptables(StrEq("filter"),
1653 ElementsAre("-D", "FORWARD", "-i", "tun0", "-o",
1654 "arcbr0", "-j", "ACCEPT", "-w"),
1655 true, nullptr));
1656 EXPECT_CALL(runner, iptables(StrEq("filter"),
1657 ElementsAre("-D", "FORWARD", "-i", "arcbr0",
1658 "-o", "tun0", "-j", "ACCEPT", "-w"),
1659 true, nullptr));
1660 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1661 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1662 "-j", "MARK", "--set-mark",
1663 "0x00002000/0x00003f00", "-w"),
1664 true, nullptr));
1665 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1666 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1667 "-j", "MARK", "--set-mark",
1668 "0x03ed0000/0xffff0000", "-w"),
1669 true, nullptr));
1670 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1671 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1672 "-j", "MARK", "--set-mark",
1673 "0x00002000/0x00003f00", "-w"),
1674 true, nullptr));
1675 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1676 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1677 "-j", "MARK", "--set-mark",
1678 "0x03ed0000/0xffff0000", "-w"),
1679 true, nullptr));
1680
1681 Datapath datapath(&runner, &firewall);
1682 datapath.SetIfnameIndex("tun0", 5);
1683 datapath.StartVpnRouting("tun0");
1684 datapath.StopVpnRouting("tun0");
1685}
1686
Garrick Evansf0ab7132019-06-18 14:50:42 +09001687TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001688 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001689 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001690 EXPECT_CALL(runner, iptables(StrEq("nat"),
1691 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1692 "-m", "socket", "--nowildcard", "-j",
1693 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001694 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001695 EXPECT_CALL(runner, iptables(StrEq("nat"),
1696 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1697 "-p", "tcp", "-j", "DNAT",
1698 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001699 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001700 EXPECT_CALL(runner, iptables(StrEq("nat"),
1701 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1702 "-p", "udp", "-j", "DNAT",
1703 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001704 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001705 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001706 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001707}
1708
1709TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001710 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001711 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001712 EXPECT_CALL(runner, iptables(StrEq("nat"),
1713 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1714 "-m", "socket", "--nowildcard", "-j",
1715 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001716 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001717 EXPECT_CALL(runner, iptables(StrEq("nat"),
1718 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1719 "-p", "tcp", "-j", "DNAT",
1720 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001721 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001722 EXPECT_CALL(runner, iptables(StrEq("nat"),
1723 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1724 "-p", "udp", "-j", "DNAT",
1725 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001726 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001727 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001728 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001729}
1730
Garrick Evans664a82f2019-12-17 12:18:05 +09001731TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001732 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001733 MockFirewall firewall;
1734 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001735
Garrick Evans664a82f2019-12-17 12:18:05 +09001736 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001737 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001738 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001739 EXPECT_EQ(ioctl_reqs, expected);
1740 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001741 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001742}
1743
1744TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001745 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001746 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001747 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001748 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1749 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1750 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001751 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001752 .WillOnce(Return(1));
1753 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1754 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1755 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001756 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001757 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1758 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1759 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001760 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001761 .WillOnce(Return(1));
1762 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1763 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1764 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001765 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001766 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001767 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001768}
1769
Taoyu Lica49c832019-12-06 17:56:43 +09001770TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001771 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001772 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001773 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1774 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1775 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001776 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001777 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1778 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1779 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001780 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001781 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001782 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001783}
1784
Taoyu Li90c13912019-11-26 17:56:54 +09001785TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001786 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001787 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001788 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1789 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1790 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001791 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001792 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1793 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1794 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001795 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001796 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001797 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001798}
1799
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001800TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001801 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001802 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001803 EXPECT_CALL(runner,
1804 ip6(StrEq("route"), StrEq("replace"),
1805 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001806 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001807 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001808}
1809
Hugo Benichie8758b52020-04-03 14:49:01 +09001810TEST(DatapathTest, AddIPv4Route) {
1811 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001812 MockFirewall firewall;
1813 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001814
1815 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1816 Ipv4Addr(255, 255, 255, 0));
1817 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1818 Ipv4Addr(255, 255, 255, 0));
1819 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1820 Ipv4Addr(255, 255, 255, 252));
1821 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1822 Ipv4Addr(255, 255, 255, 252));
1823
1824 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1825 SIOCDELRT};
1826 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001827
1828 std::string route1 =
1829 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1830 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1831 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1832 "RTF_GATEWAY}";
1833 std::string route2 =
1834 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1835 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1836 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1837 std::vector<std::string> captured_routes;
1838 for (const auto& route : ioctl_rtentry_args) {
1839 std::ostringstream stream;
1840 stream << route.second;
1841 captured_routes.emplace_back(stream.str());
1842 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001843 EXPECT_EQ(route1, captured_routes[0]);
1844 EXPECT_EQ(route1, captured_routes[1]);
1845 EXPECT_EQ(route2, captured_routes[2]);
1846 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001847 ioctl_reqs.clear();
1848 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001849}
1850
Garrick Evans2f581a02020-05-11 10:43:35 +09001851TEST(DatapathTest, ArcVethHostName) {
1852 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1853 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1854 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1855 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1856 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1857 EXPECT_EQ("vethexceeds_ify", ifname);
1858 EXPECT_LT(ifname.length(), IFNAMSIZ);
1859}
1860
Garrick Evans8a067562020-05-11 12:47:30 +09001861TEST(DatapathTest, ArcBridgeName) {
1862 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1863 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1864 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1865 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1866 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1867 EXPECT_EQ("arc_exceeds_ify", ifname);
1868 EXPECT_LT(ifname.length(), IFNAMSIZ);
1869}
1870
Garrick Evans3388a032020-03-24 11:25:55 +09001871} // namespace patchpanel