blob: 8418767d155805321c9f1a5a32ac9210b7a6b2ad [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 Benichi155de002021-01-19 16:45:46 +0900418 // Asserts for check_routing_mark chain
419 EXPECT_CALL(runner, iptables(StrEq("mangle"),
420 ElementsAre("-N", "check_routing_mark", "-w"),
421 true, nullptr));
422 EXPECT_CALL(runner, iptables(StrEq("mangle"),
423 ElementsAre("-F", "check_routing_mark", "-w"),
424 true, nullptr));
425 EXPECT_CALL(runner, iptables(StrEq("mangle"),
426 ElementsAre("-A", "POSTROUTING", "-j",
427 "CONNMARK", "--restore-mark",
428 "--mask", "0xffff0000", "-w"),
429 true, nullptr));
430 EXPECT_CALL(runner, iptables(StrEq("mangle"),
431 ElementsAre("-A", "POSTROUTING", "-m", "mark",
432 "!", "--mark", "0x0/0xffff0000",
433 "-j", "check_routing_mark", "-w"),
434 true, nullptr));
435 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
436 ElementsAre("-N", "check_routing_mark", "-w"),
437 true, nullptr));
438 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
439 ElementsAre("-F", "check_routing_mark", "-w"),
440 true, nullptr));
441 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
442 ElementsAre("-A", "POSTROUTING", "-j",
443 "CONNMARK", "--restore-mark",
444 "--mask", "0xffff0000", "-w"),
445 true, nullptr));
446 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
447 ElementsAre("-A", "POSTROUTING", "-m", "mark",
448 "!", "--mark", "0x0/0xffff0000",
449 "-j", "check_routing_mark", "-w"),
450 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900451
452 Datapath datapath(&runner, &firewall);
453 datapath.Start();
454}
455
456TEST(DatapathTest, Stop) {
457 MockProcessRunner runner;
458 MockFirewall firewall;
459 // Asserts for sysctl modifications
460 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
461 StrEq("32768 61000"), true));
462 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
463 StrEq("0"), true));
464 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
465 // Asserts for RemoveOutboundIPv4SNATMark("vmtap+")
466 EXPECT_CALL(runner,
467 iptables(StrEq("mangle"),
468 ElementsAre("-D", "PREROUTING", "-i", "vmtap+", "-j",
469 "MARK", "--set-mark", "1/1", "-w"),
470 true, nullptr));
471 // Asserts for RemoveForwardEstablishedRule
472 EXPECT_CALL(runner,
473 iptables(StrEq("filter"),
474 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
475 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
476 true, nullptr));
477 // Asserts for RemoveSNATMarkRules
478 EXPECT_CALL(
479 runner,
480 iptables(StrEq("filter"),
481 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
482 "state", "--state", "INVALID", "-j", "DROP", "-w"),
483 true, nullptr));
484 EXPECT_CALL(runner,
485 iptables(StrEq("filter"),
486 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
487 "1/1", "-j", "ACCEPT", "-w"),
488 true, nullptr));
489 EXPECT_CALL(runner,
490 iptables(StrEq("nat"),
491 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
492 "1/1", "-j", "MASQUERADE", "-w"),
493 true, nullptr));
494 // Asserts for RemoveSourceIPv4DropRule() calls.
495 EXPECT_CALL(runner,
496 iptables(StrEq("filter"),
497 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
498 "100.115.92.0/23", "-j", "DROP", "-w"),
499 true, nullptr));
500 EXPECT_CALL(runner,
501 iptables(StrEq("filter"),
502 ElementsAre("-D", "OUTPUT", "-o", "wlan+", "-s",
503 "100.115.92.0/23", "-j", "DROP", "-w"),
504 true, nullptr));
505 EXPECT_CALL(runner,
506 iptables(StrEq("filter"),
507 ElementsAre("-D", "OUTPUT", "-o", "mlan+", "-s",
508 "100.115.92.0/23", "-j", "DROP", "-w"),
509 true, nullptr));
510 EXPECT_CALL(runner,
511 iptables(StrEq("filter"),
512 ElementsAre("-D", "OUTPUT", "-o", "usb+", "-s",
513 "100.115.92.0/23", "-j", "DROP", "-w"),
514 true, nullptr));
515 EXPECT_CALL(runner,
516 iptables(StrEq("filter"),
517 ElementsAre("-D", "OUTPUT", "-o", "wwan+", "-s",
518 "100.115.92.0/23", "-j", "DROP", "-w"),
519 true, nullptr));
520 EXPECT_CALL(runner,
521 iptables(StrEq("filter"),
522 ElementsAre("-D", "OUTPUT", "-o", "rmnet+", "-s",
523 "100.115.92.0/23", "-j", "DROP", "-w"),
524 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900525 // Asserts for apply_local_source_mark chain
526 EXPECT_CALL(runner, iptables(StrEq("mangle"),
527 ElementsAre("-D", "OUTPUT", "-j",
528 "apply_local_source_mark", "-w"),
529 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900530 // Asserts for OUTPUT CONNMARK restore rule
531 EXPECT_CALL(runner, iptables(StrEq("mangle"),
532 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
533 "--restore-mark", "--mask",
534 "0xffff0000", "-w"),
535 true, nullptr));
536 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
537 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
538 "--restore-mark", "--mask",
539 "0xffff0000", "-w"),
540 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900541 EXPECT_CALL(runner,
542 iptables(StrEq("mangle"),
543 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
544 nullptr));
545 EXPECT_CALL(runner,
546 iptables(StrEq("mangle"),
547 ElementsAre("-X", "apply_local_source_mark", "-w"), true,
548 nullptr));
549 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
550 ElementsAre("-D", "OUTPUT", "-j",
551 "apply_local_source_mark", "-w"),
552 true, nullptr));
553 EXPECT_CALL(runner,
554 ip6tables(StrEq("mangle"),
555 ElementsAre("-F", "apply_local_source_mark", "-w"),
556 true, nullptr));
557 EXPECT_CALL(runner,
558 ip6tables(StrEq("mangle"),
559 ElementsAre("-X", "apply_local_source_mark", "-w"),
560 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900561 // Asserts for apply_vpn_mark chain
562 EXPECT_CALL(runner, iptables(StrEq("mangle"),
563 ElementsAre("-D", "OUTPUT", "-m", "mark",
564 "--mark", "0x00008000/0x0000c000",
565 "-j", "apply_vpn_mark", "-w"),
566 true, nullptr));
567 EXPECT_CALL(runner, iptables(StrEq("mangle"),
568 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
569 nullptr));
570 EXPECT_CALL(runner, iptables(StrEq("mangle"),
571 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
572 nullptr));
573 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
574 ElementsAre("-D", "OUTPUT", "-m", "mark",
575 "--mark", "0x00008000/0x0000c000",
576 "-j", "apply_vpn_mark", "-w"),
577 true, nullptr));
578 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
579 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
580 nullptr));
581 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
582 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
583 nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900584 // Asserts for check_routing_mark chain
585 EXPECT_CALL(runner, iptables(StrEq("mangle"),
586 ElementsAre("-D", "POSTROUTING", "-j",
587 "CONNMARK", "--restore-mark",
588 "--mask", "0xffff0000", "-w"),
589 true, nullptr));
590 EXPECT_CALL(runner, iptables(StrEq("mangle"),
591 ElementsAre("-D", "POSTROUTING", "-m", "mark",
592 "!", "--mark", "0x0/0xffff0000",
593 "-j", "check_routing_mark", "-w"),
594 true, nullptr));
595 EXPECT_CALL(runner, iptables(StrEq("mangle"),
596 ElementsAre("-F", "check_routing_mark", "-w"),
597 true, nullptr));
598 EXPECT_CALL(runner, iptables(StrEq("mangle"),
599 ElementsAre("-X", "check_routing_mark", "-w"),
600 true, nullptr));
601 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
602 ElementsAre("-D", "POSTROUTING", "-j",
603 "CONNMARK", "--restore-mark",
604 "--mask", "0xffff0000", "-w"),
605 true, nullptr));
606 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
607 ElementsAre("-D", "POSTROUTING", "-m", "mark",
608 "!", "--mark", "0x0/0xffff0000",
609 "-j", "check_routing_mark", "-w"),
610 true, nullptr));
611 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
612 ElementsAre("-F", "check_routing_mark", "-w"),
613 true, nullptr));
614 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
615 ElementsAre("-X", "check_routing_mark", "-w"),
616 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900617
618 Datapath datapath(&runner, &firewall);
619 datapath.Stop();
620}
621
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900622TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900623 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900624 MockFirewall firewall;
625 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900626 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900627 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900628 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900629 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900630 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900631 std::vector<ioctl_req_t> expected = {
632 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
633 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900634 EXPECT_EQ(ioctl_reqs, expected);
635 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900636 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900637}
638
639TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900640 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900641 MockFirewall firewall;
642 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900643 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900644 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900645 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900646 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900647 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900648 std::vector<ioctl_req_t> expected = {
649 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
650 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900651 EXPECT_EQ(ioctl_reqs, expected);
652 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900653 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900654}
655
Garrick Evans621ed262019-11-13 12:28:43 +0900656TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900657 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900658 MockFirewall firewall;
659 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900660 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900661 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900662 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
663 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900664 EXPECT_EQ(ioctl_reqs, expected);
665 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900666 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900667}
668
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900669TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900670 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900671 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900672 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
673 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900674 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900675 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900676}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900677
Hugo Benichi33860d72020-07-09 16:34:01 +0900678TEST(DatapathTest, NetnsAttachName) {
679 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900680 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900681 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
682 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900683 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900684 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
685}
686
687TEST(DatapathTest, NetnsDeleteName) {
688 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900689 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900690 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900691 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900692 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
693}
694
Garrick Evans8a949dc2019-07-18 16:17:53 +0900695TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900696 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900697 MockFirewall firewall;
698 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900699 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900700 EXPECT_CALL(
701 runner,
702 ip(StrEq("addr"), StrEq("add"),
703 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900704 EXPECT_CALL(runner,
705 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900706 EXPECT_CALL(runner, iptables(StrEq("mangle"),
707 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900708 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900709 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900710 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900711}
712
Hugo Benichi76675592020-04-08 14:29:57 +0900713TEST(DatapathTest, ConnectVethPair) {
714 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900715 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900716 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
717 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900718 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900719 true));
720 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
721 ElementsAre("100.115.92.169/30", "brd",
722 "100.115.92.171", "dev", "peer_foo"),
723 true))
724 .WillOnce(Return(0));
725 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
726 ElementsAre("dev", "peer_foo", "up", "addr",
727 "01:02:03:04:05:06", "multicast", "on"),
728 true))
729 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900730 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
731 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900732 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900733 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
734 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900735 Ipv4Addr(100, 115, 92, 169), 30, true));
736}
737
Garrick Evans2470caa2020-03-04 14:15:41 +0900738TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900739 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900740 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900741 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
742 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900743 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900744 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900745 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900746 EXPECT_TRUE(
747 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900748}
749
750TEST(DatapathTest, ToggleInterface) {
751 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900752 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900753 EXPECT_CALL(runner,
754 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900755 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900756 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900757 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900758 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
759 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
760}
761
762TEST(DatapathTest, ConfigureInterface) {
763 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900764 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900765 EXPECT_CALL(
766 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900767 ip(StrEq("addr"), StrEq("add"),
768 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
769 .WillOnce(Return(0));
770 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
771 ElementsAre("dev", "foo", "up", "addr",
772 "02:02:02:02:02:02", "multicast", "on"),
773 true))
774 .WillOnce(Return(0));
775
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900776 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900777 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
778 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
779 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900780}
781
782TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900783 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900784 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900785 EXPECT_CALL(runner,
786 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900787 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900788 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900789}
790
Garrick Evans8a949dc2019-07-18 16:17:53 +0900791TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900792 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900793 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900794 EXPECT_CALL(runner, iptables(StrEq("mangle"),
795 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900796 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900797 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900798 EXPECT_CALL(runner,
799 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900800 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900801 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900802 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900803}
804
Hugo Benichi321f23b2020-09-25 15:42:05 +0900805TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
806 MockProcessRunner runner;
807 MockFirewall firewall;
808 EXPECT_CALL(runner,
809 iptables(StrEq("filter"),
810 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
811 "100.115.92.0/24", "-j", "DROP", "-w"),
812 true, nullptr));
813 EXPECT_CALL(runner,
814 iptables(StrEq("filter"),
815 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
816 "100.115.92.0/24", "-j", "DROP", "-w"),
817 true, nullptr));
818 Datapath datapath(&runner, &firewall);
819 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
820 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
821}
822
Hugo Benichi7c342672020-09-08 09:18:14 +0900823TEST(DatapathTest, StartRoutingNamespace) {
824 MockProcessRunner runner;
825 MockFirewall firewall;
826 MacAddress mac = {1, 2, 3, 4, 5, 6};
827
828 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
829 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
830 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
831 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
832 "veth0", "netns", "netns_foo"),
833 true));
834 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
835 ElementsAre("100.115.92.130/30", "brd",
836 "100.115.92.131", "dev", "veth0"),
837 true))
838 .WillOnce(Return(0));
839 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
840 ElementsAre("dev", "veth0", "up", "addr",
841 "01:02:03:04:05:06", "multicast", "off"),
842 true))
843 .WillOnce(Return(0));
844 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
845 ElementsAre("arc_ns0", "up"), true));
846 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
847 ElementsAre("100.115.92.129/30", "brd",
848 "100.115.92.131", "dev", "arc_ns0"),
849 true))
850 .WillOnce(Return(0));
851 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
852 ElementsAre("dev", "arc_ns0", "up", "addr",
853 "01:02:03:04:05:06", "multicast", "off"),
854 true))
855 .WillOnce(Return(0));
856 EXPECT_CALL(runner, iptables(StrEq("filter"),
857 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
858 "-j", "ACCEPT", "-w"),
859 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900860 EXPECT_CALL(runner, iptables(StrEq("filter"),
861 ElementsAre("-A", "FORWARD", "-i", "arc_ns0",
862 "-j", "ACCEPT", "-w"),
863 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900864 EXPECT_CALL(runner,
865 iptables(StrEq("mangle"),
866 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
867 "MARK", "--set-mark", "1/1", "-w"),
868 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900869 EXPECT_CALL(runner, iptables(StrEq("mangle"),
870 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
871 "-j", "MARK", "--set-mark",
872 "0x00000200/0x00003f00", "-w"),
873 true, nullptr));
874 EXPECT_CALL(runner, iptables(StrEq("mangle"),
875 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
876 "-j", "CONNMARK", "--restore-mark",
877 "--mask", "0xffff0000", "-w"),
878 true, nullptr));
879 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
880 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
881 "-j", "MARK", "--set-mark",
882 "0x00000200/0x00003f00", "-w"),
883 true, nullptr));
884 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
885 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
886 "-j", "CONNMARK", "--restore-mark",
887 "--mask", "0xffff0000", "-w"),
888 true, nullptr));
889 EXPECT_CALL(runner, iptables(StrEq("mangle"),
890 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
891 "-j", "apply_vpn_mark", "-w"),
892 true, nullptr));
893 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
894 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
895 "-j", "apply_vpn_mark", "-w"),
896 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900897
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());
908 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900909 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900910 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900911 ioctl_reqs.clear();
912 ioctl_rtentry_args.clear();
913}
914
915TEST(DatapathTest, StopRoutingNamespace) {
916 MockProcessRunner runner;
917 MockFirewall firewall;
918
919 EXPECT_CALL(runner, iptables(StrEq("filter"),
920 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
921 "-j", "ACCEPT", "-w"),
922 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900923 EXPECT_CALL(runner, iptables(StrEq("filter"),
924 ElementsAre("-D", "FORWARD", "-i", "arc_ns0",
925 "-j", "ACCEPT", "-w"),
926 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900927 EXPECT_CALL(runner,
928 iptables(StrEq("mangle"),
929 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
930 "MARK", "--set-mark", "1/1", "-w"),
931 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900932 EXPECT_CALL(runner, iptables(StrEq("mangle"),
933 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
934 "-j", "MARK", "--set-mark",
935 "0x00000200/0x00003f00", "-w"),
936 true, nullptr));
937 EXPECT_CALL(runner, iptables(StrEq("mangle"),
938 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
939 "-j", "CONNMARK", "--restore-mark",
940 "--mask", "0xffff0000", "-w"),
941 true, nullptr));
942 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
943 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
944 "-j", "MARK", "--set-mark",
945 "0x00000200/0x00003f00", "-w"),
946 true, nullptr));
947 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
948 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
949 "-j", "CONNMARK", "--restore-mark",
950 "--mask", "0xffff0000", "-w"),
951 true, nullptr));
952 EXPECT_CALL(runner, iptables(StrEq("mangle"),
953 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
954 "-j", "apply_vpn_mark", "-w"),
955 true, nullptr));
956 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
957 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
958 "-j", "apply_vpn_mark", "-w"),
959 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900960 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
961 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
962 false));
963
Hugo Benichifcf81022020-12-04 11:01:37 +0900964 ConnectedNamespace nsinfo = {};
965 nsinfo.pid = kTestPID;
966 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900967 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900968 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900969 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900970 nsinfo.host_ifname = "arc_ns0";
971 nsinfo.peer_ifname = "veth0";
972 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
973 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900974 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900975 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900976}
977
Hugo Benichi8d622b52020-08-13 15:24:12 +0900978TEST(DatapathTest, StartRoutingDevice_Arc) {
979 MockProcessRunner runner;
980 MockFirewall firewall;
981 EXPECT_CALL(runner, iptables(StrEq("nat"),
982 ElementsAre("-A", "PREROUTING", "-i", "eth0",
983 "-m", "socket", "--nowildcard", "-j",
984 "ACCEPT", "-w"),
985 true, nullptr));
986 EXPECT_CALL(runner, iptables(StrEq("nat"),
987 ElementsAre("-A", "PREROUTING", "-i", "eth0",
988 "-p", "tcp", "-j", "DNAT",
989 "--to-destination", "1.2.3.4", "-w"),
990 true, nullptr));
991 EXPECT_CALL(runner, iptables(StrEq("nat"),
992 ElementsAre("-A", "PREROUTING", "-i", "eth0",
993 "-p", "udp", "-j", "DNAT",
994 "--to-destination", "1.2.3.4", "-w"),
995 true, nullptr));
996 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900997 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
998 "arc_eth0", "-j", "ACCEPT", "-w"),
999 true, nullptr));
1000 EXPECT_CALL(runner, iptables(StrEq("filter"),
1001 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1002 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001003 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001004 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1005 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1006 "-j", "MARK", "--set-mark",
1007 "0x00002000/0x00003f00", "-w"),
1008 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001009 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1010 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1011 "-j", "MARK", "--set-mark",
1012 "0x03ea0000/0xffff0000", "-w"),
1013 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001014 EXPECT_CALL(
1015 runner,
1016 ip6tables(StrEq("mangle"),
1017 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1018 "--set-mark", "0x00002000/0x00003f00", "-w"),
1019 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001020 EXPECT_CALL(
1021 runner,
1022 ip6tables(StrEq("mangle"),
1023 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1024 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1025 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001026
1027 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001028 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001029 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001030 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001031}
1032
1033TEST(DatapathTest, StartRoutingDevice_CrosVM) {
1034 MockProcessRunner runner;
1035 MockFirewall firewall;
1036 EXPECT_CALL(runner, iptables(StrEq("filter"),
1037 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
1038 "-j", "ACCEPT", "-w"),
1039 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001040 EXPECT_CALL(runner, iptables(StrEq("filter"),
1041 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
1042 "-j", "ACCEPT", "-w"),
1043 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001044 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1045 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1046 "-j", "MARK", "--set-mark",
1047 "0x00002100/0x00003f00", "-w"),
1048 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001049 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1050 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1051 "-j", "CONNMARK", "--restore-mark",
1052 "--mask", "0xffff0000", "-w"),
1053 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001054 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1055 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1056 "-j", "MARK", "--set-mark",
1057 "0x00002100/0x00003f00", "-w"),
1058 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001059 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1060 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1061 "-j", "CONNMARK", "--restore-mark",
1062 "--mask", "0xffff0000", "-w"),
1063 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001064 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1065 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1066 "-j", "apply_vpn_mark", "-w"),
1067 true, nullptr));
1068 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1069 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1070 "-j", "apply_vpn_mark", "-w"),
1071 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001072
1073 Datapath datapath(&runner, &firewall);
1074 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001075 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001076}
1077
1078TEST(DatapathTest, StopRoutingDevice_Arc) {
1079 MockProcessRunner runner;
1080 MockFirewall firewall;
1081 EXPECT_CALL(runner, iptables(StrEq("nat"),
1082 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1083 "-m", "socket", "--nowildcard", "-j",
1084 "ACCEPT", "-w"),
1085 true, nullptr));
1086 EXPECT_CALL(runner, iptables(StrEq("nat"),
1087 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1088 "-p", "tcp", "-j", "DNAT",
1089 "--to-destination", "1.2.3.4", "-w"),
1090 true, nullptr));
1091 EXPECT_CALL(runner, iptables(StrEq("nat"),
1092 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1093 "-p", "udp", "-j", "DNAT",
1094 "--to-destination", "1.2.3.4", "-w"),
1095 true, nullptr));
1096 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001097 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1098 "arc_eth0", "-j", "ACCEPT", "-w"),
1099 true, nullptr));
1100 EXPECT_CALL(runner, iptables(StrEq("filter"),
1101 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1102 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001103 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001104 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1105 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1106 "-j", "MARK", "--set-mark",
1107 "0x00002000/0x00003f00", "-w"),
1108 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001109 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1110 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1111 "-j", "MARK", "--set-mark",
1112 "0x03ea0000/0xffff0000", "-w"),
1113 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001114 EXPECT_CALL(
1115 runner,
1116 ip6tables(StrEq("mangle"),
1117 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1118 "--set-mark", "0x00002000/0x00003f00", "-w"),
1119 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001120 EXPECT_CALL(
1121 runner,
1122 ip6tables(StrEq("mangle"),
1123 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1124 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1125 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001126
1127 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001128 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001129 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001130 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001131}
1132
1133TEST(DatapathTest, StopRoutingDevice_CrosVM) {
1134 MockProcessRunner runner;
1135 MockFirewall firewall;
1136 EXPECT_CALL(runner, iptables(StrEq("filter"),
1137 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
1138 "-j", "ACCEPT", "-w"),
1139 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001140 EXPECT_CALL(runner, iptables(StrEq("filter"),
1141 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
1142 "-j", "ACCEPT", "-w"),
1143 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001144 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1145 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1146 "-j", "MARK", "--set-mark",
1147 "0x00002100/0x00003f00", "-w"),
1148 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001149 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1150 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1151 "-j", "CONNMARK", "--restore-mark",
1152 "--mask", "0xffff0000", "-w"),
1153 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001154 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1155 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1156 "-j", "MARK", "--set-mark",
1157 "0x00002100/0x00003f00", "-w"),
1158 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001159 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1160 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1161 "-j", "CONNMARK", "--restore-mark",
1162 "--mask", "0xffff0000", "-w"),
1163 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001164 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1165 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1166 "-j", "apply_vpn_mark", "-w"),
1167 true, nullptr));
1168 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1169 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1170 "-j", "apply_vpn_mark", "-w"),
1171 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001172
1173 Datapath datapath(&runner, &firewall);
1174 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001175 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001176}
1177
Hugo Benichid82d8832020-08-14 10:05:03 +09001178TEST(DatapathTest, StartStopIpForwarding) {
1179 struct {
1180 IpFamily family;
1181 std::string iif;
1182 std::string oif;
1183 std::vector<std::string> start_args;
1184 std::vector<std::string> stop_args;
1185 bool result;
1186 } testcases[] = {
1187 {IpFamily::IPv4, "", "", {}, {}, false},
1188 {IpFamily::NONE, "foo", "bar", {}, {}, false},
1189 {IpFamily::IPv4,
1190 "foo",
1191 "bar",
1192 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1193 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1194 true},
1195 {IpFamily::IPv4,
1196 "",
1197 "bar",
1198 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1199 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1200 true},
1201 {IpFamily::IPv4,
1202 "foo",
1203 "",
1204 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1205 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1206 true},
1207 {IpFamily::IPv6,
1208 "foo",
1209 "bar",
1210 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1211 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1212 true},
1213 {IpFamily::IPv6,
1214 "",
1215 "bar",
1216 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1217 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1218 true},
1219 {IpFamily::IPv6,
1220 "foo",
1221 "",
1222 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1223 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1224 true},
1225 {IpFamily::Dual,
1226 "foo",
1227 "bar",
1228 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1229 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1230 true},
1231 {IpFamily::Dual,
1232 "",
1233 "bar",
1234 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1235 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1236 true},
1237 {IpFamily::Dual,
1238 "foo",
1239 "",
1240 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1241 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1242 true},
1243 };
1244
1245 for (const auto& tt : testcases) {
1246 MockProcessRunner runner;
1247 MockFirewall firewall;
1248 if (tt.result) {
1249 if (tt.family & IpFamily::IPv4) {
1250 EXPECT_CALL(runner,
1251 iptables(StrEq("filter"), tt.start_args, true, nullptr))
1252 .WillOnce(Return(0));
1253 EXPECT_CALL(runner,
1254 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
1255 .WillOnce(Return(0));
1256 }
1257 if (tt.family & IpFamily::IPv6) {
1258 EXPECT_CALL(runner,
1259 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
1260 .WillOnce(Return(0));
1261 EXPECT_CALL(runner,
1262 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
1263 .WillOnce(Return(0));
1264 }
1265 }
1266 Datapath datapath(&runner, &firewall);
1267
1268 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
1269 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
1270 }
1271}
1272
Hugo Benichi76be34a2020-08-26 22:35:54 +09001273TEST(DatapathTest, StartStopConnectionPinning) {
1274 MockProcessRunner runner;
1275 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +09001276
1277 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001278 EXPECT_CALL(runner,
1279 iptables(StrEq("mangle"),
1280 ElementsAre("-A", "check_routing_mark", "-o", "eth0",
1281 "-m", "mark", "!", "--mark",
1282 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1283 true, nullptr));
1284 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1285 ElementsAre("-A", "check_routing_mark", "-o",
1286 "eth0", "-m", "mark", "!", "--mark",
1287 "0x03eb0000/0xffff0000", "-j",
1288 "DROP", "-w"),
1289 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001290 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1291 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1292 "-j", "CONNMARK", "--set-mark",
1293 "0x03eb0000/0xffff0000", "-w"),
1294 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001295 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1296 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1297 "-j", "CONNMARK", "--set-mark",
1298 "0x03eb0000/0xffff0000", "-w"),
1299 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001300 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1301 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1302 "-j", "CONNMARK", "--save-mark",
1303 "--mask", "0x00003f00", "-w"),
1304 true, nullptr));
1305 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1306 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1307 "-j", "CONNMARK", "--save-mark",
1308 "--mask", "0x00003f00", "-w"),
1309 true, nullptr));
1310 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1311 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1312 "-j", "CONNMARK", "--restore-mark",
1313 "--mask", "0x00003f00", "-w"),
1314 true, nullptr));
1315 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1316 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1317 "-j", "CONNMARK", "--restore-mark",
1318 "--mask", "0x00003f00", "-w"),
1319 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +09001320
Hugo Benichi1af52392020-11-27 18:09:32 +09001321 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001322 EXPECT_CALL(runner,
1323 iptables(StrEq("mangle"),
1324 ElementsAre("-D", "check_routing_mark", "-o", "eth0",
1325 "-m", "mark", "!", "--mark",
1326 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1327 true, nullptr));
1328 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1329 ElementsAre("-D", "check_routing_mark", "-o",
1330 "eth0", "-m", "mark", "!", "--mark",
1331 "0x03eb0000/0xffff0000", "-j",
1332 "DROP", "-w"),
1333 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001334 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1335 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1336 "-j", "CONNMARK", "--set-mark",
1337 "0x03eb0000/0xffff0000", "-w"),
1338 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001339 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1340 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1341 "-j", "CONNMARK", "--set-mark",
1342 "0x03eb0000/0xffff0000", "-w"),
1343 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001344 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1345 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1346 "-j", "CONNMARK", "--save-mark",
1347 "--mask", "0x00003f00", "-w"),
1348 true, nullptr));
1349 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1350 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1351 "-j", "CONNMARK", "--save-mark",
1352 "--mask", "0x00003f00", "-w"),
1353 true, nullptr));
1354 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1355 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1356 "-j", "CONNMARK", "--restore-mark",
1357 "--mask", "0x00003f00", "-w"),
1358 true, nullptr));
1359 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1360 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1361 "-j", "CONNMARK", "--restore-mark",
1362 "--mask", "0x00003f00", "-w"),
1363 true, nullptr));
1364
Hugo Benichi76be34a2020-08-26 22:35:54 +09001365 Datapath datapath(&runner, &firewall);
1366 datapath.SetIfnameIndex("eth0", 3);
1367 datapath.StartConnectionPinning("eth0");
1368 datapath.StopConnectionPinning("eth0");
1369}
1370
Hugo Benichibfc49112020-12-14 12:54:44 +09001371TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +09001372 MockProcessRunner runner;
1373 MockFirewall firewall;
1374
1375 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001376 EXPECT_CALL(runner,
1377 iptables(StrEq("mangle"),
1378 ElementsAre("-A", "check_routing_mark", "-o", "arcbr0",
1379 "-m", "mark", "!", "--mark",
1380 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1381 true, nullptr));
1382 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1383 ElementsAre("-A", "check_routing_mark", "-o",
1384 "arcbr0", "-m", "mark", "!",
1385 "--mark", "0x03ed0000/0xffff0000",
1386 "-j", "DROP", "-w"),
1387 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001388 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1389 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1390 "-j", "CONNMARK", "--set-mark",
1391 "0x03ed0000/0xffff0000", "-w"),
1392 true, nullptr));
1393 EXPECT_CALL(runner,
1394 iptables(StrEq("mangle"),
1395 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1396 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1397 true, nullptr));
1398 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1399 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1400 "-j", "CONNMARK", "--set-mark",
1401 "0x03ed0000/0xffff0000", "-w"),
1402 true, nullptr));
1403 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1404 ElementsAre("-A", "apply_vpn_mark", "-j",
1405 "MARK", "--set-mark",
1406 "0x03ed0000/0xffff0000", "-w"),
1407 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001408 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1409 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1410 "-j", "CONNMARK", "--save-mark",
1411 "--mask", "0x00003f00", "-w"),
1412 true, nullptr));
1413 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1414 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1415 "-j", "CONNMARK", "--save-mark",
1416 "--mask", "0x00003f00", "-w"),
1417 true, nullptr));
1418 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1419 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1420 "-j", "CONNMARK", "--restore-mark",
1421 "--mask", "0x00003f00", "-w"),
1422 true, nullptr));
1423 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1424 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1425 "-j", "CONNMARK", "--restore-mark",
1426 "--mask", "0x00003f00", "-w"),
1427 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001428 EXPECT_CALL(runner, iptables(StrEq("nat"),
1429 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1430 "-j", "MASQUERADE", "-w"),
1431 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001432 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001433 EXPECT_CALL(runner,
1434 iptables(StrEq("mangle"),
1435 ElementsAre("-D", "check_routing_mark", "-o", "arcbr0",
1436 "-m", "mark", "!", "--mark",
1437 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1438 true, nullptr));
1439 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1440 ElementsAre("-D", "check_routing_mark", "-o",
1441 "arcbr0", "-m", "mark", "!",
1442 "--mark", "0x03ed0000/0xffff0000",
1443 "-j", "DROP", "-w"),
1444 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001445 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1446 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1447 "-j", "CONNMARK", "--set-mark",
1448 "0x03ed0000/0xffff0000", "-w"),
1449 true, nullptr));
1450 EXPECT_CALL(runner,
1451 iptables(StrEq("mangle"),
1452 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1453 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1454 true, nullptr));
1455 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1456 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1457 "-j", "CONNMARK", "--set-mark",
1458 "0x03ed0000/0xffff0000", "-w"),
1459 true, nullptr));
1460 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1461 ElementsAre("-D", "apply_vpn_mark", "-j",
1462 "MARK", "--set-mark",
1463 "0x03ed0000/0xffff0000", "-w"),
1464 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001465 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1466 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1467 "-j", "CONNMARK", "--save-mark",
1468 "--mask", "0x00003f00", "-w"),
1469 true, nullptr));
1470 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1471 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1472 "-j", "CONNMARK", "--save-mark",
1473 "--mask", "0x00003f00", "-w"),
1474 true, nullptr));
1475 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1476 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1477 "-j", "CONNMARK", "--restore-mark",
1478 "--mask", "0x00003f00", "-w"),
1479 true, nullptr));
1480 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1481 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1482 "-j", "CONNMARK", "--restore-mark",
1483 "--mask", "0x00003f00", "-w"),
1484 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001485 EXPECT_CALL(runner, iptables(StrEq("nat"),
1486 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1487 "-j", "MASQUERADE", "-w"),
1488 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001489
1490 Datapath datapath(&runner, &firewall);
1491 datapath.SetIfnameIndex("arcbr0", 5);
1492 datapath.StartVpnRouting("arcbr0");
1493 datapath.StopVpnRouting("arcbr0");
1494}
1495
Hugo Benichibfc49112020-12-14 12:54:44 +09001496TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
1497 MockProcessRunner runner;
1498 MockFirewall firewall;
1499
1500 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001501 EXPECT_CALL(runner,
1502 iptables(StrEq("mangle"),
1503 ElementsAre("-A", "check_routing_mark", "-o", "tun0",
1504 "-m", "mark", "!", "--mark",
1505
1506 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1507 true, nullptr));
1508 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1509 ElementsAre("-A", "check_routing_mark", "-o",
1510 "tun0", "-m", "mark", "!", "--mark",
1511
1512 "0x03ed0000/0xffff0000", "-j",
1513 "DROP", "-w"),
1514 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001515 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1516 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1517 "-j", "CONNMARK", "--set-mark",
1518 "0x03ed0000/0xffff0000", "-w"),
1519 true, nullptr));
1520 EXPECT_CALL(runner,
1521 iptables(StrEq("mangle"),
1522 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1523 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1524 true, nullptr));
1525 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1526 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1527 "-j", "CONNMARK", "--set-mark",
1528 "0x03ed0000/0xffff0000", "-w"),
1529 true, nullptr));
1530 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1531 ElementsAre("-A", "apply_vpn_mark", "-j",
1532 "MARK", "--set-mark",
1533 "0x03ed0000/0xffff0000", "-w"),
1534 true, nullptr));
1535 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1536 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1537 "-j", "CONNMARK", "--save-mark",
1538 "--mask", "0x00003f00", "-w"),
1539 true, nullptr));
1540 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1541 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1542 "-j", "CONNMARK", "--save-mark",
1543 "--mask", "0x00003f00", "-w"),
1544 true, nullptr));
1545 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1546 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1547 "-j", "CONNMARK", "--restore-mark",
1548 "--mask", "0x00003f00", "-w"),
1549 true, nullptr));
1550 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1551 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1552 "-j", "CONNMARK", "--restore-mark",
1553 "--mask", "0x00003f00", "-w"),
1554 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001555 EXPECT_CALL(runner, iptables(StrEq("nat"),
1556 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1557 "-j", "MASQUERADE", "-w"),
1558 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001559 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001560 EXPECT_CALL(runner,
1561 iptables(StrEq("mangle"),
1562 ElementsAre("-D", "check_routing_mark", "-o", "tun0",
1563 "-m", "mark", "!", "--mark",
1564
1565 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1566 true, nullptr));
1567 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1568 ElementsAre("-D", "check_routing_mark", "-o",
1569 "tun0", "-m", "mark", "!", "--mark",
1570
1571 "0x03ed0000/0xffff0000", "-j",
1572 "DROP", "-w"),
1573 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001574 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1575 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1576 "-j", "CONNMARK", "--set-mark",
1577 "0x03ed0000/0xffff0000", "-w"),
1578 true, nullptr));
1579 EXPECT_CALL(runner,
1580 iptables(StrEq("mangle"),
1581 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1582 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1583 true, nullptr));
1584 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1585 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1586 "-j", "CONNMARK", "--set-mark",
1587 "0x03ed0000/0xffff0000", "-w"),
1588 true, nullptr));
1589 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1590 ElementsAre("-D", "apply_vpn_mark", "-j",
1591 "MARK", "--set-mark",
1592 "0x03ed0000/0xffff0000", "-w"),
1593 true, nullptr));
1594 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1595 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1596 "-j", "CONNMARK", "--save-mark",
1597 "--mask", "0x00003f00", "-w"),
1598 true, nullptr));
1599 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1600 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1601 "-j", "CONNMARK", "--save-mark",
1602 "--mask", "0x00003f00", "-w"),
1603 true, nullptr));
1604 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1605 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1606 "-j", "CONNMARK", "--restore-mark",
1607 "--mask", "0x00003f00", "-w"),
1608 true, nullptr));
1609 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1610 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1611 "-j", "CONNMARK", "--restore-mark",
1612 "--mask", "0x00003f00", "-w"),
1613 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001614 EXPECT_CALL(runner, iptables(StrEq("nat"),
1615 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1616 "-j", "MASQUERADE", "-w"),
1617 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001618 // Start tun0 <-> arcbr0 routing
1619 EXPECT_CALL(runner, iptables(StrEq("filter"),
1620 ElementsAre("-A", "FORWARD", "-i", "tun0", "-o",
1621 "arcbr0", "-j", "ACCEPT", "-w"),
1622 true, nullptr));
1623 EXPECT_CALL(runner, iptables(StrEq("filter"),
1624 ElementsAre("-A", "FORWARD", "-i", "arcbr0",
1625 "-o", "tun0", "-j", "ACCEPT", "-w"),
1626 true, nullptr));
1627 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1628 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1629 "-j", "MARK", "--set-mark",
1630 "0x00002000/0x00003f00", "-w"),
1631 true, nullptr));
1632 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1633 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1634 "-j", "MARK", "--set-mark",
1635 "0x03ed0000/0xffff0000", "-w"),
1636 true, nullptr));
1637 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1638 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1639 "-j", "MARK", "--set-mark",
1640 "0x00002000/0x00003f00", "-w"),
1641 true, nullptr));
1642 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1643 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1644 "-j", "MARK", "--set-mark",
1645 "0x03ed0000/0xffff0000", "-w"),
1646 true, nullptr));
1647 // Stop tun0 <-> arcbr0 routing
1648 EXPECT_CALL(runner, iptables(StrEq("filter"),
1649 ElementsAre("-D", "FORWARD", "-i", "tun0", "-o",
1650 "arcbr0", "-j", "ACCEPT", "-w"),
1651 true, nullptr));
1652 EXPECT_CALL(runner, iptables(StrEq("filter"),
1653 ElementsAre("-D", "FORWARD", "-i", "arcbr0",
1654 "-o", "tun0", "-j", "ACCEPT", "-w"),
1655 true, nullptr));
1656 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1657 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1658 "-j", "MARK", "--set-mark",
1659 "0x00002000/0x00003f00", "-w"),
1660 true, nullptr));
1661 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1662 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1663 "-j", "MARK", "--set-mark",
1664 "0x03ed0000/0xffff0000", "-w"),
1665 true, nullptr));
1666 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1667 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1668 "-j", "MARK", "--set-mark",
1669 "0x00002000/0x00003f00", "-w"),
1670 true, nullptr));
1671 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1672 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1673 "-j", "MARK", "--set-mark",
1674 "0x03ed0000/0xffff0000", "-w"),
1675 true, nullptr));
1676
1677 Datapath datapath(&runner, &firewall);
1678 datapath.SetIfnameIndex("tun0", 5);
1679 datapath.StartVpnRouting("tun0");
1680 datapath.StopVpnRouting("tun0");
1681}
1682
Garrick Evansf0ab7132019-06-18 14:50:42 +09001683TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001684 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001685 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001686 EXPECT_CALL(runner, iptables(StrEq("nat"),
1687 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1688 "-m", "socket", "--nowildcard", "-j",
1689 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001690 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001691 EXPECT_CALL(runner, iptables(StrEq("nat"),
1692 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1693 "-p", "tcp", "-j", "DNAT",
1694 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001695 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001696 EXPECT_CALL(runner, iptables(StrEq("nat"),
1697 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1698 "-p", "udp", "-j", "DNAT",
1699 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001700 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001701 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001702 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001703}
1704
1705TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001706 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001707 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001708 EXPECT_CALL(runner, iptables(StrEq("nat"),
1709 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1710 "-m", "socket", "--nowildcard", "-j",
1711 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001712 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001713 EXPECT_CALL(runner, iptables(StrEq("nat"),
1714 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1715 "-p", "tcp", "-j", "DNAT",
1716 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001717 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001718 EXPECT_CALL(runner, iptables(StrEq("nat"),
1719 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1720 "-p", "udp", "-j", "DNAT",
1721 "--to-destination", "1.2.3.4", "-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 Evansf0ab7132019-06-18 14:50:42 +09001724 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001725}
1726
Garrick Evans664a82f2019-12-17 12:18:05 +09001727TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001728 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001729 MockFirewall firewall;
1730 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001731
Garrick Evans664a82f2019-12-17 12:18:05 +09001732 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001733 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001734 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001735 EXPECT_EQ(ioctl_reqs, expected);
1736 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001737 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001738}
1739
1740TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001741 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001742 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001743 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001744 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1745 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1746 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001747 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001748 .WillOnce(Return(1));
1749 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1750 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1751 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001752 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001753 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1754 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1755 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001756 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001757 .WillOnce(Return(1));
1758 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1759 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1760 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001761 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001762 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001763 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001764}
1765
Taoyu Lica49c832019-12-06 17:56:43 +09001766TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001767 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001768 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001769 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1770 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1771 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001772 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001773 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1774 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1775 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001776 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001777 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001778 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001779}
1780
Taoyu Li90c13912019-11-26 17:56:54 +09001781TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001782 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001783 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001784 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1785 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1786 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001787 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001788 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1789 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1790 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001791 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001792 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001793 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001794}
1795
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001796TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001797 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001798 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001799 EXPECT_CALL(runner,
1800 ip6(StrEq("route"), StrEq("replace"),
1801 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001802 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001803 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001804}
1805
Hugo Benichie8758b52020-04-03 14:49:01 +09001806TEST(DatapathTest, AddIPv4Route) {
1807 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001808 MockFirewall firewall;
1809 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001810
1811 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1812 Ipv4Addr(255, 255, 255, 0));
1813 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1814 Ipv4Addr(255, 255, 255, 0));
1815 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1816 Ipv4Addr(255, 255, 255, 252));
1817 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1818 Ipv4Addr(255, 255, 255, 252));
1819
1820 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1821 SIOCDELRT};
1822 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001823
1824 std::string route1 =
1825 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1826 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1827 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1828 "RTF_GATEWAY}";
1829 std::string route2 =
1830 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1831 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1832 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1833 std::vector<std::string> captured_routes;
1834 for (const auto& route : ioctl_rtentry_args) {
1835 std::ostringstream stream;
1836 stream << route.second;
1837 captured_routes.emplace_back(stream.str());
1838 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001839 EXPECT_EQ(route1, captured_routes[0]);
1840 EXPECT_EQ(route1, captured_routes[1]);
1841 EXPECT_EQ(route2, captured_routes[2]);
1842 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001843 ioctl_reqs.clear();
1844 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001845}
1846
Garrick Evansd291af62020-05-25 10:39:06 +09001847TEST(DatapathTest, AddSNATMarkRules) {
1848 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001849 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +09001850 EXPECT_CALL(
1851 runner,
1852 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +09001853 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +09001854 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001855 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +09001856 EXPECT_CALL(runner,
1857 iptables(StrEq("filter"),
1858 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark",
1859 "1/1", "-j", "ACCEPT", "-w"),
1860 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +09001861 EXPECT_CALL(runner,
1862 iptables(StrEq("nat"),
1863 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +09001864 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001865 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001866 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001867 datapath.AddSNATMarkRules();
1868}
1869
1870TEST(DatapathTest, RemoveSNATMarkRules) {
1871 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001872 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +09001873 EXPECT_CALL(
1874 runner,
1875 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +09001876 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +09001877 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001878 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +09001879 EXPECT_CALL(runner,
1880 iptables(StrEq("filter"),
1881 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
1882 "1/1", "-j", "ACCEPT", "-w"),
1883 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +09001884 EXPECT_CALL(runner,
1885 iptables(StrEq("nat"),
1886 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +09001887 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001888 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001889 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001890 datapath.RemoveSNATMarkRules();
1891}
1892
Garrick Evans2f581a02020-05-11 10:43:35 +09001893TEST(DatapathTest, ArcVethHostName) {
1894 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1895 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1896 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1897 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1898 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1899 EXPECT_EQ("vethexceeds_ify", ifname);
1900 EXPECT_LT(ifname.length(), IFNAMSIZ);
1901}
1902
Garrick Evans8a067562020-05-11 12:47:30 +09001903TEST(DatapathTest, ArcBridgeName) {
1904 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1905 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1906 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1907 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1908 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1909 EXPECT_EQ("arc_exceeds_ify", ifname);
1910 EXPECT_LT(ifname.length(), IFNAMSIZ);
1911}
1912
Garrick Evans3388a032020-03-24 11:25:55 +09001913} // namespace patchpanel