blob: 3603734634f1425cde3fe7c903fc6bf0fbe33960 [file] [log] [blame]
Garrick Evansf0ab7132019-06-18 14:50:42 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/datapath.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +09006
Garrick Evansc7ae82c2019-09-04 16:25:10 +09007#include <linux/if_tun.h>
Taoyu Li90c13912019-11-26 17:56:54 +09008#include <net/if.h>
Garrick Evansc7ae82c2019-09-04 16:25:10 +09009#include <sys/ioctl.h>
10
Garrick Evansf0ab7132019-06-18 14:50:42 +090011#include <utility>
12#include <vector>
13
Garrick Evansc7ae82c2019-09-04 16:25:10 +090014#include <base/bind.h>
Qijiang Fane90b8792020-03-09 16:15:41 +090015#include <base/bind_helpers.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090016#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090017#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090018#include <gtest/gtest.h>
19
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090020#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090021#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090022
Garrick Evans8e8e3472020-01-23 14:03:50 +090023using testing::_;
24using testing::ElementsAre;
25using testing::Return;
26using testing::StrEq;
27
Garrick Evans3388a032020-03-24 11:25:55 +090028namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090029namespace {
30
Hugo Benichi76675592020-04-08 14:29:57 +090031// TODO(hugobenichi) Centralize this constant definition
32constexpr pid_t kTestPID = -2;
33
Hugo Benichie8758b52020-04-03 14:49:01 +090034std::vector<ioctl_req_t> ioctl_reqs;
35std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090036
37// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090038int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090039 ioctl_reqs.push_back(req);
40 return 0;
41}
42
43// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
44int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
45 ioctl_reqs.push_back(req);
46 ioctl_rtentry_args.push_back({"", *arg});
47 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
48 // this value to ioctl() on the stack.
49 if (arg->rt_dev) {
50 auto& cap = ioctl_rtentry_args.back();
51 cap.first = std::string(arg->rt_dev);
52 cap.second.rt_dev = (char*)cap.first.c_str();
53 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090054 return 0;
55}
56
57} // namespace
58
Garrick Evans8e8e3472020-01-23 14:03:50 +090059class MockProcessRunner : public MinijailedProcessRunner {
60 public:
61 MockProcessRunner() = default;
62 ~MockProcessRunner() = default;
63
Garrick Evans2470caa2020-03-04 14:15:41 +090064 MOCK_METHOD1(WriteSentinelToContainer, int(pid_t pid));
Garrick Evans8e8e3472020-01-23 14:03:50 +090065 MOCK_METHOD3(brctl,
66 int(const std::string& cmd,
67 const std::vector<std::string>& argv,
68 bool log_failures));
69 MOCK_METHOD4(chown,
70 int(const std::string& uid,
71 const std::string& gid,
72 const std::string& file,
73 bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +090074 MOCK_METHOD4(ip,
75 int(const std::string& obj,
76 const std::string& cmd,
77 const std::vector<std::string>& args,
78 bool log_failures));
79 MOCK_METHOD4(ip6,
80 int(const std::string& obj,
81 const std::string& cmd,
82 const std::vector<std::string>& args,
83 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090084 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090085 int(const std::string& table,
86 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090087 bool log_failures,
88 std::string* output));
89 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090090 int(const std::string& table,
91 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090092 bool log_failures,
93 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +090094 MOCK_METHOD2(modprobe_all,
95 int(const std::vector<std::string>& modules, bool log_failures));
96 MOCK_METHOD3(sysctl_w,
97 int(const std::string& key,
98 const std::string& value,
99 bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900100 MOCK_METHOD3(ip_netns_attach,
101 int(const std::string& netns_name,
102 pid_t netns_pid,
103 bool log_failures));
104 MOCK_METHOD2(ip_netns_delete,
105 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900106};
107
Hugo Benichid82d8832020-08-14 10:05:03 +0900108TEST(DatapathTest, IpFamily) {
109 EXPECT_EQ(IpFamily::Dual, IpFamily::IPv4 | IpFamily::IPv6);
110 EXPECT_EQ(IpFamily::Dual & IpFamily::IPv4, IpFamily::IPv4);
111 EXPECT_EQ(IpFamily::Dual & IpFamily::IPv6, IpFamily::IPv6);
112 EXPECT_NE(IpFamily::Dual, IpFamily::IPv4);
113 EXPECT_NE(IpFamily::Dual, IpFamily::IPv6);
114 EXPECT_NE(IpFamily::IPv4, IpFamily::IPv6);
115}
116
Hugo Benichibf811c62020-09-07 17:30:45 +0900117TEST(DatapathTest, Start) {
118 MockProcessRunner runner;
119 MockFirewall firewall;
120 // Asserts for sysctl modifications
121 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("1"), true));
122 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
123 StrEq("32768 47103"), true));
124 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
125 StrEq("1"), true));
Hugo Benichi561fae42021-01-22 15:28:40 +0900126 // Asserts for SNAT rules.
Hugo Benichibf811c62020-09-07 17:30:45 +0900127 EXPECT_CALL(
128 runner,
129 iptables(StrEq("filter"),
130 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
131 "state", "--state", "INVALID", "-j", "DROP", "-w"),
132 true, nullptr));
133 EXPECT_CALL(runner,
Hugo Benichibf811c62020-09-07 17:30:45 +0900134 iptables(StrEq("nat"),
135 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
136 "1/1", "-j", "MASQUERADE", "-w"),
137 true, nullptr));
138 // Asserts for AddForwardEstablishedRule
139 EXPECT_CALL(runner,
140 iptables(StrEq("filter"),
141 ElementsAre("-A", "FORWARD", "-m", "state", "--state",
142 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
143 true, nullptr));
144 // Asserts for AddSourceIPv4DropRule() calls.
145 EXPECT_CALL(runner,
146 iptables(StrEq("filter"),
147 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
148 "100.115.92.0/23", "-j", "DROP", "-w"),
149 true, nullptr));
150 EXPECT_CALL(runner,
151 iptables(StrEq("filter"),
152 ElementsAre("-I", "OUTPUT", "-o", "wlan+", "-s",
153 "100.115.92.0/23", "-j", "DROP", "-w"),
154 true, nullptr));
155 EXPECT_CALL(runner,
156 iptables(StrEq("filter"),
157 ElementsAre("-I", "OUTPUT", "-o", "mlan+", "-s",
158 "100.115.92.0/23", "-j", "DROP", "-w"),
159 true, nullptr));
160 EXPECT_CALL(runner,
161 iptables(StrEq("filter"),
162 ElementsAre("-I", "OUTPUT", "-o", "usb+", "-s",
163 "100.115.92.0/23", "-j", "DROP", "-w"),
164 true, nullptr));
165 EXPECT_CALL(runner,
166 iptables(StrEq("filter"),
167 ElementsAre("-I", "OUTPUT", "-o", "wwan+", "-s",
168 "100.115.92.0/23", "-j", "DROP", "-w"),
169 true, nullptr));
170 EXPECT_CALL(runner,
171 iptables(StrEq("filter"),
172 ElementsAre("-I", "OUTPUT", "-o", "rmnet+", "-s",
173 "100.115.92.0/23", "-j", "DROP", "-w"),
174 true, nullptr));
175 // Asserts for AddOutboundIPv4SNATMark("vmtap+")
176 EXPECT_CALL(runner,
177 iptables(StrEq("mangle"),
178 ElementsAre("-A", "PREROUTING", "-i", "vmtap+", "-j",
179 "MARK", "--set-mark", "1/1", "-w"),
180 true, nullptr));
Taoyu Li78f0c9a2020-12-25 22:58:26 +0900181 // Asserts for OUTPUT ndp connmark bypass rule
182 EXPECT_CALL(
183 runner,
184 ip6tables(StrEq("mangle"),
185 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
186 "router-solicitation", "-j", "ACCEPT", "-w"),
187 true, nullptr));
188 EXPECT_CALL(
189 runner,
190 ip6tables(StrEq("mangle"),
191 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
192 "router-advertisement", "-j", "ACCEPT", "-w"),
193 true, nullptr));
194 EXPECT_CALL(
195 runner,
196 ip6tables(StrEq("mangle"),
197 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
198 "neighbour-solicitation", "-j", "ACCEPT", "-w"),
199 true, nullptr));
200 EXPECT_CALL(
201 runner,
202 ip6tables(StrEq("mangle"),
203 ElementsAre("-A", "OUTPUT", "-p", "icmpv6", "--icmpv6-type",
204 "neighbour-advertisement", "-j", "ACCEPT", "-w"),
205 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900206 // Asserts for OUTPUT CONNMARK restore rule
207 EXPECT_CALL(runner, iptables(StrEq("mangle"),
208 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
209 "--restore-mark", "--mask",
210 "0xffff0000", "-w"),
211 true, nullptr));
212 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
213 ElementsAre("-A", "OUTPUT", "-j", "CONNMARK",
214 "--restore-mark", "--mask",
215 "0xffff0000", "-w"),
216 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900217 // Asserts for apply_local_source_mark chain
218 EXPECT_CALL(runner,
219 iptables(StrEq("mangle"),
220 ElementsAre("-N", "apply_local_source_mark", "-w"), true,
221 nullptr));
222 EXPECT_CALL(runner,
223 iptables(StrEq("mangle"),
224 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
225 nullptr));
226 EXPECT_CALL(runner, iptables(StrEq("mangle"),
227 ElementsAre("-A", "OUTPUT", "-j",
228 "apply_local_source_mark", "-w"),
229 true, nullptr));
230 EXPECT_CALL(
231 runner,
232 iptables(StrEq("mangle"),
233 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
234 "--uid-owner", "chronos", "-j", "MARK", "--set-mark",
235 "0x00008100/0x0000ff00", "-w"),
236 true, nullptr));
237 EXPECT_CALL(runner, iptables(StrEq("mangle"),
238 ElementsAre("-A", "apply_local_source_mark",
239 "-m", "owner", "--uid-owner",
240 "debugd", "-j", "MARK", "--set-mark",
241 "0x00008200/0x0000ff00", "-w"),
242 true, nullptr));
243 EXPECT_CALL(runner,
244 iptables(StrEq("mangle"),
245 ElementsAre("-A", "apply_local_source_mark", "-m",
246 "owner", "--uid-owner", "cups", "-j", "MARK",
247 "--set-mark", "0x00008200/0x0000ff00", "-w"),
248 true, nullptr));
249 EXPECT_CALL(
250 runner,
251 iptables(StrEq("mangle"),
252 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
253 "--uid-owner", "kerberosd", "-j", "MARK",
254 "--set-mark", "0x00008400/0x0000ff00", "-w"),
255 true, nullptr));
256 EXPECT_CALL(
257 runner,
258 iptables(StrEq("mangle"),
259 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
260 "--uid-owner", "kerberosd-exec", "-j", "MARK",
261 "--set-mark", "0x00008400/0x0000ff00", "-w"),
262 true, nullptr));
263 EXPECT_CALL(
264 runner,
265 iptables(StrEq("mangle"),
266 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
267 "--uid-owner", "tlsdate", "-j", "MARK", "--set-mark",
268 "0x00008400/0x0000ff00", "-w"),
269 true, nullptr));
270 EXPECT_CALL(
271 runner,
272 iptables(StrEq("mangle"),
273 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
274 "--uid-owner", "pluginvm", "-j", "MARK",
275 "--set-mark", "0x00008200/0x0000ff00", "-w"),
276 true, nullptr));
277 EXPECT_CALL(
278 runner,
279 iptables(StrEq("mangle"),
280 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
281 "--uid-owner", "fuse-smbfs", "-j", "MARK",
282 "--set-mark", "0x00008400/0x0000ff00", "-w"),
283 true, nullptr));
284 EXPECT_CALL(
285 runner,
286 iptables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900287 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
288 "--cgroup", "0x00010001", "-j", "MARK", "--set-mark",
289 "0x00000300/0x0000ff00", "-w"),
290 true, nullptr));
291 EXPECT_CALL(
292 runner,
293 iptables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900294 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
295 "--mark", "0x0/0x00003f00", "-j", "MARK",
296 "--set-mark", "0x00000400/0x00003f00", "-w"),
297 true, nullptr));
298 EXPECT_CALL(runner,
299 ip6tables(StrEq("mangle"),
300 ElementsAre("-N", "apply_local_source_mark", "-w"),
301 true, nullptr));
302 EXPECT_CALL(runner,
303 ip6tables(StrEq("mangle"),
304 ElementsAre("-F", "apply_local_source_mark", "-w"),
305 true, nullptr));
306 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
307 ElementsAre("-A", "OUTPUT", "-j",
308 "apply_local_source_mark", "-w"),
309 true, nullptr));
310 EXPECT_CALL(
311 runner,
312 ip6tables(StrEq("mangle"),
313 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
314 "--uid-owner", "debugd", "-j", "MARK", "--set-mark",
315 "0x00008200/0x0000ff00", "-w"),
316 true, nullptr));
317 EXPECT_CALL(
318 runner,
319 ip6tables(StrEq("mangle"),
320 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
321 "--uid-owner", "chronos", "-j", "MARK",
322 "--set-mark", "0x00008100/0x0000ff00", "-w"),
323 true, nullptr));
324 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
325 ElementsAre("-A", "apply_local_source_mark",
326 "-m", "owner", "--uid-owner",
327 "cups", "-j", "MARK", "--set-mark",
328 "0x00008200/0x0000ff00", "-w"),
329 true, nullptr));
330 EXPECT_CALL(
331 runner,
332 ip6tables(StrEq("mangle"),
333 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
334 "--uid-owner", "kerberosd", "-j", "MARK",
335 "--set-mark", "0x00008400/0x0000ff00", "-w"),
336 true, nullptr));
337 EXPECT_CALL(
338 runner,
339 ip6tables(StrEq("mangle"),
340 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
341 "--uid-owner", "kerberosd-exec", "-j", "MARK",
342 "--set-mark", "0x00008400/0x0000ff00", "-w"),
343 true, nullptr));
344 EXPECT_CALL(
345 runner,
346 ip6tables(StrEq("mangle"),
347 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
348 "--uid-owner", "tlsdate", "-j", "MARK",
349 "--set-mark", "0x00008400/0x0000ff00", "-w"),
350 true, nullptr));
351 EXPECT_CALL(
352 runner,
353 ip6tables(StrEq("mangle"),
354 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
355 "--uid-owner", "pluginvm", "-j", "MARK",
356 "--set-mark", "0x00008200/0x0000ff00", "-w"),
357 true, nullptr));
358 EXPECT_CALL(
359 runner,
360 ip6tables(StrEq("mangle"),
361 ElementsAre("-A", "apply_local_source_mark", "-m", "owner",
362 "--uid-owner", "fuse-smbfs", "-j", "MARK",
363 "--set-mark", "0x00008400/0x0000ff00", "-w"),
364 true, nullptr));
365 EXPECT_CALL(
366 runner,
367 ip6tables(StrEq("mangle"),
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900368 ElementsAre("-A", "apply_local_source_mark", "-m", "cgroup",
369 "--cgroup", "0x00010001", "-j", "MARK",
370 "--set-mark", "0x00000300/0x0000ff00", "-w"),
371 true, nullptr));
372 EXPECT_CALL(
373 runner,
374 ip6tables(StrEq("mangle"),
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900375 ElementsAre("-A", "apply_local_source_mark", "-m", "mark",
376 "--mark", "0x0/0x00003f00", "-j", "MARK",
377 "--set-mark", "0x00000400/0x00003f00", "-w"),
378 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900379 // Asserts for apply_vpn_mark chain
380 EXPECT_CALL(runner, iptables(StrEq("mangle"),
381 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
382 nullptr));
383 EXPECT_CALL(runner, iptables(StrEq("mangle"),
384 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
385 nullptr));
386 EXPECT_CALL(runner, iptables(StrEq("mangle"),
387 ElementsAre("-A", "OUTPUT", "-m", "mark",
388 "--mark", "0x00008000/0x0000c000",
389 "-j", "apply_vpn_mark", "-w"),
390 true, nullptr));
391 EXPECT_CALL(runner, iptables(StrEq("mangle"),
392 ElementsAre("-A", "apply_vpn_mark", "-m", "mark",
393 "!", "--mark", "0x0/0xffff0000",
394 "-j", "ACCEPT", "-w"),
395 true, nullptr));
396 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
397 ElementsAre("-N", "apply_vpn_mark", "-w"), true,
398 nullptr));
399 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
400 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
401 nullptr));
402 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
403 ElementsAre("-A", "OUTPUT", "-m", "mark",
404 "--mark", "0x00008000/0x0000c000",
405 "-j", "apply_vpn_mark", "-w"),
406 true, nullptr));
407 EXPECT_CALL(
408 runner,
409 ip6tables(StrEq("mangle"),
410 ElementsAre("-A", "apply_vpn_mark", "-m", "mark", "!", "--mark",
411 "0x0/0xffff0000", "-j", "ACCEPT", "-w"),
412 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900413 // Asserts for check_routing_mark chain
414 EXPECT_CALL(runner, iptables(StrEq("mangle"),
415 ElementsAre("-N", "check_routing_mark", "-w"),
416 true, nullptr));
417 EXPECT_CALL(runner, iptables(StrEq("mangle"),
418 ElementsAre("-F", "check_routing_mark", "-w"),
419 true, nullptr));
420 EXPECT_CALL(runner, iptables(StrEq("mangle"),
421 ElementsAre("-A", "POSTROUTING", "-j",
422 "CONNMARK", "--restore-mark",
423 "--mask", "0xffff0000", "-w"),
424 true, nullptr));
425 EXPECT_CALL(runner, iptables(StrEq("mangle"),
426 ElementsAre("-A", "POSTROUTING", "-m", "mark",
427 "!", "--mark", "0x0/0xffff0000",
428 "-j", "check_routing_mark", "-w"),
429 true, nullptr));
430 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
431 ElementsAre("-N", "check_routing_mark", "-w"),
432 true, nullptr));
433 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
434 ElementsAre("-F", "check_routing_mark", "-w"),
435 true, nullptr));
436 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
437 ElementsAre("-A", "POSTROUTING", "-j",
438 "CONNMARK", "--restore-mark",
439 "--mask", "0xffff0000", "-w"),
440 true, nullptr));
441 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
442 ElementsAre("-A", "POSTROUTING", "-m", "mark",
443 "!", "--mark", "0x0/0xffff0000",
444 "-j", "check_routing_mark", "-w"),
445 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900446
447 Datapath datapath(&runner, &firewall);
448 datapath.Start();
449}
450
451TEST(DatapathTest, Stop) {
452 MockProcessRunner runner;
453 MockFirewall firewall;
454 // Asserts for sysctl modifications
455 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
456 StrEq("32768 61000"), true));
457 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
458 StrEq("0"), true));
459 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
460 // Asserts for RemoveOutboundIPv4SNATMark("vmtap+")
461 EXPECT_CALL(runner,
462 iptables(StrEq("mangle"),
463 ElementsAre("-D", "PREROUTING", "-i", "vmtap+", "-j",
464 "MARK", "--set-mark", "1/1", "-w"),
465 true, nullptr));
466 // Asserts for RemoveForwardEstablishedRule
467 EXPECT_CALL(runner,
468 iptables(StrEq("filter"),
469 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
470 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
471 true, nullptr));
Hugo Benichi561fae42021-01-22 15:28:40 +0900472 // Asserts for SNAT rules.
Hugo Benichibf811c62020-09-07 17:30:45 +0900473 EXPECT_CALL(
474 runner,
475 iptables(StrEq("filter"),
476 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
477 "state", "--state", "INVALID", "-j", "DROP", "-w"),
478 true, nullptr));
479 EXPECT_CALL(runner,
Hugo Benichibf811c62020-09-07 17:30:45 +0900480 iptables(StrEq("nat"),
481 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
482 "1/1", "-j", "MASQUERADE", "-w"),
483 true, nullptr));
484 // Asserts for RemoveSourceIPv4DropRule() calls.
485 EXPECT_CALL(runner,
486 iptables(StrEq("filter"),
487 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
488 "100.115.92.0/23", "-j", "DROP", "-w"),
489 true, nullptr));
490 EXPECT_CALL(runner,
491 iptables(StrEq("filter"),
492 ElementsAre("-D", "OUTPUT", "-o", "wlan+", "-s",
493 "100.115.92.0/23", "-j", "DROP", "-w"),
494 true, nullptr));
495 EXPECT_CALL(runner,
496 iptables(StrEq("filter"),
497 ElementsAre("-D", "OUTPUT", "-o", "mlan+", "-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", "usb+", "-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", "wwan+", "-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", "rmnet+", "-s",
513 "100.115.92.0/23", "-j", "DROP", "-w"),
514 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900515 // Asserts for apply_local_source_mark chain
516 EXPECT_CALL(runner, iptables(StrEq("mangle"),
517 ElementsAre("-D", "OUTPUT", "-j",
518 "apply_local_source_mark", "-w"),
519 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +0900520 // Asserts for OUTPUT CONNMARK restore rule
521 EXPECT_CALL(runner, iptables(StrEq("mangle"),
522 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
523 "--restore-mark", "--mask",
524 "0xffff0000", "-w"),
525 true, nullptr));
526 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
527 ElementsAre("-D", "OUTPUT", "-j", "CONNMARK",
528 "--restore-mark", "--mask",
529 "0xffff0000", "-w"),
530 true, nullptr));
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900531 EXPECT_CALL(runner,
532 iptables(StrEq("mangle"),
533 ElementsAre("-F", "apply_local_source_mark", "-w"), true,
534 nullptr));
535 EXPECT_CALL(runner,
536 iptables(StrEq("mangle"),
537 ElementsAre("-X", "apply_local_source_mark", "-w"), true,
538 nullptr));
539 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
540 ElementsAre("-D", "OUTPUT", "-j",
541 "apply_local_source_mark", "-w"),
542 true, nullptr));
543 EXPECT_CALL(runner,
544 ip6tables(StrEq("mangle"),
545 ElementsAre("-F", "apply_local_source_mark", "-w"),
546 true, nullptr));
547 EXPECT_CALL(runner,
548 ip6tables(StrEq("mangle"),
549 ElementsAre("-X", "apply_local_source_mark", "-w"),
550 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900551 // Asserts for apply_vpn_mark chain
552 EXPECT_CALL(runner, iptables(StrEq("mangle"),
553 ElementsAre("-D", "OUTPUT", "-m", "mark",
554 "--mark", "0x00008000/0x0000c000",
555 "-j", "apply_vpn_mark", "-w"),
556 true, nullptr));
557 EXPECT_CALL(runner, iptables(StrEq("mangle"),
558 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
559 nullptr));
560 EXPECT_CALL(runner, iptables(StrEq("mangle"),
561 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
562 nullptr));
563 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
564 ElementsAre("-D", "OUTPUT", "-m", "mark",
565 "--mark", "0x00008000/0x0000c000",
566 "-j", "apply_vpn_mark", "-w"),
567 true, nullptr));
568 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
569 ElementsAre("-F", "apply_vpn_mark", "-w"), true,
570 nullptr));
571 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
572 ElementsAre("-X", "apply_vpn_mark", "-w"), true,
573 nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +0900574 // Asserts for check_routing_mark chain
575 EXPECT_CALL(runner, iptables(StrEq("mangle"),
576 ElementsAre("-D", "POSTROUTING", "-j",
577 "CONNMARK", "--restore-mark",
578 "--mask", "0xffff0000", "-w"),
579 true, nullptr));
580 EXPECT_CALL(runner, iptables(StrEq("mangle"),
581 ElementsAre("-D", "POSTROUTING", "-m", "mark",
582 "!", "--mark", "0x0/0xffff0000",
583 "-j", "check_routing_mark", "-w"),
584 true, nullptr));
585 EXPECT_CALL(runner, iptables(StrEq("mangle"),
586 ElementsAre("-F", "check_routing_mark", "-w"),
587 true, nullptr));
588 EXPECT_CALL(runner, iptables(StrEq("mangle"),
589 ElementsAre("-X", "check_routing_mark", "-w"),
590 true, nullptr));
591 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
592 ElementsAre("-D", "POSTROUTING", "-j",
593 "CONNMARK", "--restore-mark",
594 "--mask", "0xffff0000", "-w"),
595 true, nullptr));
596 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
597 ElementsAre("-D", "POSTROUTING", "-m", "mark",
598 "!", "--mark", "0x0/0xffff0000",
599 "-j", "check_routing_mark", "-w"),
600 true, nullptr));
601 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
602 ElementsAre("-F", "check_routing_mark", "-w"),
603 true, nullptr));
604 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
605 ElementsAre("-X", "check_routing_mark", "-w"),
606 true, nullptr));
Hugo Benichibf811c62020-09-07 17:30:45 +0900607
608 Datapath datapath(&runner, &firewall);
609 datapath.Stop();
610}
611
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900612TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900613 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900614 MockFirewall firewall;
615 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900616 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900617 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900618 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900619 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900620 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900621 std::vector<ioctl_req_t> expected = {
622 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
623 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900624 EXPECT_EQ(ioctl_reqs, expected);
625 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900626 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900627}
628
629TEST(DatapathTest, AddTAPWithOwner) {
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, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900633 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900634 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900635 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900636 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900637 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900638 std::vector<ioctl_req_t> expected = {
639 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
640 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900641 EXPECT_EQ(ioctl_reqs, expected);
642 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900643 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900644}
645
Garrick Evans621ed262019-11-13 12:28:43 +0900646TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900647 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900648 MockFirewall firewall;
649 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900650 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900651 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900652 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
653 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900654 EXPECT_EQ(ioctl_reqs, expected);
655 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900656 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900657}
658
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900659TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900660 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900661 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900662 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
663 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900664 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900665 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900666}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900667
Hugo Benichi33860d72020-07-09 16:34:01 +0900668TEST(DatapathTest, NetnsAttachName) {
669 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900670 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900671 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
672 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900673 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900674 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
675}
676
677TEST(DatapathTest, NetnsDeleteName) {
678 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900679 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900680 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900681 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900682 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
683}
684
Garrick Evans8a949dc2019-07-18 16:17:53 +0900685TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900686 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900687 MockFirewall firewall;
688 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900689 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900690 EXPECT_CALL(
691 runner,
692 ip(StrEq("addr"), StrEq("add"),
693 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900694 EXPECT_CALL(runner,
695 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900696 EXPECT_CALL(runner, iptables(StrEq("mangle"),
697 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900698 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900699 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900700 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900701}
702
Hugo Benichi76675592020-04-08 14:29:57 +0900703TEST(DatapathTest, ConnectVethPair) {
704 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900705 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900706 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
707 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900708 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900709 true));
710 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
711 ElementsAre("100.115.92.169/30", "brd",
712 "100.115.92.171", "dev", "peer_foo"),
713 true))
714 .WillOnce(Return(0));
715 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
716 ElementsAre("dev", "peer_foo", "up", "addr",
717 "01:02:03:04:05:06", "multicast", "on"),
718 true))
719 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900720 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
721 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900722 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900723 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
724 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900725 Ipv4Addr(100, 115, 92, 169), 30, true));
726}
727
Garrick Evans2470caa2020-03-04 14:15:41 +0900728TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900729 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900730 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900731 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
732 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900733 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900734 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900735 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900736 EXPECT_TRUE(
737 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900738}
739
740TEST(DatapathTest, ToggleInterface) {
741 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900742 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900743 EXPECT_CALL(runner,
744 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900745 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900746 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900747 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900748 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
749 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
750}
751
752TEST(DatapathTest, ConfigureInterface) {
753 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900754 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900755 EXPECT_CALL(
756 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900757 ip(StrEq("addr"), StrEq("add"),
758 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
759 .WillOnce(Return(0));
760 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
761 ElementsAre("dev", "foo", "up", "addr",
762 "02:02:02:02:02:02", "multicast", "on"),
763 true))
764 .WillOnce(Return(0));
765
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900766 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900767 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
768 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
769 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900770}
771
772TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900773 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900774 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900775 EXPECT_CALL(runner,
776 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900777 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900778 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900779}
780
Garrick Evans8a949dc2019-07-18 16:17:53 +0900781TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900782 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900783 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900784 EXPECT_CALL(runner, iptables(StrEq("mangle"),
785 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900786 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900787 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900788 EXPECT_CALL(runner,
789 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900790 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900791 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900792 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900793}
794
Hugo Benichi321f23b2020-09-25 15:42:05 +0900795TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
796 MockProcessRunner runner;
797 MockFirewall firewall;
798 EXPECT_CALL(runner,
799 iptables(StrEq("filter"),
800 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
801 "100.115.92.0/24", "-j", "DROP", "-w"),
802 true, nullptr));
803 EXPECT_CALL(runner,
804 iptables(StrEq("filter"),
805 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
806 "100.115.92.0/24", "-j", "DROP", "-w"),
807 true, nullptr));
808 Datapath datapath(&runner, &firewall);
809 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
810 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
811}
812
Hugo Benichi7c342672020-09-08 09:18:14 +0900813TEST(DatapathTest, StartRoutingNamespace) {
814 MockProcessRunner runner;
815 MockFirewall firewall;
816 MacAddress mac = {1, 2, 3, 4, 5, 6};
817
818 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
819 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
820 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
821 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
822 "veth0", "netns", "netns_foo"),
823 true));
824 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
825 ElementsAre("100.115.92.130/30", "brd",
826 "100.115.92.131", "dev", "veth0"),
827 true))
828 .WillOnce(Return(0));
829 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
830 ElementsAre("dev", "veth0", "up", "addr",
831 "01:02:03:04:05:06", "multicast", "off"),
832 true))
833 .WillOnce(Return(0));
834 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
835 ElementsAre("arc_ns0", "up"), true));
836 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
837 ElementsAre("100.115.92.129/30", "brd",
838 "100.115.92.131", "dev", "arc_ns0"),
839 true))
840 .WillOnce(Return(0));
841 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
842 ElementsAre("dev", "arc_ns0", "up", "addr",
843 "01:02:03:04:05:06", "multicast", "off"),
844 true))
845 .WillOnce(Return(0));
846 EXPECT_CALL(runner, iptables(StrEq("filter"),
847 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
848 "-j", "ACCEPT", "-w"),
849 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900850 EXPECT_CALL(runner, iptables(StrEq("filter"),
851 ElementsAre("-A", "FORWARD", "-i", "arc_ns0",
852 "-j", "ACCEPT", "-w"),
853 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900854 EXPECT_CALL(runner,
855 iptables(StrEq("mangle"),
856 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
857 "MARK", "--set-mark", "1/1", "-w"),
858 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900859 EXPECT_CALL(runner, iptables(StrEq("mangle"),
860 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
861 "-j", "MARK", "--set-mark",
862 "0x00000200/0x00003f00", "-w"),
863 true, nullptr));
864 EXPECT_CALL(runner, iptables(StrEq("mangle"),
865 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
866 "-j", "CONNMARK", "--restore-mark",
867 "--mask", "0xffff0000", "-w"),
868 true, nullptr));
869 EXPECT_CALL(runner, ip6tables(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, ip6tables(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, iptables(StrEq("mangle"),
880 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
881 "-j", "apply_vpn_mark", "-w"),
882 true, nullptr));
883 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
884 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
885 "-j", "apply_vpn_mark", "-w"),
886 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900887
Hugo Benichifcf81022020-12-04 11:01:37 +0900888 ConnectedNamespace nsinfo = {};
889 nsinfo.pid = kTestPID;
890 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900891 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900892 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900893 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900894 nsinfo.host_ifname = "arc_ns0";
895 nsinfo.peer_ifname = "veth0";
896 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
897 base::DoNothing());
898 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900899 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900900 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900901 ioctl_reqs.clear();
902 ioctl_rtentry_args.clear();
903}
904
905TEST(DatapathTest, StopRoutingNamespace) {
906 MockProcessRunner runner;
907 MockFirewall firewall;
908
909 EXPECT_CALL(runner, iptables(StrEq("filter"),
910 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
911 "-j", "ACCEPT", "-w"),
912 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900913 EXPECT_CALL(runner, iptables(StrEq("filter"),
914 ElementsAre("-D", "FORWARD", "-i", "arc_ns0",
915 "-j", "ACCEPT", "-w"),
916 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900917 EXPECT_CALL(runner,
918 iptables(StrEq("mangle"),
919 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
920 "MARK", "--set-mark", "1/1", "-w"),
921 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900922 EXPECT_CALL(runner, iptables(StrEq("mangle"),
923 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
924 "-j", "MARK", "--set-mark",
925 "0x00000200/0x00003f00", "-w"),
926 true, nullptr));
927 EXPECT_CALL(runner, iptables(StrEq("mangle"),
928 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
929 "-j", "CONNMARK", "--restore-mark",
930 "--mask", "0xffff0000", "-w"),
931 true, nullptr));
932 EXPECT_CALL(runner, ip6tables(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, ip6tables(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, iptables(StrEq("mangle"),
943 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
944 "-j", "apply_vpn_mark", "-w"),
945 true, nullptr));
946 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
947 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
948 "-j", "apply_vpn_mark", "-w"),
949 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900950 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
951 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
952 false));
953
Hugo Benichifcf81022020-12-04 11:01:37 +0900954 ConnectedNamespace nsinfo = {};
955 nsinfo.pid = kTestPID;
956 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900957 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900958 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900959 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900960 nsinfo.host_ifname = "arc_ns0";
961 nsinfo.peer_ifname = "veth0";
962 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
963 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900964 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900965 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900966}
967
Hugo Benichi8d622b52020-08-13 15:24:12 +0900968TEST(DatapathTest, StartRoutingDevice_Arc) {
969 MockProcessRunner runner;
970 MockFirewall firewall;
971 EXPECT_CALL(runner, iptables(StrEq("nat"),
972 ElementsAre("-A", "PREROUTING", "-i", "eth0",
973 "-m", "socket", "--nowildcard", "-j",
974 "ACCEPT", "-w"),
975 true, nullptr));
976 EXPECT_CALL(runner, iptables(StrEq("nat"),
977 ElementsAre("-A", "PREROUTING", "-i", "eth0",
978 "-p", "tcp", "-j", "DNAT",
979 "--to-destination", "1.2.3.4", "-w"),
980 true, nullptr));
981 EXPECT_CALL(runner, iptables(StrEq("nat"),
982 ElementsAre("-A", "PREROUTING", "-i", "eth0",
983 "-p", "udp", "-j", "DNAT",
984 "--to-destination", "1.2.3.4", "-w"),
985 true, nullptr));
986 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900987 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
988 "arc_eth0", "-j", "ACCEPT", "-w"),
989 true, nullptr));
990 EXPECT_CALL(runner, iptables(StrEq("filter"),
991 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
992 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +0900993 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900994 EXPECT_CALL(runner, iptables(StrEq("mangle"),
995 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
996 "-j", "MARK", "--set-mark",
997 "0x00002000/0x00003f00", "-w"),
998 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900999 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1000 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
1001 "-j", "MARK", "--set-mark",
1002 "0x03ea0000/0xffff0000", "-w"),
1003 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001004 EXPECT_CALL(
1005 runner,
1006 ip6tables(StrEq("mangle"),
1007 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1008 "--set-mark", "0x00002000/0x00003f00", "-w"),
1009 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001010 EXPECT_CALL(
1011 runner,
1012 ip6tables(StrEq("mangle"),
1013 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1014 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1015 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001016
1017 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001018 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001019 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001020 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001021}
1022
1023TEST(DatapathTest, StartRoutingDevice_CrosVM) {
1024 MockProcessRunner runner;
1025 MockFirewall firewall;
1026 EXPECT_CALL(runner, iptables(StrEq("filter"),
1027 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
1028 "-j", "ACCEPT", "-w"),
1029 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001030 EXPECT_CALL(runner, iptables(StrEq("filter"),
1031 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
1032 "-j", "ACCEPT", "-w"),
1033 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001034 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1035 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1036 "-j", "MARK", "--set-mark",
1037 "0x00002100/0x00003f00", "-w"),
1038 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001039 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1040 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1041 "-j", "CONNMARK", "--restore-mark",
1042 "--mask", "0xffff0000", "-w"),
1043 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001044 EXPECT_CALL(runner, ip6tables(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, ip6tables(StrEq("mangle"),
1050 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1051 "-j", "CONNMARK", "--restore-mark",
1052 "--mask", "0xffff0000", "-w"),
1053 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001054 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1055 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1056 "-j", "apply_vpn_mark", "-w"),
1057 true, nullptr));
1058 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1059 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
1060 "-j", "apply_vpn_mark", "-w"),
1061 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001062
1063 Datapath datapath(&runner, &firewall);
1064 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001065 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001066}
1067
1068TEST(DatapathTest, StopRoutingDevice_Arc) {
1069 MockProcessRunner runner;
1070 MockFirewall firewall;
1071 EXPECT_CALL(runner, iptables(StrEq("nat"),
1072 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1073 "-m", "socket", "--nowildcard", "-j",
1074 "ACCEPT", "-w"),
1075 true, nullptr));
1076 EXPECT_CALL(runner, iptables(StrEq("nat"),
1077 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1078 "-p", "tcp", "-j", "DNAT",
1079 "--to-destination", "1.2.3.4", "-w"),
1080 true, nullptr));
1081 EXPECT_CALL(runner, iptables(StrEq("nat"),
1082 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1083 "-p", "udp", "-j", "DNAT",
1084 "--to-destination", "1.2.3.4", "-w"),
1085 true, nullptr));
1086 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001087 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1088 "arc_eth0", "-j", "ACCEPT", "-w"),
1089 true, nullptr));
1090 EXPECT_CALL(runner, iptables(StrEq("filter"),
1091 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1092 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +09001093 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001094 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1095 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1096 "-j", "MARK", "--set-mark",
1097 "0x00002000/0x00003f00", "-w"),
1098 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001099 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1100 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
1101 "-j", "MARK", "--set-mark",
1102 "0x03ea0000/0xffff0000", "-w"),
1103 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001104 EXPECT_CALL(
1105 runner,
1106 ip6tables(StrEq("mangle"),
1107 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1108 "--set-mark", "0x00002000/0x00003f00", "-w"),
1109 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001110 EXPECT_CALL(
1111 runner,
1112 ip6tables(StrEq("mangle"),
1113 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
1114 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
1115 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001116
1117 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001118 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001119 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001120 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001121}
1122
1123TEST(DatapathTest, StopRoutingDevice_CrosVM) {
1124 MockProcessRunner runner;
1125 MockFirewall firewall;
1126 EXPECT_CALL(runner, iptables(StrEq("filter"),
1127 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
1128 "-j", "ACCEPT", "-w"),
1129 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +09001130 EXPECT_CALL(runner, iptables(StrEq("filter"),
1131 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
1132 "-j", "ACCEPT", "-w"),
1133 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +09001134 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1135 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1136 "-j", "MARK", "--set-mark",
1137 "0x00002100/0x00003f00", "-w"),
1138 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +09001139 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1140 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1141 "-j", "CONNMARK", "--restore-mark",
1142 "--mask", "0xffff0000", "-w"),
1143 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +09001144 EXPECT_CALL(runner, ip6tables(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, ip6tables(StrEq("mangle"),
1150 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1151 "-j", "CONNMARK", "--restore-mark",
1152 "--mask", "0xffff0000", "-w"),
1153 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +09001154 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1155 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1156 "-j", "apply_vpn_mark", "-w"),
1157 true, nullptr));
1158 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1159 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
1160 "-j", "apply_vpn_mark", "-w"),
1161 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +09001162
1163 Datapath datapath(&runner, &firewall);
1164 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +09001165 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +09001166}
1167
Hugo Benichid82d8832020-08-14 10:05:03 +09001168TEST(DatapathTest, StartStopIpForwarding) {
1169 struct {
1170 IpFamily family;
1171 std::string iif;
1172 std::string oif;
1173 std::vector<std::string> start_args;
1174 std::vector<std::string> stop_args;
1175 bool result;
1176 } testcases[] = {
1177 {IpFamily::IPv4, "", "", {}, {}, false},
1178 {IpFamily::NONE, "foo", "bar", {}, {}, false},
1179 {IpFamily::IPv4,
1180 "foo",
1181 "bar",
1182 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1183 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1184 true},
1185 {IpFamily::IPv4,
1186 "",
1187 "bar",
1188 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1189 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1190 true},
1191 {IpFamily::IPv4,
1192 "foo",
1193 "",
1194 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1195 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1196 true},
1197 {IpFamily::IPv6,
1198 "foo",
1199 "bar",
1200 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1201 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1202 true},
1203 {IpFamily::IPv6,
1204 "",
1205 "bar",
1206 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1207 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1208 true},
1209 {IpFamily::IPv6,
1210 "foo",
1211 "",
1212 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1213 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1214 true},
1215 {IpFamily::Dual,
1216 "foo",
1217 "bar",
1218 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1219 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
1220 true},
1221 {IpFamily::Dual,
1222 "",
1223 "bar",
1224 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1225 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
1226 true},
1227 {IpFamily::Dual,
1228 "foo",
1229 "",
1230 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1231 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
1232 true},
1233 };
1234
1235 for (const auto& tt : testcases) {
1236 MockProcessRunner runner;
1237 MockFirewall firewall;
1238 if (tt.result) {
1239 if (tt.family & IpFamily::IPv4) {
1240 EXPECT_CALL(runner,
1241 iptables(StrEq("filter"), tt.start_args, true, nullptr))
1242 .WillOnce(Return(0));
1243 EXPECT_CALL(runner,
1244 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
1245 .WillOnce(Return(0));
1246 }
1247 if (tt.family & IpFamily::IPv6) {
1248 EXPECT_CALL(runner,
1249 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
1250 .WillOnce(Return(0));
1251 EXPECT_CALL(runner,
1252 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
1253 .WillOnce(Return(0));
1254 }
1255 }
1256 Datapath datapath(&runner, &firewall);
1257
1258 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
1259 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
1260 }
1261}
1262
Hugo Benichi76be34a2020-08-26 22:35:54 +09001263TEST(DatapathTest, StartStopConnectionPinning) {
1264 MockProcessRunner runner;
1265 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +09001266
1267 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001268 EXPECT_CALL(runner,
1269 iptables(StrEq("mangle"),
1270 ElementsAre("-A", "check_routing_mark", "-o", "eth0",
1271 "-m", "mark", "!", "--mark",
1272 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1273 true, nullptr));
1274 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1275 ElementsAre("-A", "check_routing_mark", "-o",
1276 "eth0", "-m", "mark", "!", "--mark",
1277 "0x03eb0000/0xffff0000", "-j",
1278 "DROP", "-w"),
1279 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001280 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1281 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1282 "-j", "CONNMARK", "--set-mark",
1283 "0x03eb0000/0xffff0000", "-w"),
1284 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001285 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1286 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1287 "-j", "CONNMARK", "--set-mark",
1288 "0x03eb0000/0xffff0000", "-w"),
1289 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001290 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1291 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1292 "-j", "CONNMARK", "--save-mark",
1293 "--mask", "0x00003f00", "-w"),
1294 true, nullptr));
1295 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1296 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1297 "-j", "CONNMARK", "--save-mark",
1298 "--mask", "0x00003f00", "-w"),
1299 true, nullptr));
1300 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1301 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1302 "-j", "CONNMARK", "--restore-mark",
1303 "--mask", "0x00003f00", "-w"),
1304 true, nullptr));
1305 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1306 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1307 "-j", "CONNMARK", "--restore-mark",
1308 "--mask", "0x00003f00", "-w"),
1309 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +09001310
Hugo Benichi1af52392020-11-27 18:09:32 +09001311 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001312 EXPECT_CALL(runner,
1313 iptables(StrEq("mangle"),
1314 ElementsAre("-D", "check_routing_mark", "-o", "eth0",
1315 "-m", "mark", "!", "--mark",
1316 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1317 true, nullptr));
1318 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1319 ElementsAre("-D", "check_routing_mark", "-o",
1320 "eth0", "-m", "mark", "!", "--mark",
1321 "0x03eb0000/0xffff0000", "-j",
1322 "DROP", "-w"),
1323 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001324 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1325 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1326 "-j", "CONNMARK", "--set-mark",
1327 "0x03eb0000/0xffff0000", "-w"),
1328 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001329 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1330 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1331 "-j", "CONNMARK", "--set-mark",
1332 "0x03eb0000/0xffff0000", "-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", "--save-mark",
1337 "--mask", "0x00003f00", "-w"),
1338 true, nullptr));
1339 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1340 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1341 "-j", "CONNMARK", "--save-mark",
1342 "--mask", "0x00003f00", "-w"),
1343 true, nullptr));
1344 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1345 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1346 "-j", "CONNMARK", "--restore-mark",
1347 "--mask", "0x00003f00", "-w"),
1348 true, nullptr));
1349 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1350 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1351 "-j", "CONNMARK", "--restore-mark",
1352 "--mask", "0x00003f00", "-w"),
1353 true, nullptr));
1354
Hugo Benichi76be34a2020-08-26 22:35:54 +09001355 Datapath datapath(&runner, &firewall);
1356 datapath.SetIfnameIndex("eth0", 3);
1357 datapath.StartConnectionPinning("eth0");
1358 datapath.StopConnectionPinning("eth0");
1359}
1360
Hugo Benichibfc49112020-12-14 12:54:44 +09001361TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +09001362 MockProcessRunner runner;
1363 MockFirewall firewall;
1364
1365 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001366 EXPECT_CALL(runner,
1367 iptables(StrEq("mangle"),
1368 ElementsAre("-A", "check_routing_mark", "-o", "arcbr0",
1369 "-m", "mark", "!", "--mark",
1370 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1371 true, nullptr));
1372 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1373 ElementsAre("-A", "check_routing_mark", "-o",
1374 "arcbr0", "-m", "mark", "!",
1375 "--mark", "0x03ed0000/0xffff0000",
1376 "-j", "DROP", "-w"),
1377 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001378 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1379 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1380 "-j", "CONNMARK", "--set-mark",
1381 "0x03ed0000/0xffff0000", "-w"),
1382 true, nullptr));
1383 EXPECT_CALL(runner,
1384 iptables(StrEq("mangle"),
1385 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1386 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1387 true, nullptr));
1388 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1389 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1390 "-j", "CONNMARK", "--set-mark",
1391 "0x03ed0000/0xffff0000", "-w"),
1392 true, nullptr));
1393 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1394 ElementsAre("-A", "apply_vpn_mark", "-j",
1395 "MARK", "--set-mark",
1396 "0x03ed0000/0xffff0000", "-w"),
1397 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001398 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1399 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1400 "-j", "CONNMARK", "--save-mark",
1401 "--mask", "0x00003f00", "-w"),
1402 true, nullptr));
1403 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1404 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1405 "-j", "CONNMARK", "--save-mark",
1406 "--mask", "0x00003f00", "-w"),
1407 true, nullptr));
1408 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1409 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1410 "-j", "CONNMARK", "--restore-mark",
1411 "--mask", "0x00003f00", "-w"),
1412 true, nullptr));
1413 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1414 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1415 "-j", "CONNMARK", "--restore-mark",
1416 "--mask", "0x00003f00", "-w"),
1417 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001418 EXPECT_CALL(runner, iptables(StrEq("nat"),
1419 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1420 "-j", "MASQUERADE", "-w"),
1421 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001422 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001423 EXPECT_CALL(runner,
1424 iptables(StrEq("mangle"),
1425 ElementsAre("-D", "check_routing_mark", "-o", "arcbr0",
1426 "-m", "mark", "!", "--mark",
1427 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1428 true, nullptr));
1429 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1430 ElementsAre("-D", "check_routing_mark", "-o",
1431 "arcbr0", "-m", "mark", "!",
1432 "--mark", "0x03ed0000/0xffff0000",
1433 "-j", "DROP", "-w"),
1434 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001435 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1436 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1437 "-j", "CONNMARK", "--set-mark",
1438 "0x03ed0000/0xffff0000", "-w"),
1439 true, nullptr));
1440 EXPECT_CALL(runner,
1441 iptables(StrEq("mangle"),
1442 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1443 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1444 true, nullptr));
1445 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1446 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1447 "-j", "CONNMARK", "--set-mark",
1448 "0x03ed0000/0xffff0000", "-w"),
1449 true, nullptr));
1450 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1451 ElementsAre("-D", "apply_vpn_mark", "-j",
1452 "MARK", "--set-mark",
1453 "0x03ed0000/0xffff0000", "-w"),
1454 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001455 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1456 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1457 "-j", "CONNMARK", "--save-mark",
1458 "--mask", "0x00003f00", "-w"),
1459 true, nullptr));
1460 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1461 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1462 "-j", "CONNMARK", "--save-mark",
1463 "--mask", "0x00003f00", "-w"),
1464 true, nullptr));
1465 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1466 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1467 "-j", "CONNMARK", "--restore-mark",
1468 "--mask", "0x00003f00", "-w"),
1469 true, nullptr));
1470 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1471 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1472 "-j", "CONNMARK", "--restore-mark",
1473 "--mask", "0x00003f00", "-w"),
1474 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001475 EXPECT_CALL(runner, iptables(StrEq("nat"),
1476 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1477 "-j", "MASQUERADE", "-w"),
1478 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001479
1480 Datapath datapath(&runner, &firewall);
1481 datapath.SetIfnameIndex("arcbr0", 5);
1482 datapath.StartVpnRouting("arcbr0");
1483 datapath.StopVpnRouting("arcbr0");
1484}
1485
Hugo Benichibfc49112020-12-14 12:54:44 +09001486TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
1487 MockProcessRunner runner;
1488 MockFirewall firewall;
1489
1490 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001491 EXPECT_CALL(runner,
1492 iptables(StrEq("mangle"),
1493 ElementsAre("-A", "check_routing_mark", "-o", "tun0",
1494 "-m", "mark", "!", "--mark",
1495
1496 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1497 true, nullptr));
1498 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1499 ElementsAre("-A", "check_routing_mark", "-o",
1500 "tun0", "-m", "mark", "!", "--mark",
1501
1502 "0x03ed0000/0xffff0000", "-j",
1503 "DROP", "-w"),
1504 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001505 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1506 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1507 "-j", "CONNMARK", "--set-mark",
1508 "0x03ed0000/0xffff0000", "-w"),
1509 true, nullptr));
1510 EXPECT_CALL(runner,
1511 iptables(StrEq("mangle"),
1512 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1513 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1514 true, nullptr));
1515 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1516 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1517 "-j", "CONNMARK", "--set-mark",
1518 "0x03ed0000/0xffff0000", "-w"),
1519 true, nullptr));
1520 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1521 ElementsAre("-A", "apply_vpn_mark", "-j",
1522 "MARK", "--set-mark",
1523 "0x03ed0000/0xffff0000", "-w"),
1524 true, nullptr));
1525 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1526 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1527 "-j", "CONNMARK", "--save-mark",
1528 "--mask", "0x00003f00", "-w"),
1529 true, nullptr));
1530 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1531 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1532 "-j", "CONNMARK", "--save-mark",
1533 "--mask", "0x00003f00", "-w"),
1534 true, nullptr));
1535 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1536 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1537 "-j", "CONNMARK", "--restore-mark",
1538 "--mask", "0x00003f00", "-w"),
1539 true, nullptr));
1540 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1541 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1542 "-j", "CONNMARK", "--restore-mark",
1543 "--mask", "0x00003f00", "-w"),
1544 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001545 EXPECT_CALL(runner, iptables(StrEq("nat"),
1546 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1547 "-j", "MASQUERADE", "-w"),
1548 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001549 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001550 EXPECT_CALL(runner,
1551 iptables(StrEq("mangle"),
1552 ElementsAre("-D", "check_routing_mark", "-o", "tun0",
1553 "-m", "mark", "!", "--mark",
1554
1555 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1556 true, nullptr));
1557 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1558 ElementsAre("-D", "check_routing_mark", "-o",
1559 "tun0", "-m", "mark", "!", "--mark",
1560
1561 "0x03ed0000/0xffff0000", "-j",
1562 "DROP", "-w"),
1563 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001564 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1565 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1566 "-j", "CONNMARK", "--set-mark",
1567 "0x03ed0000/0xffff0000", "-w"),
1568 true, nullptr));
1569 EXPECT_CALL(runner,
1570 iptables(StrEq("mangle"),
1571 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1572 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1573 true, nullptr));
1574 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1575 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1576 "-j", "CONNMARK", "--set-mark",
1577 "0x03ed0000/0xffff0000", "-w"),
1578 true, nullptr));
1579 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1580 ElementsAre("-D", "apply_vpn_mark", "-j",
1581 "MARK", "--set-mark",
1582 "0x03ed0000/0xffff0000", "-w"),
1583 true, nullptr));
1584 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1585 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1586 "-j", "CONNMARK", "--save-mark",
1587 "--mask", "0x00003f00", "-w"),
1588 true, nullptr));
1589 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1590 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1591 "-j", "CONNMARK", "--save-mark",
1592 "--mask", "0x00003f00", "-w"),
1593 true, nullptr));
1594 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1595 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1596 "-j", "CONNMARK", "--restore-mark",
1597 "--mask", "0x00003f00", "-w"),
1598 true, nullptr));
1599 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1600 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1601 "-j", "CONNMARK", "--restore-mark",
1602 "--mask", "0x00003f00", "-w"),
1603 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001604 EXPECT_CALL(runner, iptables(StrEq("nat"),
1605 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1606 "-j", "MASQUERADE", "-w"),
1607 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001608 // Start tun0 <-> arcbr0 routing
1609 EXPECT_CALL(runner, iptables(StrEq("filter"),
1610 ElementsAre("-A", "FORWARD", "-i", "tun0", "-o",
1611 "arcbr0", "-j", "ACCEPT", "-w"),
1612 true, nullptr));
1613 EXPECT_CALL(runner, iptables(StrEq("filter"),
1614 ElementsAre("-A", "FORWARD", "-i", "arcbr0",
1615 "-o", "tun0", "-j", "ACCEPT", "-w"),
1616 true, nullptr));
1617 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1618 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1619 "-j", "MARK", "--set-mark",
1620 "0x00002000/0x00003f00", "-w"),
1621 true, nullptr));
1622 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1623 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1624 "-j", "MARK", "--set-mark",
1625 "0x03ed0000/0xffff0000", "-w"),
1626 true, nullptr));
1627 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1628 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1629 "-j", "MARK", "--set-mark",
1630 "0x00002000/0x00003f00", "-w"),
1631 true, nullptr));
1632 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1633 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1634 "-j", "MARK", "--set-mark",
1635 "0x03ed0000/0xffff0000", "-w"),
1636 true, nullptr));
1637 // Stop tun0 <-> arcbr0 routing
1638 EXPECT_CALL(runner, iptables(StrEq("filter"),
1639 ElementsAre("-D", "FORWARD", "-i", "tun0", "-o",
1640 "arcbr0", "-j", "ACCEPT", "-w"),
1641 true, nullptr));
1642 EXPECT_CALL(runner, iptables(StrEq("filter"),
1643 ElementsAre("-D", "FORWARD", "-i", "arcbr0",
1644 "-o", "tun0", "-j", "ACCEPT", "-w"),
1645 true, nullptr));
1646 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1647 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1648 "-j", "MARK", "--set-mark",
1649 "0x00002000/0x00003f00", "-w"),
1650 true, nullptr));
1651 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1652 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1653 "-j", "MARK", "--set-mark",
1654 "0x03ed0000/0xffff0000", "-w"),
1655 true, nullptr));
1656 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1657 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1658 "-j", "MARK", "--set-mark",
1659 "0x00002000/0x00003f00", "-w"),
1660 true, nullptr));
1661 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1662 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1663 "-j", "MARK", "--set-mark",
1664 "0x03ed0000/0xffff0000", "-w"),
1665 true, nullptr));
1666
1667 Datapath datapath(&runner, &firewall);
1668 datapath.SetIfnameIndex("tun0", 5);
1669 datapath.StartVpnRouting("tun0");
1670 datapath.StopVpnRouting("tun0");
1671}
1672
Garrick Evansf0ab7132019-06-18 14:50:42 +09001673TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001674 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001675 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001676 EXPECT_CALL(runner, iptables(StrEq("nat"),
1677 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1678 "-m", "socket", "--nowildcard", "-j",
1679 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001680 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001681 EXPECT_CALL(runner, iptables(StrEq("nat"),
1682 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1683 "-p", "tcp", "-j", "DNAT",
1684 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001685 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001686 EXPECT_CALL(runner, iptables(StrEq("nat"),
1687 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1688 "-p", "udp", "-j", "DNAT",
1689 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001690 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001691 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001692 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001693}
1694
1695TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001696 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001697 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001698 EXPECT_CALL(runner, iptables(StrEq("nat"),
1699 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1700 "-m", "socket", "--nowildcard", "-j",
1701 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001702 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001703 EXPECT_CALL(runner, iptables(StrEq("nat"),
1704 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1705 "-p", "tcp", "-j", "DNAT",
1706 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001707 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001708 EXPECT_CALL(runner, iptables(StrEq("nat"),
1709 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1710 "-p", "udp", "-j", "DNAT",
1711 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001712 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001713 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001714 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001715}
1716
Garrick Evans664a82f2019-12-17 12:18:05 +09001717TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001718 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001719 MockFirewall firewall;
1720 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001721
Garrick Evans664a82f2019-12-17 12:18:05 +09001722 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001723 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001724 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001725 EXPECT_EQ(ioctl_reqs, expected);
1726 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001727 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001728}
1729
1730TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001731 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001732 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001733 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001734 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1735 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1736 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001737 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001738 .WillOnce(Return(1));
1739 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1740 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1741 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001742 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001743 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1744 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1745 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001746 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001747 .WillOnce(Return(1));
1748 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1749 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1750 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001751 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001752 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001753 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001754}
1755
Taoyu Lica49c832019-12-06 17:56:43 +09001756TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001757 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001758 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001759 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1760 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1761 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001762 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001763 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1764 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1765 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001766 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001767 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001768 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001769}
1770
Taoyu Li90c13912019-11-26 17:56:54 +09001771TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001772 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001773 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001774 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1775 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1776 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001777 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001778 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1779 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1780 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001781 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001782 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001783 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001784}
1785
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001786TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001787 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001788 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001789 EXPECT_CALL(runner,
1790 ip6(StrEq("route"), StrEq("replace"),
1791 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001792 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001793 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001794}
1795
Hugo Benichie8758b52020-04-03 14:49:01 +09001796TEST(DatapathTest, AddIPv4Route) {
1797 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001798 MockFirewall firewall;
1799 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001800
1801 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1802 Ipv4Addr(255, 255, 255, 0));
1803 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1804 Ipv4Addr(255, 255, 255, 0));
1805 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1806 Ipv4Addr(255, 255, 255, 252));
1807 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1808 Ipv4Addr(255, 255, 255, 252));
1809
1810 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1811 SIOCDELRT};
1812 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001813
1814 std::string route1 =
1815 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1816 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1817 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1818 "RTF_GATEWAY}";
1819 std::string route2 =
1820 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1821 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1822 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1823 std::vector<std::string> captured_routes;
1824 for (const auto& route : ioctl_rtentry_args) {
1825 std::ostringstream stream;
1826 stream << route.second;
1827 captured_routes.emplace_back(stream.str());
1828 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001829 EXPECT_EQ(route1, captured_routes[0]);
1830 EXPECT_EQ(route1, captured_routes[1]);
1831 EXPECT_EQ(route2, captured_routes[2]);
1832 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001833 ioctl_reqs.clear();
1834 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001835}
1836
Garrick Evans2f581a02020-05-11 10:43:35 +09001837TEST(DatapathTest, ArcVethHostName) {
1838 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1839 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1840 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1841 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1842 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1843 EXPECT_EQ("vethexceeds_ify", ifname);
1844 EXPECT_LT(ifname.length(), IFNAMSIZ);
1845}
1846
Garrick Evans8a067562020-05-11 12:47:30 +09001847TEST(DatapathTest, ArcBridgeName) {
1848 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1849 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1850 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1851 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1852 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1853 EXPECT_EQ("arc_exceeds_ify", ifname);
1854 EXPECT_LT(ifname.length(), IFNAMSIZ);
1855}
1856
Garrick Evans3388a032020-03-24 11:25:55 +09001857} // namespace patchpanel