blob: 66af543e8a201603623e3c7016c5c5fee747c337 [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));
126 // Asserts for AddSNATMarkRules
127 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,
134 iptables(StrEq("filter"),
135 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark",
136 "1/1", "-j", "ACCEPT", "-w"),
137 true, nullptr));
138 EXPECT_CALL(runner,
139 iptables(StrEq("nat"),
140 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
141 "1/1", "-j", "MASQUERADE", "-w"),
142 true, nullptr));
143 // Asserts for AddForwardEstablishedRule
144 EXPECT_CALL(runner,
145 iptables(StrEq("filter"),
146 ElementsAre("-A", "FORWARD", "-m", "state", "--state",
147 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
148 true, nullptr));
149 // Asserts for AddSourceIPv4DropRule() calls.
150 EXPECT_CALL(runner,
151 iptables(StrEq("filter"),
152 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-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", "wlan+", "-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", "mlan+", "-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", "usb+", "-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", "wwan+", "-s",
173 "100.115.92.0/23", "-j", "DROP", "-w"),
174 true, nullptr));
175 EXPECT_CALL(runner,
176 iptables(StrEq("filter"),
177 ElementsAre("-I", "OUTPUT", "-o", "rmnet+", "-s",
178 "100.115.92.0/23", "-j", "DROP", "-w"),
179 true, nullptr));
180 // Asserts for AddOutboundIPv4SNATMark("vmtap+")
181 EXPECT_CALL(runner,
182 iptables(StrEq("mangle"),
183 ElementsAre("-A", "PREROUTING", "-i", "vmtap+", "-j",
184 "MARK", "--set-mark", "1/1", "-w"),
185 true, nullptr));
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900186 // Asserts for OUTPUT ndp connmark bypass rule
187 EXPECT_CALL(
188 runner,
189 ip6tables(StrEq("mangle"),
190 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
191 "router-solicitation", "-j", "ACCEPT", "-w"),
192 true, nullptr));
193 EXPECT_CALL(
194 runner,
195 ip6tables(StrEq("mangle"),
196 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
197 "router-advertisement", "-j", "ACCEPT", "-w"),
198 true, nullptr));
199 EXPECT_CALL(
200 runner,
201 ip6tables(StrEq("mangle"),
202 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
203 "neighbour-solicitation", "-j", "ACCEPT", "-w"),
204 true, nullptr));
205 EXPECT_CALL(
206 runner,
207 ip6tables(StrEq("mangle"),
208 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
209 "neighbour-advertisement", "-j", "ACCEPT", "-w"),
210 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900211 // Asserts for OUTPUT CONNMARK restore rule
212 EXPECT_CALL(runner, iptables(StrEq("mangle"),
213 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
214 "--restore-mark", "--mask",
215 "0xffff0000", "-w"),
216 true, nullptr));
217 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
218 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
219 "--restore-mark", "--mask",
220 "0xffff0000", "-w"),
221 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900222 // Asserts for apply_local_source_mark chain
223 EXPECT_CALL(runner,
224 iptables(StrEq("mangle"),
225 ElementsAre("-N", "apply_local_source_mark", "-w"), true,
226 nullptr));
227 EXPECT_CALL(runner,
228 iptables(StrEq("mangle"),
229 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
230 nullptr));
231 EXPECT_CALL(runner, iptables(StrEq("mangle"),
232 ElementsAre("-A", "OUTPUT", "-j",
233 "apply_local_source_mark", "-w"),
234 true, nullptr));
235 EXPECT_CALL(
236 runner,
237 iptables(StrEq("mangle"),
238 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
239 "--uid-owner", "chronos", "-j", "MARK", "--set-mark",
240 "0x00008100/0x0000ff00", "-w"),
241 true, nullptr));
242 EXPECT_CALL(runner, iptables(StrEq("mangle"),
243 ElementsAre("-A", "apply_local_source_mark",
244 "-m", "owner", "--uid-owner",
245 "debugd", "-j", "MARK", "--set-mark",
246 "0x00008200/0x0000ff00", "-w"),
247 true, nullptr));
248 EXPECT_CALL(runner,
249 iptables(StrEq("mangle"),
250 ElementsAre("-A", "apply_local_source_mark", "-m",
251 "owner", "--uid-owner", "cups", "-j", "MARK",
252 "--set-mark", "0x00008200/0x0000ff00", "-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", "kerberosd", "-j", "MARK",
259 "--set-mark", "0x00008400/0x0000ff00", "-w"),
260 true, nullptr));
261 EXPECT_CALL(
262 runner,
263 iptables(StrEq("mangle"),
264 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
265 "--uid-owner", "kerberosd-exec", "-j", "MARK",
266 "--set-mark", "0x00008400/0x0000ff00", "-w"),
267 true, nullptr));
268 EXPECT_CALL(
269 runner,
270 iptables(StrEq("mangle"),
271 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
272 "--uid-owner", "tlsdate", "-j", "MARK", "--set-mark",
273 "0x00008400/0x0000ff00", "-w"),
274 true, nullptr));
275 EXPECT_CALL(
276 runner,
277 iptables(StrEq("mangle"),
278 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
279 "--uid-owner", "pluginvm", "-j", "MARK",
280 "--set-mark", "0x00008200/0x0000ff00", "-w"),
281 true, nullptr));
282 EXPECT_CALL(
283 runner,
284 iptables(StrEq("mangle"),
285 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
286 "--uid-owner", "fuse-smbfs", "-j", "MARK",
287 "--set-mark", "0x00008400/0x0000ff00", "-w"),
288 true, nullptr));
289 EXPECT_CALL(
290 runner,
291 iptables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900292 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
293 "--cgroup", "0x00010001", "-j", "MARK", "--set-mark",
294 "0x00000300/0x0000ff00", "-w"),
295 true, nullptr));
296 EXPECT_CALL(
297 runner,
298 iptables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900299 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
300 "--mark", "0x0/0x00003f00", "-j", "MARK",
301 "--set-mark", "0x00000400/0x00003f00", "-w"),
302 true, nullptr));
303 EXPECT_CALL(runner,
304 ip6tables(StrEq("mangle"),
305 ElementsAre("-N", "apply_local_source_mark", "-w"),
306 true, nullptr));
307 EXPECT_CALL(runner,
308 ip6tables(StrEq("mangle"),
309 ElementsAre("-F", "apply_local_source_mark", "-w"),
310 true, nullptr));
311 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
312 ElementsAre("-A", "OUTPUT", "-j",
313 "apply_local_source_mark", "-w"),
314 true, nullptr));
315 EXPECT_CALL(
316 runner,
317 ip6tables(StrEq("mangle"),
318 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
319 "--uid-owner", "debugd", "-j", "MARK", "--set-mark",
320 "0x00008200/0x0000ff00", "-w"),
321 true, nullptr));
322 EXPECT_CALL(
323 runner,
324 ip6tables(StrEq("mangle"),
325 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
326 "--uid-owner", "chronos", "-j", "MARK",
327 "--set-mark", "0x00008100/0x0000ff00", "-w"),
328 true, nullptr));
329 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
330 ElementsAre("-A", "apply_local_source_mark",
331 "-m", "owner", "--uid-owner",
332 "cups", "-j", "MARK", "--set-mark",
333 "0x00008200/0x0000ff00", "-w"),
334 true, nullptr));
335 EXPECT_CALL(
336 runner,
337 ip6tables(StrEq("mangle"),
338 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
339 "--uid-owner", "kerberosd", "-j", "MARK",
340 "--set-mark", "0x00008400/0x0000ff00", "-w"),
341 true, nullptr));
342 EXPECT_CALL(
343 runner,
344 ip6tables(StrEq("mangle"),
345 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
346 "--uid-owner", "kerberosd-exec", "-j", "MARK",
347 "--set-mark", "0x00008400/0x0000ff00", "-w"),
348 true, nullptr));
349 EXPECT_CALL(
350 runner,
351 ip6tables(StrEq("mangle"),
352 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
353 "--uid-owner", "tlsdate", "-j", "MARK",
354 "--set-mark", "0x00008400/0x0000ff00", "-w"),
355 true, nullptr));
356 EXPECT_CALL(
357 runner,
358 ip6tables(StrEq("mangle"),
359 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
360 "--uid-owner", "pluginvm", "-j", "MARK",
361 "--set-mark", "0x00008200/0x0000ff00", "-w"),
362 true, nullptr));
363 EXPECT_CALL(
364 runner,
365 ip6tables(StrEq("mangle"),
366 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
367 "--uid-owner", "fuse-smbfs", "-j", "MARK",
368 "--set-mark", "0x00008400/0x0000ff00", "-w"),
369 true, nullptr));
370 EXPECT_CALL(
371 runner,
372 ip6tables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900373 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
374 "--cgroup", "0x00010001", "-j", "MARK",
375 "--set-mark", "0x00000300/0x0000ff00", "-w"),
376 true, nullptr));
377 EXPECT_CALL(
378 runner,
379 ip6tables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900380 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
381 "--mark", "0x0/0x00003f00", "-j", "MARK",
382 "--set-mark", "0x00000400/0x00003f00", "-w"),
383 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900384 // Asserts for apply_vpn_mark chain
385 EXPECT_CALL(runner, iptables(StrEq("mangle"),
386 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
387 nullptr));
388 EXPECT_CALL(runner, iptables(StrEq("mangle"),
389 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
390 nullptr));
391 EXPECT_CALL(runner, iptables(StrEq("mangle"),
392 ElementsAre("-A", "OUTPUT", "-m", "mark",
393 "--mark", "0x00008000/0x0000c000",
394 "-j", "apply_vpn_mark", "-w"),
395 true, nullptr));
396 EXPECT_CALL(runner, iptables(StrEq("mangle"),
397 ElementsAre("-A", "apply_vpn_mark", "-m", "mark",
398 "!", "--mark", "0x0/0xffff0000",
399 "-j", "ACCEPT", "-w"),
400 true, nullptr));
401 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
402 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
403 nullptr));
404 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
405 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
406 nullptr));
407 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
408 ElementsAre("-A", "OUTPUT", "-m", "mark",
409 "--mark", "0x00008000/0x0000c000",
410 "-j", "apply_vpn_mark", "-w"),
411 true, nullptr));
412 EXPECT_CALL(
413 runner,
414 ip6tables(StrEq("mangle"),
415 ElementsAre("-A", "apply_vpn_mark", "-m", "mark", "!", "--mark",
416 "0x0/0xffff0000", "-j", "ACCEPT", "-w"),
417 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900418
419 Datapath datapath(&runner, &firewall);
420 datapath.Start();
421}
422
423TEST(DatapathTest, Stop) {
424 MockProcessRunner runner;
425 MockFirewall firewall;
426 // Asserts for sysctl modifications
427 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
428 StrEq("32768 61000"), true));
429 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
430 StrEq("0"), true));
431 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
432 // Asserts for RemoveOutboundIPv4SNATMark("vmtap+")
433 EXPECT_CALL(runner,
434 iptables(StrEq("mangle"),
435 ElementsAre("-D", "PREROUTING", "-i", "vmtap+", "-j",
436 "MARK", "--set-mark", "1/1", "-w"),
437 true, nullptr));
438 // Asserts for RemoveForwardEstablishedRule
439 EXPECT_CALL(runner,
440 iptables(StrEq("filter"),
441 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
442 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
443 true, nullptr));
444 // Asserts for RemoveSNATMarkRules
445 EXPECT_CALL(
446 runner,
447 iptables(StrEq("filter"),
448 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
449 "state", "--state", "INVALID", "-j", "DROP", "-w"),
450 true, nullptr));
451 EXPECT_CALL(runner,
452 iptables(StrEq("filter"),
453 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
454 "1/1", "-j", "ACCEPT", "-w"),
455 true, nullptr));
456 EXPECT_CALL(runner,
457 iptables(StrEq("nat"),
458 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
459 "1/1", "-j", "MASQUERADE", "-w"),
460 true, nullptr));
461 // Asserts for RemoveSourceIPv4DropRule() calls.
462 EXPECT_CALL(runner,
463 iptables(StrEq("filter"),
464 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
465 "100.115.92.0/23", "-j", "DROP", "-w"),
466 true, nullptr));
467 EXPECT_CALL(runner,
468 iptables(StrEq("filter"),
469 ElementsAre("-D", "OUTPUT", "-o", "wlan+", "-s",
470 "100.115.92.0/23", "-j", "DROP", "-w"),
471 true, nullptr));
472 EXPECT_CALL(runner,
473 iptables(StrEq("filter"),
474 ElementsAre("-D", "OUTPUT", "-o", "mlan+", "-s",
475 "100.115.92.0/23", "-j", "DROP", "-w"),
476 true, nullptr));
477 EXPECT_CALL(runner,
478 iptables(StrEq("filter"),
479 ElementsAre("-D", "OUTPUT", "-o", "usb+", "-s",
480 "100.115.92.0/23", "-j", "DROP", "-w"),
481 true, nullptr));
482 EXPECT_CALL(runner,
483 iptables(StrEq("filter"),
484 ElementsAre("-D", "OUTPUT", "-o", "wwan+", "-s",
485 "100.115.92.0/23", "-j", "DROP", "-w"),
486 true, nullptr));
487 EXPECT_CALL(runner,
488 iptables(StrEq("filter"),
489 ElementsAre("-D", "OUTPUT", "-o", "rmnet+", "-s",
490 "100.115.92.0/23", "-j", "DROP", "-w"),
491 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900492 // Asserts for apply_local_source_mark chain
493 EXPECT_CALL(runner, iptables(StrEq("mangle"),
494 ElementsAre("-D", "OUTPUT", "-j",
495 "apply_local_source_mark", "-w"),
496 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900497 // Asserts for OUTPUT CONNMARK restore rule
498 EXPECT_CALL(runner, iptables(StrEq("mangle"),
499 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
500 "--restore-mark", "--mask",
501 "0xffff0000", "-w"),
502 true, nullptr));
503 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
504 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
505 "--restore-mark", "--mask",
506 "0xffff0000", "-w"),
507 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900508 EXPECT_CALL(runner,
509 iptables(StrEq("mangle"),
510 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
511 nullptr));
512 EXPECT_CALL(runner,
513 iptables(StrEq("mangle"),
514 ElementsAre("-X", "apply_local_source_mark", "-w"), true,
515 nullptr));
516 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
517 ElementsAre("-D", "OUTPUT", "-j",
518 "apply_local_source_mark", "-w"),
519 true, nullptr));
520 EXPECT_CALL(runner,
521 ip6tables(StrEq("mangle"),
522 ElementsAre("-F", "apply_local_source_mark", "-w"),
523 true, nullptr));
524 EXPECT_CALL(runner,
525 ip6tables(StrEq("mangle"),
526 ElementsAre("-X", "apply_local_source_mark", "-w"),
527 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900528 // Asserts for apply_vpn_mark chain
529 EXPECT_CALL(runner, iptables(StrEq("mangle"),
530 ElementsAre("-D", "OUTPUT", "-m", "mark",
531 "--mark", "0x00008000/0x0000c000",
532 "-j", "apply_vpn_mark", "-w"),
533 true, nullptr));
534 EXPECT_CALL(runner, iptables(StrEq("mangle"),
535 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
536 nullptr));
537 EXPECT_CALL(runner, iptables(StrEq("mangle"),
538 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
539 nullptr));
540 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
541 ElementsAre("-D", "OUTPUT", "-m", "mark",
542 "--mark", "0x00008000/0x0000c000",
543 "-j", "apply_vpn_mark", "-w"),
544 true, nullptr));
545 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
546 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
547 nullptr));
548 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
549 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
550 nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900551
552 Datapath datapath(&runner, &firewall);
553 datapath.Stop();
554}
555
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900556TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900557 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900558 MockFirewall firewall;
559 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900560 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900561 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900562 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900563 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900564 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900565 std::vector<ioctl_req_t> expected = {
566 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
567 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900568 EXPECT_EQ(ioctl_reqs, expected);
569 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900570 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900571}
572
573TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900574 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900575 MockFirewall firewall;
576 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900577 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900578 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900579 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900580 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900581 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900582 std::vector<ioctl_req_t> expected = {
583 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
584 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900585 EXPECT_EQ(ioctl_reqs, expected);
586 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900587 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900588}
589
Garrick Evans621ed262019-11-13 12:28:43 +0900590TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900591 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900592 MockFirewall firewall;
593 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900594 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900595 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900596 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
597 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900598 EXPECT_EQ(ioctl_reqs, expected);
599 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900600 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900601}
602
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900603TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900604 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900605 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900606 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
607 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900608 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900609 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900610}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900611
Hugo Benichi33860d72020-07-09 16:34:01 +0900612TEST(DatapathTest, NetnsAttachName) {
613 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900614 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900615 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
616 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900617 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900618 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
619}
620
621TEST(DatapathTest, NetnsDeleteName) {
622 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900623 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900624 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900625 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900626 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
627}
628
Garrick Evans8a949dc2019-07-18 16:17:53 +0900629TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900630 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900631 MockFirewall firewall;
632 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900633 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900634 EXPECT_CALL(
635 runner,
636 ip(StrEq("addr"), StrEq("add"),
637 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900638 EXPECT_CALL(runner,
639 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900640 EXPECT_CALL(runner, iptables(StrEq("mangle"),
641 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900642 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900643 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900644 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900645}
646
Hugo Benichi76675592020-04-08 14:29:57 +0900647TEST(DatapathTest, ConnectVethPair) {
648 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900649 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900650 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
651 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900652 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900653 true));
654 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
655 ElementsAre("100.115.92.169/30", "brd",
656 "100.115.92.171", "dev", "peer_foo"),
657 true))
658 .WillOnce(Return(0));
659 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
660 ElementsAre("dev", "peer_foo", "up", "addr",
661 "01:02:03:04:05:06", "multicast", "on"),
662 true))
663 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900664 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
665 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900666 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900667 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
668 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900669 Ipv4Addr(100, 115, 92, 169), 30, true));
670}
671
Garrick Evans2470caa2020-03-04 14:15:41 +0900672TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900673 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900674 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900675 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
676 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900677 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900678 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900679 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900680 EXPECT_TRUE(
681 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900682}
683
684TEST(DatapathTest, ToggleInterface) {
685 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900686 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900687 EXPECT_CALL(runner,
688 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900689 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900690 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900691 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900692 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
693 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
694}
695
696TEST(DatapathTest, ConfigureInterface) {
697 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900698 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900699 EXPECT_CALL(
700 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900701 ip(StrEq("addr"), StrEq("add"),
702 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
703 .WillOnce(Return(0));
704 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
705 ElementsAre("dev", "foo", "up", "addr",
706 "02:02:02:02:02:02", "multicast", "on"),
707 true))
708 .WillOnce(Return(0));
709
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900710 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900711 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
712 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
713 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900714}
715
716TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900717 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900718 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900719 EXPECT_CALL(runner,
720 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900721 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900722 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900723}
724
Garrick Evans8a949dc2019-07-18 16:17:53 +0900725TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900726 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900727 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900728 EXPECT_CALL(runner, iptables(StrEq("mangle"),
729 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900730 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900731 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900732 EXPECT_CALL(runner,
733 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900734 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900735 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900736 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900737}
738
Hugo Benichi321f23b2020-09-25 15:42:05 +0900739TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
740 MockProcessRunner runner;
741 MockFirewall firewall;
742 EXPECT_CALL(runner,
743 iptables(StrEq("filter"),
744 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
745 "100.115.92.0/24", "-j", "DROP", "-w"),
746 true, nullptr));
747 EXPECT_CALL(runner,
748 iptables(StrEq("filter"),
749 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
750 "100.115.92.0/24", "-j", "DROP", "-w"),
751 true, nullptr));
752 Datapath datapath(&runner, &firewall);
753 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
754 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
755}
756
Hugo Benichi7c342672020-09-08 09:18:14 +0900757TEST(DatapathTest, StartRoutingNamespace) {
758 MockProcessRunner runner;
759 MockFirewall firewall;
760 MacAddress mac = {1, 2, 3, 4, 5, 6};
761
762 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
763 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
764 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
765 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
766 "veth0", "netns", "netns_foo"),
767 true));
768 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
769 ElementsAre("100.115.92.130/30", "brd",
770 "100.115.92.131", "dev", "veth0"),
771 true))
772 .WillOnce(Return(0));
773 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
774 ElementsAre("dev", "veth0", "up", "addr",
775 "01:02:03:04:05:06", "multicast", "off"),
776 true))
777 .WillOnce(Return(0));
778 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
779 ElementsAre("arc_ns0", "up"), true));
780 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
781 ElementsAre("100.115.92.129/30", "brd",
782 "100.115.92.131", "dev", "arc_ns0"),
783 true))
784 .WillOnce(Return(0));
785 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
786 ElementsAre("dev", "arc_ns0", "up", "addr",
787 "01:02:03:04:05:06", "multicast", "off"),
788 true))
789 .WillOnce(Return(0));
790 EXPECT_CALL(runner, iptables(StrEq("filter"),
791 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
792 "-j", "ACCEPT", "-w"),
793 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900794 EXPECT_CALL(runner, iptables(StrEq("filter"),
795 ElementsAre("-A", "FORWARD", "-i", "arc_ns0",
796 "-j", "ACCEPT", "-w"),
797 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900798 EXPECT_CALL(runner,
799 iptables(StrEq("mangle"),
800 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
801 "MARK", "--set-mark", "1/1", "-w"),
802 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900803 EXPECT_CALL(runner, iptables(StrEq("mangle"),
804 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
805 "-j", "MARK", "--set-mark",
806 "0x00000200/0x00003f00", "-w"),
807 true, nullptr));
808 EXPECT_CALL(runner, iptables(StrEq("mangle"),
809 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
810 "-j", "CONNMARK", "--restore-mark",
811 "--mask", "0xffff0000", "-w"),
812 true, nullptr));
813 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
814 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
815 "-j", "MARK", "--set-mark",
816 "0x00000200/0x00003f00", "-w"),
817 true, nullptr));
818 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
819 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
820 "-j", "CONNMARK", "--restore-mark",
821 "--mask", "0xffff0000", "-w"),
822 true, nullptr));
823 EXPECT_CALL(runner, iptables(StrEq("mangle"),
824 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
825 "-j", "apply_vpn_mark", "-w"),
826 true, nullptr));
827 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
828 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
829 "-j", "apply_vpn_mark", "-w"),
830 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900831
Hugo Benichifcf81022020-12-04 11:01:37 +0900832 ConnectedNamespace nsinfo = {};
833 nsinfo.pid = kTestPID;
834 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900835 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900836 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900837 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900838 nsinfo.host_ifname = "arc_ns0";
839 nsinfo.peer_ifname = "veth0";
840 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
841 base::DoNothing());
842 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900843 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900844 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900845 ioctl_reqs.clear();
846 ioctl_rtentry_args.clear();
847}
848
849TEST(DatapathTest, StopRoutingNamespace) {
850 MockProcessRunner runner;
851 MockFirewall firewall;
852
853 EXPECT_CALL(runner, iptables(StrEq("filter"),
854 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
855 "-j", "ACCEPT", "-w"),
856 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900857 EXPECT_CALL(runner, iptables(StrEq("filter"),
858 ElementsAre("-D", "FORWARD", "-i", "arc_ns0",
859 "-j", "ACCEPT", "-w"),
860 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900861 EXPECT_CALL(runner,
862 iptables(StrEq("mangle"),
863 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
864 "MARK", "--set-mark", "1/1", "-w"),
865 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900866 EXPECT_CALL(runner, iptables(StrEq("mangle"),
867 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
868 "-j", "MARK", "--set-mark",
869 "0x00000200/0x00003f00", "-w"),
870 true, nullptr));
871 EXPECT_CALL(runner, iptables(StrEq("mangle"),
872 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
873 "-j", "CONNMARK", "--restore-mark",
874 "--mask", "0xffff0000", "-w"),
875 true, nullptr));
876 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
877 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
878 "-j", "MARK", "--set-mark",
879 "0x00000200/0x00003f00", "-w"),
880 true, nullptr));
881 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
882 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
883 "-j", "CONNMARK", "--restore-mark",
884 "--mask", "0xffff0000", "-w"),
885 true, nullptr));
886 EXPECT_CALL(runner, iptables(StrEq("mangle"),
887 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
888 "-j", "apply_vpn_mark", "-w"),
889 true, nullptr));
890 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
891 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
892 "-j", "apply_vpn_mark", "-w"),
893 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900894 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
895 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
896 false));
897
Hugo Benichifcf81022020-12-04 11:01:37 +0900898 ConnectedNamespace nsinfo = {};
899 nsinfo.pid = kTestPID;
900 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900901 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900902 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900903 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900904 nsinfo.host_ifname = "arc_ns0";
905 nsinfo.peer_ifname = "veth0";
906 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
907 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900908 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900909 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900910}
911
Hugo Benichi8d622b52020-08-13 15:24:12 +0900912TEST(DatapathTest, StartRoutingDevice_Arc) {
913 MockProcessRunner runner;
914 MockFirewall firewall;
915 EXPECT_CALL(runner, iptables(StrEq("nat"),
916 ElementsAre("-A", "PREROUTING", "-i", "eth0",
917 "-m", "socket", "--nowildcard", "-j",
918 "ACCEPT", "-w"),
919 true, nullptr));
920 EXPECT_CALL(runner, iptables(StrEq("nat"),
921 ElementsAre("-A", "PREROUTING", "-i", "eth0",
922 "-p", "tcp", "-j", "DNAT",
923 "--to-destination", "1.2.3.4", "-w"),
924 true, nullptr));
925 EXPECT_CALL(runner, iptables(StrEq("nat"),
926 ElementsAre("-A", "PREROUTING", "-i", "eth0",
927 "-p", "udp", "-j", "DNAT",
928 "--to-destination", "1.2.3.4", "-w"),
929 true, nullptr));
930 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900931 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
932 "arc_eth0", "-j", "ACCEPT", "-w"),
933 true, nullptr));
934 EXPECT_CALL(runner, iptables(StrEq("filter"),
935 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
936 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +0900937 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900938 EXPECT_CALL(runner, iptables(StrEq("mangle"),
939 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
940 "-j", "MARK", "--set-mark",
941 "0x00002000/0x00003f00", "-w"),
942 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900943 EXPECT_CALL(runner, iptables(StrEq("mangle"),
944 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
945 "-j", "MARK", "--set-mark",
946 "0x03ea0000/0xffff0000", "-w"),
947 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900948 EXPECT_CALL(
949 runner,
950 ip6tables(StrEq("mangle"),
951 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
952 "--set-mark", "0x00002000/0x00003f00", "-w"),
953 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900954 EXPECT_CALL(
955 runner,
956 ip6tables(StrEq("mangle"),
957 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
958 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
959 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900960
961 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900962 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900963 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900964 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900965}
966
967TEST(DatapathTest, StartRoutingDevice_CrosVM) {
968 MockProcessRunner runner;
969 MockFirewall firewall;
970 EXPECT_CALL(runner, iptables(StrEq("filter"),
971 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
972 "-j", "ACCEPT", "-w"),
973 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900974 EXPECT_CALL(runner, iptables(StrEq("filter"),
975 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
976 "-j", "ACCEPT", "-w"),
977 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900978 EXPECT_CALL(runner, iptables(StrEq("mangle"),
979 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
980 "-j", "MARK", "--set-mark",
981 "0x00002100/0x00003f00", "-w"),
982 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900983 EXPECT_CALL(runner, iptables(StrEq("mangle"),
984 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
985 "-j", "CONNMARK", "--restore-mark",
986 "--mask", "0xffff0000", "-w"),
987 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900988 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
989 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
990 "-j", "MARK", "--set-mark",
991 "0x00002100/0x00003f00", "-w"),
992 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900993 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
994 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
995 "-j", "CONNMARK", "--restore-mark",
996 "--mask", "0xffff0000", "-w"),
997 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900998 EXPECT_CALL(runner, iptables(StrEq("mangle"),
999 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1000 "-j", "apply_vpn_mark", "-w"),
1001 true, nullptr));
1002 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1003 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1004 "-j", "apply_vpn_mark", "-w"),
1005 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001006
1007 Datapath datapath(&runner, &firewall);
1008 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001009 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001010}
1011
1012TEST(DatapathTest, StopRoutingDevice_Arc) {
1013 MockProcessRunner runner;
1014 MockFirewall firewall;
1015 EXPECT_CALL(runner, iptables(StrEq("nat"),
1016 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1017 "-m", "socket", "--nowildcard", "-j",
1018 "ACCEPT", "-w"),
1019 true, nullptr));
1020 EXPECT_CALL(runner, iptables(StrEq("nat"),
1021 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1022 "-p", "tcp", "-j", "DNAT",
1023 "--to-destination", "1.2.3.4", "-w"),
1024 true, nullptr));
1025 EXPECT_CALL(runner, iptables(StrEq("nat"),
1026 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1027 "-p", "udp", "-j", "DNAT",
1028 "--to-destination", "1.2.3.4", "-w"),
1029 true, nullptr));
1030 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001031 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1032 "arc_eth0", "-j", "ACCEPT", "-w"),
1033 true, nullptr));
1034 EXPECT_CALL(runner, iptables(StrEq("filter"),
1035 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1036 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001037 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001038 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1039 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1040 "-j", "MARK", "--set-mark",
1041 "0x00002000/0x00003f00", "-w"),
1042 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001043 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1044 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1045 "-j", "MARK", "--set-mark",
1046 "0x03ea0000/0xffff0000", "-w"),
1047 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001048 EXPECT_CALL(
1049 runner,
1050 ip6tables(StrEq("mangle"),
1051 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1052 "--set-mark", "0x00002000/0x00003f00", "-w"),
1053 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001054 EXPECT_CALL(
1055 runner,
1056 ip6tables(StrEq("mangle"),
1057 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1058 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1059 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001060
1061 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001062 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001063 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001064 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001065}
1066
1067TEST(DatapathTest, StopRoutingDevice_CrosVM) {
1068 MockProcessRunner runner;
1069 MockFirewall firewall;
1070 EXPECT_CALL(runner, iptables(StrEq("filter"),
1071 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
1072 "-j", "ACCEPT", "-w"),
1073 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001074 EXPECT_CALL(runner, iptables(StrEq("filter"),
1075 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
1076 "-j", "ACCEPT", "-w"),
1077 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001078 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1079 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1080 "-j", "MARK", "--set-mark",
1081 "0x00002100/0x00003f00", "-w"),
1082 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001083 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1084 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1085 "-j", "CONNMARK", "--restore-mark",
1086 "--mask", "0xffff0000", "-w"),
1087 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001088 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1089 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1090 "-j", "MARK", "--set-mark",
1091 "0x00002100/0x00003f00", "-w"),
1092 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001093 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1094 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1095 "-j", "CONNMARK", "--restore-mark",
1096 "--mask", "0xffff0000", "-w"),
1097 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001098 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1099 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1100 "-j", "apply_vpn_mark", "-w"),
1101 true, nullptr));
1102 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1103 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1104 "-j", "apply_vpn_mark", "-w"),
1105 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001106
1107 Datapath datapath(&runner, &firewall);
1108 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001109 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001110}
1111
Hugo Benichid82d8832020-08-14 10:05:03 +09001112TEST(DatapathTest, StartStopIpForwarding) {
1113 struct {
1114 IpFamily family;
1115 std::string iif;
1116 std::string oif;
1117 std::vector<std::string> start_args;
1118 std::vector<std::string> stop_args;
1119 bool result;
1120 } testcases[] = {
1121 {IpFamily::IPv4, "", "", {}, {}, false},
1122 {IpFamily::NONE, "foo", "bar", {}, {}, false},
1123 {IpFamily::IPv4,
1124 "foo",
1125 "bar",
1126 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1127 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1128 true},
1129 {IpFamily::IPv4,
1130 "",
1131 "bar",
1132 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1133 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1134 true},
1135 {IpFamily::IPv4,
1136 "foo",
1137 "",
1138 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1139 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1140 true},
1141 {IpFamily::IPv6,
1142 "foo",
1143 "bar",
1144 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1145 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1146 true},
1147 {IpFamily::IPv6,
1148 "",
1149 "bar",
1150 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1151 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1152 true},
1153 {IpFamily::IPv6,
1154 "foo",
1155 "",
1156 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1157 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1158 true},
1159 {IpFamily::Dual,
1160 "foo",
1161 "bar",
1162 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1163 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1164 true},
1165 {IpFamily::Dual,
1166 "",
1167 "bar",
1168 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1169 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1170 true},
1171 {IpFamily::Dual,
1172 "foo",
1173 "",
1174 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1175 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1176 true},
1177 };
1178
1179 for (const auto& tt : testcases) {
1180 MockProcessRunner runner;
1181 MockFirewall firewall;
1182 if (tt.result) {
1183 if (tt.family & IpFamily::IPv4) {
1184 EXPECT_CALL(runner,
1185 iptables(StrEq("filter"), tt.start_args, true, nullptr))
1186 .WillOnce(Return(0));
1187 EXPECT_CALL(runner,
1188 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
1189 .WillOnce(Return(0));
1190 }
1191 if (tt.family & IpFamily::IPv6) {
1192 EXPECT_CALL(runner,
1193 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
1194 .WillOnce(Return(0));
1195 EXPECT_CALL(runner,
1196 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
1197 .WillOnce(Return(0));
1198 }
1199 }
1200 Datapath datapath(&runner, &firewall);
1201
1202 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
1203 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
1204 }
1205}
1206
Hugo Benichi76be34a2020-08-26 22:35:54 +09001207TEST(DatapathTest, StartStopConnectionPinning) {
1208 MockProcessRunner runner;
1209 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +09001210
1211 // Setup
Hugo Benichi76be34a2020-08-26 22:35:54 +09001212 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1213 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1214 "-j", "CONNMARK", "--set-mark",
1215 "0x03eb0000/0xffff0000", "-w"),
1216 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001217 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1218 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1219 "-j", "CONNMARK", "--set-mark",
1220 "0x03eb0000/0xffff0000", "-w"),
1221 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001222 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1223 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1224 "-j", "CONNMARK", "--save-mark",
1225 "--mask", "0x00003f00", "-w"),
1226 true, nullptr));
1227 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1228 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1229 "-j", "CONNMARK", "--save-mark",
1230 "--mask", "0x00003f00", "-w"),
1231 true, nullptr));
1232 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1233 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1234 "-j", "CONNMARK", "--restore-mark",
1235 "--mask", "0x00003f00", "-w"),
1236 true, nullptr));
1237 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1238 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1239 "-j", "CONNMARK", "--restore-mark",
1240 "--mask", "0x00003f00", "-w"),
1241 true, nullptr));
1242 // Teardown
1243 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1244 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1245 "-j", "CONNMARK", "--set-mark",
1246 "0x03eb0000/0xffff0000", "-w"),
1247 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001248 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1249 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1250 "-j", "CONNMARK", "--set-mark",
1251 "0x03eb0000/0xffff0000", "-w"),
1252 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001253 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1254 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1255 "-j", "CONNMARK", "--save-mark",
1256 "--mask", "0x00003f00", "-w"),
1257 true, nullptr));
1258 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1259 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1260 "-j", "CONNMARK", "--save-mark",
1261 "--mask", "0x00003f00", "-w"),
1262 true, nullptr));
1263 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1264 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1265 "-j", "CONNMARK", "--restore-mark",
1266 "--mask", "0x00003f00", "-w"),
1267 true, nullptr));
1268 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1269 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1270 "-j", "CONNMARK", "--restore-mark",
1271 "--mask", "0x00003f00", "-w"),
1272 true, nullptr));
1273
Hugo Benichi76be34a2020-08-26 22:35:54 +09001274 Datapath datapath(&runner, &firewall);
1275 datapath.SetIfnameIndex("eth0", 3);
1276 datapath.StartConnectionPinning("eth0");
1277 datapath.StopConnectionPinning("eth0");
1278}
1279
Hugo Benichibfc49112020-12-14 12:54:44 +09001280TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +09001281 MockProcessRunner runner;
1282 MockFirewall firewall;
1283
1284 // Setup
1285 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1286 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1287 "-j", "CONNMARK", "--set-mark",
1288 "0x03ed0000/0xffff0000", "-w"),
1289 true, nullptr));
1290 EXPECT_CALL(runner,
1291 iptables(StrEq("mangle"),
1292 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1293 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1294 true, nullptr));
1295 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1296 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1297 "-j", "CONNMARK", "--set-mark",
1298 "0x03ed0000/0xffff0000", "-w"),
1299 true, nullptr));
1300 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1301 ElementsAre("-A", "apply_vpn_mark", "-j",
1302 "MARK", "--set-mark",
1303 "0x03ed0000/0xffff0000", "-w"),
1304 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001305 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1306 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1307 "-j", "CONNMARK", "--save-mark",
1308 "--mask", "0x00003f00", "-w"),
1309 true, nullptr));
1310 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1311 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1312 "-j", "CONNMARK", "--save-mark",
1313 "--mask", "0x00003f00", "-w"),
1314 true, nullptr));
1315 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1316 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1317 "-j", "CONNMARK", "--restore-mark",
1318 "--mask", "0x00003f00", "-w"),
1319 true, nullptr));
1320 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1321 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1322 "-j", "CONNMARK", "--restore-mark",
1323 "--mask", "0x00003f00", "-w"),
1324 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001325 EXPECT_CALL(runner, iptables(StrEq("nat"),
1326 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1327 "-j", "MASQUERADE", "-w"),
1328 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001329 // Teardown
1330 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1331 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1332 "-j", "CONNMARK", "--set-mark",
1333 "0x03ed0000/0xffff0000", "-w"),
1334 true, nullptr));
1335 EXPECT_CALL(runner,
1336 iptables(StrEq("mangle"),
1337 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1338 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1339 true, nullptr));
1340 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1341 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1342 "-j", "CONNMARK", "--set-mark",
1343 "0x03ed0000/0xffff0000", "-w"),
1344 true, nullptr));
1345 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1346 ElementsAre("-D", "apply_vpn_mark", "-j",
1347 "MARK", "--set-mark",
1348 "0x03ed0000/0xffff0000", "-w"),
1349 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001350 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1351 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1352 "-j", "CONNMARK", "--save-mark",
1353 "--mask", "0x00003f00", "-w"),
1354 true, nullptr));
1355 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1356 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1357 "-j", "CONNMARK", "--save-mark",
1358 "--mask", "0x00003f00", "-w"),
1359 true, nullptr));
1360 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1361 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1362 "-j", "CONNMARK", "--restore-mark",
1363 "--mask", "0x00003f00", "-w"),
1364 true, nullptr));
1365 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1366 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1367 "-j", "CONNMARK", "--restore-mark",
1368 "--mask", "0x00003f00", "-w"),
1369 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001370 EXPECT_CALL(runner, iptables(StrEq("nat"),
1371 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1372 "-j", "MASQUERADE", "-w"),
1373 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001374
1375 Datapath datapath(&runner, &firewall);
1376 datapath.SetIfnameIndex("arcbr0", 5);
1377 datapath.StartVpnRouting("arcbr0");
1378 datapath.StopVpnRouting("arcbr0");
1379}
1380
Hugo Benichibfc49112020-12-14 12:54:44 +09001381TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
1382 MockProcessRunner runner;
1383 MockFirewall firewall;
1384
1385 // Setup
1386 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1387 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1388 "-j", "CONNMARK", "--set-mark",
1389 "0x03ed0000/0xffff0000", "-w"),
1390 true, nullptr));
1391 EXPECT_CALL(runner,
1392 iptables(StrEq("mangle"),
1393 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1394 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1395 true, nullptr));
1396 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1397 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1398 "-j", "CONNMARK", "--set-mark",
1399 "0x03ed0000/0xffff0000", "-w"),
1400 true, nullptr));
1401 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1402 ElementsAre("-A", "apply_vpn_mark", "-j",
1403 "MARK", "--set-mark",
1404 "0x03ed0000/0xffff0000", "-w"),
1405 true, nullptr));
1406 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1407 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1408 "-j", "CONNMARK", "--save-mark",
1409 "--mask", "0x00003f00", "-w"),
1410 true, nullptr));
1411 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1412 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1413 "-j", "CONNMARK", "--save-mark",
1414 "--mask", "0x00003f00", "-w"),
1415 true, nullptr));
1416 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1417 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1418 "-j", "CONNMARK", "--restore-mark",
1419 "--mask", "0x00003f00", "-w"),
1420 true, nullptr));
1421 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1422 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1423 "-j", "CONNMARK", "--restore-mark",
1424 "--mask", "0x00003f00", "-w"),
1425 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001426 EXPECT_CALL(runner, iptables(StrEq("nat"),
1427 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1428 "-j", "MASQUERADE", "-w"),
1429 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001430 // Teardown
1431 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1432 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1433 "-j", "CONNMARK", "--set-mark",
1434 "0x03ed0000/0xffff0000", "-w"),
1435 true, nullptr));
1436 EXPECT_CALL(runner,
1437 iptables(StrEq("mangle"),
1438 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1439 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1440 true, nullptr));
1441 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1442 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1443 "-j", "CONNMARK", "--set-mark",
1444 "0x03ed0000/0xffff0000", "-w"),
1445 true, nullptr));
1446 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1447 ElementsAre("-D", "apply_vpn_mark", "-j",
1448 "MARK", "--set-mark",
1449 "0x03ed0000/0xffff0000", "-w"),
1450 true, nullptr));
1451 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1452 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1453 "-j", "CONNMARK", "--save-mark",
1454 "--mask", "0x00003f00", "-w"),
1455 true, nullptr));
1456 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1457 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1458 "-j", "CONNMARK", "--save-mark",
1459 "--mask", "0x00003f00", "-w"),
1460 true, nullptr));
1461 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1462 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1463 "-j", "CONNMARK", "--restore-mark",
1464 "--mask", "0x00003f00", "-w"),
1465 true, nullptr));
1466 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1467 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1468 "-j", "CONNMARK", "--restore-mark",
1469 "--mask", "0x00003f00", "-w"),
1470 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001471 EXPECT_CALL(runner, iptables(StrEq("nat"),
1472 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1473 "-j", "MASQUERADE", "-w"),
1474 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001475 // Start tun0 <-> arcbr0 routing
1476 EXPECT_CALL(runner, iptables(StrEq("filter"),
1477 ElementsAre("-A", "FORWARD", "-i", "tun0", "-o",
1478 "arcbr0", "-j", "ACCEPT", "-w"),
1479 true, nullptr));
1480 EXPECT_CALL(runner, iptables(StrEq("filter"),
1481 ElementsAre("-A", "FORWARD", "-i", "arcbr0",
1482 "-o", "tun0", "-j", "ACCEPT", "-w"),
1483 true, nullptr));
1484 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1485 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1486 "-j", "MARK", "--set-mark",
1487 "0x00002000/0x00003f00", "-w"),
1488 true, nullptr));
1489 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1490 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1491 "-j", "MARK", "--set-mark",
1492 "0x03ed0000/0xffff0000", "-w"),
1493 true, nullptr));
1494 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1495 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1496 "-j", "MARK", "--set-mark",
1497 "0x00002000/0x00003f00", "-w"),
1498 true, nullptr));
1499 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1500 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1501 "-j", "MARK", "--set-mark",
1502 "0x03ed0000/0xffff0000", "-w"),
1503 true, nullptr));
1504 // Stop tun0 <-> arcbr0 routing
1505 EXPECT_CALL(runner, iptables(StrEq("filter"),
1506 ElementsAre("-D", "FORWARD", "-i", "tun0", "-o",
1507 "arcbr0", "-j", "ACCEPT", "-w"),
1508 true, nullptr));
1509 EXPECT_CALL(runner, iptables(StrEq("filter"),
1510 ElementsAre("-D", "FORWARD", "-i", "arcbr0",
1511 "-o", "tun0", "-j", "ACCEPT", "-w"),
1512 true, nullptr));
1513 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1514 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1515 "-j", "MARK", "--set-mark",
1516 "0x00002000/0x00003f00", "-w"),
1517 true, nullptr));
1518 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1519 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1520 "-j", "MARK", "--set-mark",
1521 "0x03ed0000/0xffff0000", "-w"),
1522 true, nullptr));
1523 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1524 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1525 "-j", "MARK", "--set-mark",
1526 "0x00002000/0x00003f00", "-w"),
1527 true, nullptr));
1528 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1529 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1530 "-j", "MARK", "--set-mark",
1531 "0x03ed0000/0xffff0000", "-w"),
1532 true, nullptr));
1533
1534 Datapath datapath(&runner, &firewall);
1535 datapath.SetIfnameIndex("tun0", 5);
1536 datapath.StartVpnRouting("tun0");
1537 datapath.StopVpnRouting("tun0");
1538}
1539
Garrick Evansf0ab7132019-06-18 14:50:42 +09001540TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001541 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001542 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001543 EXPECT_CALL(runner, iptables(StrEq("nat"),
1544 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1545 "-m", "socket", "--nowildcard", "-j",
1546 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001547 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001548 EXPECT_CALL(runner, iptables(StrEq("nat"),
1549 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1550 "-p", "tcp", "-j", "DNAT",
1551 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001552 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001553 EXPECT_CALL(runner, iptables(StrEq("nat"),
1554 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1555 "-p", "udp", "-j", "DNAT",
1556 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001557 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001558 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001559 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001560}
1561
1562TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001563 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001564 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001565 EXPECT_CALL(runner, iptables(StrEq("nat"),
1566 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1567 "-m", "socket", "--nowildcard", "-j",
1568 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001569 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001570 EXPECT_CALL(runner, iptables(StrEq("nat"),
1571 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1572 "-p", "tcp", "-j", "DNAT",
1573 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001574 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001575 EXPECT_CALL(runner, iptables(StrEq("nat"),
1576 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1577 "-p", "udp", "-j", "DNAT",
1578 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001579 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001580 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001581 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001582}
1583
Garrick Evans664a82f2019-12-17 12:18:05 +09001584TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001585 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001586 MockFirewall firewall;
1587 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001588
Garrick Evans664a82f2019-12-17 12:18:05 +09001589 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001590 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001591 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001592 EXPECT_EQ(ioctl_reqs, expected);
1593 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001594 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001595}
1596
1597TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001598 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001599 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001600 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001601 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1602 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1603 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001604 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001605 .WillOnce(Return(1));
1606 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1607 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1608 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001609 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001610 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1611 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1612 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001613 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001614 .WillOnce(Return(1));
1615 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1616 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1617 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001618 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001619 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001620 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001621}
1622
Taoyu Lica49c832019-12-06 17:56:43 +09001623TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001624 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001625 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001626 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1627 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1628 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001629 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001630 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1631 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1632 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001633 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001634 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001635 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001636}
1637
Taoyu Li90c13912019-11-26 17:56:54 +09001638TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001639 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001640 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001641 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1642 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1643 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001644 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001645 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1646 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1647 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001648 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001649 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001650 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001651}
1652
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001653TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001654 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001655 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001656 EXPECT_CALL(runner,
1657 ip6(StrEq("route"), StrEq("replace"),
1658 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001659 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001660 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001661}
1662
Hugo Benichie8758b52020-04-03 14:49:01 +09001663TEST(DatapathTest, AddIPv4Route) {
1664 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001665 MockFirewall firewall;
1666 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001667
1668 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1669 Ipv4Addr(255, 255, 255, 0));
1670 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1671 Ipv4Addr(255, 255, 255, 0));
1672 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1673 Ipv4Addr(255, 255, 255, 252));
1674 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1675 Ipv4Addr(255, 255, 255, 252));
1676
1677 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1678 SIOCDELRT};
1679 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001680
1681 std::string route1 =
1682 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1683 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1684 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1685 "RTF_GATEWAY}";
1686 std::string route2 =
1687 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1688 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1689 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1690 std::vector<std::string> captured_routes;
1691 for (const auto& route : ioctl_rtentry_args) {
1692 std::ostringstream stream;
1693 stream << route.second;
1694 captured_routes.emplace_back(stream.str());
1695 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001696 EXPECT_EQ(route1, captured_routes[0]);
1697 EXPECT_EQ(route1, captured_routes[1]);
1698 EXPECT_EQ(route2, captured_routes[2]);
1699 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001700 ioctl_reqs.clear();
1701 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001702}
1703
Garrick Evansd291af62020-05-25 10:39:06 +09001704TEST(DatapathTest, AddSNATMarkRules) {
1705 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001706 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +09001707 EXPECT_CALL(
1708 runner,
1709 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +09001710 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +09001711 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001712 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +09001713 EXPECT_CALL(runner,
1714 iptables(StrEq("filter"),
1715 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark",
1716 "1/1", "-j", "ACCEPT", "-w"),
1717 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +09001718 EXPECT_CALL(runner,
1719 iptables(StrEq("nat"),
1720 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +09001721 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001722 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001723 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001724 datapath.AddSNATMarkRules();
1725}
1726
1727TEST(DatapathTest, RemoveSNATMarkRules) {
1728 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001729 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +09001730 EXPECT_CALL(
1731 runner,
1732 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +09001733 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +09001734 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001735 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +09001736 EXPECT_CALL(runner,
1737 iptables(StrEq("filter"),
1738 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
1739 "1/1", "-j", "ACCEPT", "-w"),
1740 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +09001741 EXPECT_CALL(runner,
1742 iptables(StrEq("nat"),
1743 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +09001744 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001745 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001746 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001747 datapath.RemoveSNATMarkRules();
1748}
1749
Garrick Evans2f581a02020-05-11 10:43:35 +09001750TEST(DatapathTest, ArcVethHostName) {
1751 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1752 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1753 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1754 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1755 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1756 EXPECT_EQ("vethexceeds_ify", ifname);
1757 EXPECT_LT(ifname.length(), IFNAMSIZ);
1758}
1759
Garrick Evans8a067562020-05-11 12:47:30 +09001760TEST(DatapathTest, ArcBridgeName) {
1761 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1762 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1763 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1764 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1765 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1766 EXPECT_EQ("arc_exceeds_ify", ifname);
1767 EXPECT_LT(ifname.length(), IFNAMSIZ);
1768}
1769
Garrick Evans3388a032020-03-24 11:25:55 +09001770} // namespace patchpanel