blob: 19cf8d7ba004673b8f3d41cb15a3b65ab43f9e62 [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>
Hugo Benichiaba7e2e2021-02-22 14:47:11 +09008#include <linux/sockios.h>
Taoyu Li90c13912019-11-26 17:56:54 +09009#include <net/if.h>
Garrick Evansc7ae82c2019-09-04 16:25:10 +090010#include <sys/ioctl.h>
11
Hugo Benichibb38bdd2021-05-14 10:36:11 +090012#include <memory>
Garrick Evansf0ab7132019-06-18 14:50:42 +090013#include <utility>
14#include <vector>
15
Garrick Evansc7ae82c2019-09-04 16:25:10 +090016#include <base/bind.h>
hscham4ce3c992021-02-19 16:37:23 +090017#include <base/callback_helpers.h>
Hugo Benichic72b07e2021-01-22 22:55:05 +090018#include <base/strings/string_split.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090019#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090020#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090021#include <gtest/gtest.h>
22
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090023#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090024#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090025
Garrick Evans8e8e3472020-01-23 14:03:50 +090026using testing::_;
27using testing::ElementsAre;
Hugo Benichic72b07e2021-01-22 22:55:05 +090028using testing::ElementsAreArray;
Garrick Evans8e8e3472020-01-23 14:03:50 +090029using testing::Return;
30using testing::StrEq;
31
Garrick Evans3388a032020-03-24 11:25:55 +090032namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090033namespace {
34
Hugo Benichi76675592020-04-08 14:29:57 +090035// TODO(hugobenichi) Centralize this constant definition
36constexpr pid_t kTestPID = -2;
37
Hugo Benichie8758b52020-04-03 14:49:01 +090038std::vector<ioctl_req_t> ioctl_reqs;
39std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Hugo Benichiaba7e2e2021-02-22 14:47:11 +090040std::vector<std::pair<std::string, struct ifreq>> ioctl_ifreq_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090041
42// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090043int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090044 ioctl_reqs.push_back(req);
45 return 0;
46}
47
48// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
49int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
50 ioctl_reqs.push_back(req);
51 ioctl_rtentry_args.push_back({"", *arg});
52 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
53 // this value to ioctl() on the stack.
54 if (arg->rt_dev) {
55 auto& cap = ioctl_rtentry_args.back();
56 cap.first = std::string(arg->rt_dev);
57 cap.second.rt_dev = (char*)cap.first.c_str();
58 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090059 return 0;
60}
61
Hugo Benichiaba7e2e2021-02-22 14:47:11 +090062// Capture ifreq ioctls operations and succeed.
63int ioctl_ifreq_cap(int fd, ioctl_req_t req, void* arg) {
64 ioctl_reqs.push_back(req);
65 switch (req) {
66 case SIOCBRADDBR:
67 case SIOCBRDELBR: {
68 ioctl_ifreq_args.push_back({std::string(static_cast<char*>(arg)), {}});
69 break;
70 }
71 case SIOCBRADDIF: {
72 struct ifreq* ifr = static_cast<struct ifreq*>(arg);
73 ioctl_ifreq_args.push_back({std::string(ifr->ifr_name), *ifr});
74 break;
75 }
76 }
77 return 0;
78}
79
Hugo Benichi1e3bab52021-01-25 22:41:58 +090080std::vector<std::string> SplitCommand(const std::string& command) {
81 return base::SplitString(command, " ",
82 base::WhitespaceHandling::TRIM_WHITESPACE,
83 base::SplitResult::SPLIT_WANT_NONEMPTY);
84}
85
Garrick Evansc7ae82c2019-09-04 16:25:10 +090086} // namespace
87
Hugo Benichic72b07e2021-01-22 22:55:05 +090088using IpFamily::Dual;
89using IpFamily::IPv4;
90using IpFamily::IPv6;
91
Garrick Evans8e8e3472020-01-23 14:03:50 +090092class MockProcessRunner : public MinijailedProcessRunner {
93 public:
94 MockProcessRunner() = default;
95 ~MockProcessRunner() = default;
96
Garrick Evans8e8e3472020-01-23 14:03:50 +090097 MOCK_METHOD4(ip,
98 int(const std::string& obj,
99 const std::string& cmd,
100 const std::vector<std::string>& args,
101 bool log_failures));
102 MOCK_METHOD4(ip6,
103 int(const std::string& obj,
104 const std::string& cmd,
105 const std::vector<std::string>& args,
106 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900107 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +0900108 int(const std::string& table,
109 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900110 bool log_failures,
111 std::string* output));
112 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +0900113 int(const std::string& table,
114 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900115 bool log_failures,
116 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900117 MOCK_METHOD3(sysctl_w,
118 int(const std::string& key,
119 const std::string& value,
120 bool log_failures));
Jie Jiangf6799312021-05-14 16:27:03 +0900121 MOCK_METHOD2(ip_netns_add,
122 int(const std::string& netns_name, bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900123 MOCK_METHOD3(ip_netns_attach,
124 int(const std::string& netns_name,
125 pid_t netns_pid,
126 bool log_failures));
127 MOCK_METHOD2(ip_netns_delete,
128 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900129};
130
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900131void Verify_ip(MockProcessRunner& runner, const std::string& command) {
132 auto args = SplitCommand(command);
133 const auto object = args[0];
134 const auto action = args[1];
135 args.erase(args.begin());
136 args.erase(args.begin());
137 EXPECT_CALL(runner,
138 ip(StrEq(object), StrEq(action), ElementsAreArray(args), _));
139}
140
141void Verify_ip6(MockProcessRunner& runner, const std::string& command) {
142 auto args = SplitCommand(command);
143 const auto object = args[0];
144 const auto action = args[1];
145 args.erase(args.begin());
146 args.erase(args.begin());
147 EXPECT_CALL(runner,
148 ip6(StrEq(object), StrEq(action), ElementsAreArray(args), _));
149}
150
Hugo Benichic72b07e2021-01-22 22:55:05 +0900151void Verify_iptables(MockProcessRunner& runner,
152 IpFamily family,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900153 const std::string& command,
154 int call_count = 1) {
Hugo Benichic72b07e2021-01-22 22:55:05 +0900155 auto args =
156 base::SplitString(command, " ", base::WhitespaceHandling::TRIM_WHITESPACE,
157 base::SplitResult::SPLIT_WANT_NONEMPTY);
158 const auto table = args[0];
159 args.erase(args.begin());
160 if (family & IPv4)
161 EXPECT_CALL(runner,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900162 iptables(StrEq(table), ElementsAreArray(args), _, nullptr))
163 .Times(call_count);
Hugo Benichic72b07e2021-01-22 22:55:05 +0900164 if (family & IPv6)
165 EXPECT_CALL(runner,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900166 ip6tables(StrEq(table), ElementsAreArray(args), _, nullptr))
167 .Times(call_count);
Hugo Benichic72b07e2021-01-22 22:55:05 +0900168}
169
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900170void Verify_sysctl_w(MockProcessRunner& runner,
171 const std::string& key,
172 const std::string& value) {
173 EXPECT_CALL(runner, sysctl_w(StrEq(key), StrEq(value), _));
174}
175
Jie Jiangf6799312021-05-14 16:27:03 +0900176void Verify_ip_netns_add(MockProcessRunner& runner,
177 const std::string& netns_name) {
178 EXPECT_CALL(runner, ip_netns_add(StrEq(netns_name), _));
179}
180
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900181void Verify_ip_netns_attach(MockProcessRunner& runner,
182 const std::string& netns_name,
183 pid_t pid) {
184 EXPECT_CALL(runner, ip_netns_attach(StrEq(netns_name), pid, _));
185}
186
187void Verify_ip_netns_delete(MockProcessRunner& runner,
188 const std::string& netns_name) {
189 EXPECT_CALL(runner, ip_netns_delete(StrEq(netns_name), _));
190}
191
Hugo Benichid82d8832020-08-14 10:05:03 +0900192TEST(DatapathTest, IpFamily) {
Hugo Benichic72b07e2021-01-22 22:55:05 +0900193 EXPECT_EQ(Dual, IPv4 | IPv6);
194 EXPECT_EQ(Dual & IPv4, IPv4);
195 EXPECT_EQ(Dual & IPv6, IPv6);
196 EXPECT_NE(Dual, IPv4);
197 EXPECT_NE(Dual, IPv6);
198 EXPECT_NE(IPv4, IPv6);
Hugo Benichid82d8832020-08-14 10:05:03 +0900199}
200
Hugo Benichibf811c62020-09-07 17:30:45 +0900201TEST(DatapathTest, Start) {
202 MockProcessRunner runner;
203 MockFirewall firewall;
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900204
Hugo Benichibf811c62020-09-07 17:30:45 +0900205 // Asserts for sysctl modifications
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900206 Verify_sysctl_w(runner, "net.ipv4.ip_forward", "1");
207 Verify_sysctl_w(runner, "net.ipv4.ip_local_port_range", "32768 47103");
208 Verify_sysctl_w(runner, "net.ipv6.conf.all.forwarding", "1");
Hugo Benichic72b07e2021-01-22 22:55:05 +0900209
210 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
211 // Asserts for iptables chain reset.
212 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900213 {Dual, "filter -D OUTPUT -j vpn_accept -w"},
214 {Dual, "filter -D FORWARD -j vpn_accept -w"},
215 {Dual, "filter -D OUTPUT -j vpn_lockdown -w"},
216 {Dual, "filter -D FORWARD -j vpn_lockdown -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900217 {Dual, "filter -F FORWARD -w"},
218 {Dual, "mangle -F FORWARD -w"},
219 {Dual, "mangle -F INPUT -w"},
220 {Dual, "mangle -F OUTPUT -w"},
221 {Dual, "mangle -F POSTROUTING -w"},
222 {Dual, "mangle -F PREROUTING -w"},
223 {Dual, "mangle -L apply_local_source_mark -w"},
224 {Dual, "mangle -F apply_local_source_mark -w"},
225 {Dual, "mangle -X apply_local_source_mark -w"},
226 {Dual, "mangle -L apply_vpn_mark -w"},
227 {Dual, "mangle -F apply_vpn_mark -w"},
228 {Dual, "mangle -X apply_vpn_mark -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900229 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
230 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
231 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900232 {Dual, "filter -L vpn_accept -w"},
233 {Dual, "filter -F vpn_accept -w"},
234 {Dual, "filter -X vpn_accept -w"},
235 {Dual, "filter -L vpn_lockdown -w"},
236 {Dual, "filter -F vpn_lockdown -w"},
237 {Dual, "filter -X vpn_lockdown -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900238 {IPv4, "nat -L redirect_dns -w"},
239 {IPv4, "nat -F redirect_dns -w"},
240 {IPv4, "nat -X redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900241 {IPv4, "nat -F POSTROUTING -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900242 {IPv4, "nat -F OUTPUT -w"},
Hugo Benichi7a066242021-04-07 23:47:32 +0900243 // Asserts for SNAT rules of traffic forwarded from downstream interfaces.
Hugo Benichic72b07e2021-01-22 22:55:05 +0900244 {IPv4,
Hugo Benichi7a066242021-04-07 23:47:32 +0900245 "filter -A FORWARD -m mark --mark 0x00000001/0x00000001 -m state "
246 "--state INVALID -j DROP "
Hugo Benichic72b07e2021-01-22 22:55:05 +0900247 "-w"},
Hugo Benichi7a066242021-04-07 23:47:32 +0900248 {IPv4,
249 "nat -A POSTROUTING -m mark --mark 0x00000001/0x00000001 -j MASQUERADE "
250 "-w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900251 // Asserts for AddForwardEstablishedRule
252 {IPv4,
253 "filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT -w"},
Hugo Benichiac799a82021-03-25 00:16:16 +0900254 {IPv4, "filter -A FORWARD -i arc+ -j ACCEPT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900255 // Asserts for AddSourceIPv4DropRule() calls.
256 {IPv4, "filter -N drop_guest_ipv4_prefix -w"},
257 {IPv4, "filter -I OUTPUT -j drop_guest_ipv4_prefix -w"},
258 {IPv4,
259 "filter -I drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/23 -j DROP "
260 "-w"},
261 {IPv4,
262 "filter -I drop_guest_ipv4_prefix -o wlan+ -s 100.115.92.0/23 -j DROP "
263 "-w"},
264 {IPv4,
265 "filter -I drop_guest_ipv4_prefix -o mlan+ -s 100.115.92.0/23 -j DROP "
266 "-w"},
267 {IPv4,
268 "filter -I drop_guest_ipv4_prefix -o usb+ -s 100.115.92.0/23 -j DROP "
269 "-w"},
270 {IPv4,
271 "filter -I drop_guest_ipv4_prefix -o wwan+ -s 100.115.92.0/23 -j DROP "
272 "-w"},
273 {IPv4,
274 "filter -I drop_guest_ipv4_prefix -o rmnet+ -s 100.115.92.0/23 -j DROP "
275 "-w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900276 // Asserts for OUTPUT ndp connmark bypass rule
277 {IPv6,
278 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT "
279 "-w"},
280 {IPv6,
281 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-advertisement -j "
282 "ACCEPT -w"},
283 {IPv6,
284 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j "
285 "ACCEPT -w"},
286 {IPv6,
287 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j "
288 "ACCEPT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900289 // Asserts for OUTPUT CONNMARK restore rule
290 {Dual,
291 "mangle -A OUTPUT -j CONNMARK --restore-mark --mask 0xffff0000 -w"},
292 // Asserts for apply_local_source_mark chain
293 {Dual, "mangle -N apply_local_source_mark -w"},
294 {Dual, "mangle -A OUTPUT -j apply_local_source_mark -w"},
295 {Dual,
296 "mangle -A apply_local_source_mark -m owner --uid-owner chronos -j MARK "
297 "--set-mark 0x00008100/0x0000ff00 -w"},
298 {Dual,
299 "mangle -A apply_local_source_mark -m owner --uid-owner debugd -j MARK "
300 "--set-mark 0x00008200/0x0000ff00 -w"},
301 {Dual,
302 "mangle -A apply_local_source_mark -m owner --uid-owner cups -j MARK "
303 "--set-mark 0x00008200/0x0000ff00 -w"},
304 {Dual,
305 "mangle -A apply_local_source_mark -m owner --uid-owner lpadmin -j MARK "
306 "--set-mark 0x00008200/0x0000ff00 -w"},
307 {Dual,
308 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd -j "
309 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
310 {Dual,
311 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd-exec "
312 "-j MARK --set-mark 0x00008400/0x0000ff00 -w"},
313 {Dual,
314 "mangle -A apply_local_source_mark -m owner --uid-owner tlsdate -j MARK "
315 "--set-mark 0x00008400/0x0000ff00 -w"},
316 {Dual,
317 "mangle -A apply_local_source_mark -m owner --uid-owner pluginvm -j "
318 "MARK --set-mark 0x00008200/0x0000ff00 -w"},
319 {Dual,
320 "mangle -A apply_local_source_mark -m owner --uid-owner fuse-smbfs -j "
321 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
322 {Dual,
323 "mangle -A apply_local_source_mark -m cgroup --cgroup 0x00010001 -j "
324 "MARK --set-mark 0x00000300/0x0000ff00 -w"},
325 {Dual,
326 "mangle -A apply_local_source_mark -m mark --mark 0x0/0x00003f00 -j "
327 "MARK --set-mark 0x00000400/0x00003f00 -w"},
328 // Asserts for apply_vpn_mark chain
329 {Dual, "mangle -N apply_vpn_mark -w"},
330 {Dual,
331 "mangle -A OUTPUT -m mark --mark 0x00008000/0x0000c000 -j "
332 "apply_vpn_mark -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900333 // Asserts for redirect_dns chain creation
334 {IPv4, "nat -N redirect_dns -w"},
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900335 // Asserts for VPN filter chain creations
336 {Dual, "filter -N vpn_lockdown -w"},
337 {Dual, "filter -I OUTPUT -j vpn_lockdown -w"},
338 {Dual, "filter -I FORWARD -j vpn_lockdown -w"},
339 {Dual, "filter -N vpn_accept -w"},
340 {Dual, "filter -I OUTPUT -j vpn_accept -w"},
341 {Dual, "filter -I FORWARD -j vpn_accept -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900342 };
343 for (const auto& c : iptables_commands) {
344 Verify_iptables(runner, c.first, c.second);
345 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900346
347 Datapath datapath(&runner, &firewall);
348 datapath.Start();
349}
350
351TEST(DatapathTest, Stop) {
352 MockProcessRunner runner;
353 MockFirewall firewall;
354 // Asserts for sysctl modifications
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900355 Verify_sysctl_w(runner, "net.ipv4.ip_local_port_range", "32768 61000");
356 Verify_sysctl_w(runner, "net.ipv6.conf.all.forwarding", "0");
357 Verify_sysctl_w(runner, "net.ipv4.ip_forward", "0");
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900358 // Asserts for iptables chain reset.
Hugo Benichic72b07e2021-01-22 22:55:05 +0900359 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
360 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900361 {Dual, "filter -D OUTPUT -j vpn_accept -w"},
362 {Dual, "filter -D FORWARD -j vpn_accept -w"},
363 {Dual, "filter -D OUTPUT -j vpn_lockdown -w"},
364 {Dual, "filter -D FORWARD -j vpn_lockdown -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900365 {Dual, "filter -F FORWARD -w"},
366 {Dual, "mangle -F FORWARD -w"},
367 {Dual, "mangle -F INPUT -w"},
368 {Dual, "mangle -F OUTPUT -w"},
369 {Dual, "mangle -F POSTROUTING -w"},
370 {Dual, "mangle -F PREROUTING -w"},
371 {Dual, "mangle -L apply_local_source_mark -w"},
372 {Dual, "mangle -F apply_local_source_mark -w"},
373 {Dual, "mangle -X apply_local_source_mark -w"},
374 {Dual, "mangle -L apply_vpn_mark -w"},
375 {Dual, "mangle -F apply_vpn_mark -w"},
376 {Dual, "mangle -X apply_vpn_mark -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900377 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
378 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
379 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900380 {Dual, "filter -L vpn_accept -w"},
381 {Dual, "filter -F vpn_accept -w"},
382 {Dual, "filter -X vpn_accept -w"},
383 {Dual, "filter -L vpn_lockdown -w"},
384 {Dual, "filter -F vpn_lockdown -w"},
385 {Dual, "filter -X vpn_lockdown -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900386 {IPv4, "nat -L redirect_dns -w"},
387 {IPv4, "nat -F redirect_dns -w"},
388 {IPv4, "nat -X redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900389 {IPv4, "nat -F POSTROUTING -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900390 {IPv4, "nat -F OUTPUT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900391 };
392 for (const auto& c : iptables_commands) {
393 Verify_iptables(runner, c.first, c.second);
394 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900395
396 Datapath datapath(&runner, &firewall);
397 datapath.Stop();
398}
399
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900400TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900401 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900402 MockFirewall firewall;
403 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900404 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900405 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900406 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900407 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900408 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900409 std::vector<ioctl_req_t> expected = {
410 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
411 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900412 EXPECT_EQ(ioctl_reqs, expected);
413 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900414 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900415}
416
417TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900418 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900419 MockFirewall firewall;
420 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900421 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900422 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900423 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900424 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900425 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900426 std::vector<ioctl_req_t> expected = {
427 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
428 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900429 EXPECT_EQ(ioctl_reqs, expected);
430 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900431 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900432}
433
Garrick Evans621ed262019-11-13 12:28:43 +0900434TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900435 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900436 MockFirewall firewall;
437 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900438 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900439 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900440 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
441 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900442 EXPECT_EQ(ioctl_reqs, expected);
443 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900444 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900445}
446
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900447TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900448 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900449 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900450 Verify_ip(runner, "tuntap del foo0 mode tap");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900451 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900452 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900453}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900454
Hugo Benichi33860d72020-07-09 16:34:01 +0900455TEST(DatapathTest, NetnsAttachName) {
456 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900457 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900458 Verify_ip_netns_delete(runner, "netns_foo");
459 Verify_ip_netns_attach(runner, "netns_foo", 1234);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900460 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900461 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
462}
463
464TEST(DatapathTest, NetnsDeleteName) {
465 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900466 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900467 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900468 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900469 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
470}
471
Garrick Evans8a949dc2019-07-18 16:17:53 +0900472TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900473 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900474 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900475 Verify_ip(runner, "addr add 1.1.1.1/30 brd 1.1.1.3 dev br");
476 Verify_ip(runner, "link set br up");
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900477
478 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900479 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900480
481 EXPECT_EQ(1, ioctl_reqs.size());
482 EXPECT_EQ(SIOCBRADDBR, ioctl_reqs[0]);
483 EXPECT_EQ("br", ioctl_ifreq_args[0].first);
484 ioctl_reqs.clear();
485 ioctl_ifreq_args.clear();
486}
487
488TEST(DatapathTest, RemoveBridge) {
489 MockProcessRunner runner;
490 MockFirewall firewall;
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900491 Verify_ip(runner, "link set br down");
492
493 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
494 datapath.RemoveBridge("br");
495
496 EXPECT_EQ(1, ioctl_reqs.size());
497 EXPECT_EQ(SIOCBRDELBR, ioctl_reqs[0]);
498 EXPECT_EQ("br", ioctl_ifreq_args[0].first);
499 ioctl_reqs.clear();
500 ioctl_ifreq_args.clear();
501}
502
503TEST(DatapathTest, AddToBridge) {
504 MockProcessRunner runner;
505 MockFirewall firewall;
506
507 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
508 datapath.SetIfnameIndex("vethwlan0", 5);
509 datapath.AddToBridge("arcbr0", "vethwlan0");
510
511 EXPECT_EQ(1, ioctl_reqs.size());
512 EXPECT_EQ(SIOCBRADDIF, ioctl_reqs[0]);
513 EXPECT_EQ("arcbr0", ioctl_ifreq_args[0].first);
514 EXPECT_EQ(5, ioctl_ifreq_args[0].second.ifr_ifindex);
515
516 ioctl_reqs.clear();
517 ioctl_ifreq_args.clear();
Garrick Evans8a949dc2019-07-18 16:17:53 +0900518}
519
Hugo Benichi76675592020-04-08 14:29:57 +0900520TEST(DatapathTest, ConnectVethPair) {
521 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900522 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900523 Verify_ip(runner,
524 "link add veth_foo type veth peer name peer_foo netns netns_foo");
525 Verify_ip(runner,
526 "addr add 100.115.92.169/30 brd 100.115.92.171 dev peer_foo");
527 Verify_ip(runner,
528 "link set dev peer_foo up addr 01:02:03:04:05:06 multicast on");
529 Verify_ip(runner, "link set veth_foo up");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900530 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900531 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
532 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900533 Ipv4Addr(100, 115, 92, 169), 30, true));
534}
535
Garrick Evans2470caa2020-03-04 14:15:41 +0900536TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900537 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900538 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900539 Verify_ip(runner,
540 "link add veth_foo type veth peer name peer_foo netns netns_foo");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900541 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900542 EXPECT_TRUE(
543 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900544}
545
546TEST(DatapathTest, ToggleInterface) {
547 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900548 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900549 Verify_ip(runner, "link set foo up");
550 Verify_ip(runner, "link set bar down");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900551 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900552 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
553 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
554}
555
556TEST(DatapathTest, ConfigureInterface) {
557 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900558 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900559 Verify_ip(runner, "addr add 1.1.1.1/30 brd 1.1.1.3 dev foo");
560 Verify_ip(runner, "link set dev foo up addr 02:02:02:02:02:02 multicast on");
Garrick Evans2470caa2020-03-04 14:15:41 +0900561
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900562 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900563 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
564 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
565 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900566}
567
568TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900569 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900570 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900571 Verify_ip(runner, "link delete foo");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900572 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900573 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900574}
575
Hugo Benichi7c342672020-09-08 09:18:14 +0900576TEST(DatapathTest, StartRoutingNamespace) {
577 MockProcessRunner runner;
578 MockFirewall firewall;
579 MacAddress mac = {1, 2, 3, 4, 5, 6};
580
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900581 Verify_ip_netns_delete(runner, "netns_foo");
582 Verify_ip_netns_attach(runner, "netns_foo", kTestPID);
583 Verify_ip(runner,
584 "link add arc_ns0 type veth peer name veth0 netns netns_foo");
585 Verify_ip(runner, "addr add 100.115.92.130/30 brd 100.115.92.131 dev veth0");
586 Verify_ip(runner,
587 "link set dev veth0 up addr 01:02:03:04:05:06 multicast off");
588 Verify_ip(runner, "link set arc_ns0 up");
589 Verify_ip(runner,
590 "addr add 100.115.92.129/30 brd 100.115.92.131 dev arc_ns0");
591 Verify_ip(runner,
592 "link set dev arc_ns0 up addr 01:02:03:04:05:06 multicast off");
Hugo Benichi860ef532021-01-25 17:19:36 +0900593 Verify_iptables(runner, IPv4, "filter -A FORWARD -o arc_ns0 -j ACCEPT -w");
594 Verify_iptables(runner, IPv4, "filter -A FORWARD -i arc_ns0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900595 Verify_iptables(runner, Dual, "mangle -N PREROUTING_arc_ns0 -w");
596 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_ns0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900597 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900598 "mangle -A PREROUTING -i arc_ns0 -j PREROUTING_arc_ns0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900599 Verify_iptables(runner, IPv4,
600 "mangle -A PREROUTING_arc_ns0 -j MARK --set-mark "
601 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900602 Verify_iptables(runner, Dual,
603 "mangle -A PREROUTING_arc_ns0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900604 "0x00000200/0x00003f00 -w");
605 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900606 "mangle -A PREROUTING_arc_ns0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900607 "--restore-mark --mask 0xffff0000 -w");
608 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900609 "mangle -A PREROUTING_arc_ns0 -j apply_vpn_mark -w");
Hugo Benichi7c342672020-09-08 09:18:14 +0900610
Hugo Benichifcf81022020-12-04 11:01:37 +0900611 ConnectedNamespace nsinfo = {};
612 nsinfo.pid = kTestPID;
613 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900614 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900615 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900616 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900617 nsinfo.host_ifname = "arc_ns0";
618 nsinfo.peer_ifname = "veth0";
619 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
620 base::DoNothing());
621 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900622 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900623 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900624 ioctl_reqs.clear();
625 ioctl_rtentry_args.clear();
626}
627
628TEST(DatapathTest, StopRoutingNamespace) {
629 MockProcessRunner runner;
630 MockFirewall firewall;
631
Hugo Benichi860ef532021-01-25 17:19:36 +0900632 Verify_iptables(runner, IPv4, "filter -D FORWARD -o arc_ns0 -j ACCEPT -w");
633 Verify_iptables(runner, IPv4, "filter -D FORWARD -i arc_ns0 -j ACCEPT -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900634 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900635 "mangle -D PREROUTING -i arc_ns0 -j PREROUTING_arc_ns0 -w");
636 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_ns0 -w");
637 Verify_iptables(runner, Dual, "mangle -X PREROUTING_arc_ns0 -w");
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900638 Verify_ip_netns_delete(runner, "netns_foo");
639 Verify_ip(runner, "link delete arc_ns0");
Hugo Benichi7c342672020-09-08 09:18:14 +0900640
Hugo Benichifcf81022020-12-04 11:01:37 +0900641 ConnectedNamespace nsinfo = {};
642 nsinfo.pid = kTestPID;
643 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900644 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900645 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900646 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900647 nsinfo.host_ifname = "arc_ns0";
648 nsinfo.peer_ifname = "veth0";
649 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
650 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900651 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900652 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900653}
654
Jie Jiangf6799312021-05-14 16:27:03 +0900655TEST(DatapathTest, StartRoutingNewNamespace) {
656 MockProcessRunner runner;
657 MockFirewall firewall;
658 MacAddress mac = {1, 2, 3, 4, 5, 6};
659
660 // The running may fail at checking ScopedNS.IsValid() in
661 // Datapath::ConnectVethPair(), so we only check if `ip netns add` is invoked
662 // correctly here.
663 Verify_ip_netns_add(runner, "netns_foo");
664
665 ConnectedNamespace nsinfo = {};
666 nsinfo.pid = ConnectedNamespace::kNewNetnsPid;
667 nsinfo.netns_name = "netns_foo";
668 nsinfo.source = TrafficSource::USER;
669 nsinfo.outbound_ifname = "";
670 nsinfo.route_on_vpn = true;
671 nsinfo.host_ifname = "arc_ns0";
672 nsinfo.peer_ifname = "veth0";
673 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
674 base::DoNothing());
675 nsinfo.peer_mac_addr = mac;
676 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
677 datapath.StartRoutingNamespace(nsinfo);
678 ioctl_reqs.clear();
679 ioctl_rtentry_args.clear();
680}
681
Hugo Benichi8d622b52020-08-13 15:24:12 +0900682TEST(DatapathTest, StartRoutingDevice_Arc) {
683 MockProcessRunner runner;
684 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900685 Verify_iptables(
686 runner, IPv4,
687 "nat -A PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
688 Verify_iptables(
689 runner, IPv4,
690 "nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
691 Verify_iptables(
692 runner, IPv4,
693 "nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
694 Verify_iptables(runner, IPv4,
695 "filter -A FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
696 Verify_iptables(runner, IPv4,
697 "filter -A FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900698 Verify_iptables(runner, Dual, "mangle -N PREROUTING_arc_eth0 -w");
699 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_eth0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900700 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900701 "mangle -A PREROUTING -i arc_eth0 -j PREROUTING_arc_eth0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900702 Verify_iptables(runner, IPv4,
703 "mangle -A PREROUTING_arc_eth0 -j MARK --set-mark "
704 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900705 Verify_iptables(runner, Dual,
706 "mangle -A PREROUTING_arc_eth0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900707 "0x00002000/0x00003f00 -w");
708 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900709 "mangle -A PREROUTING_arc_eth0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900710 "0x03ea0000/0xffff0000 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900711
712 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900713 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900714 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900715 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900716}
717
718TEST(DatapathTest, StartRoutingDevice_CrosVM) {
719 MockProcessRunner runner;
720 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900721 Verify_iptables(runner, IPv4, "filter -A FORWARD -o vmtap0 -j ACCEPT -w");
722 Verify_iptables(runner, IPv4, "filter -A FORWARD -i vmtap0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900723 Verify_iptables(runner, Dual, "mangle -N PREROUTING_vmtap0 -w");
724 Verify_iptables(runner, Dual, "mangle -F PREROUTING_vmtap0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900725 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900726 "mangle -A PREROUTING -i vmtap0 -j PREROUTING_vmtap0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900727 Verify_iptables(runner, IPv4,
728 "mangle -A PREROUTING_vmtap0 -j MARK --set-mark "
729 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900730 Verify_iptables(runner, Dual,
731 "mangle -A PREROUTING_vmtap0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900732 "0x00002100/0x00003f00 -w");
733 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900734 "mangle -A PREROUTING_vmtap0 -j CONNMARK --restore-mark "
735 "--mask 0xffff0000 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900736 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900737 "mangle -A PREROUTING_vmtap0 -j apply_vpn_mark -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900738
739 Datapath datapath(&runner, &firewall);
740 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900741 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900742}
743
744TEST(DatapathTest, StopRoutingDevice_Arc) {
745 MockProcessRunner runner;
746 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900747 Verify_iptables(
748 runner, IPv4,
749 "nat -D PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
750 Verify_iptables(
751 runner, IPv4,
752 "nat -D PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
753 Verify_iptables(
754 runner, IPv4,
755 "nat -D PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
756 Verify_iptables(runner, IPv4,
757 "filter -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
758 Verify_iptables(runner, IPv4,
759 "filter -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
760 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900761 "mangle -D PREROUTING -i arc_eth0 -j PREROUTING_arc_eth0 -w");
762 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arc_eth0 -w");
763 Verify_iptables(runner, Dual, "mangle -X PREROUTING_arc_eth0 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900764
765 Datapath datapath(&runner, &firewall);
766 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900767 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900768}
769
770TEST(DatapathTest, StopRoutingDevice_CrosVM) {
771 MockProcessRunner runner;
772 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900773 Verify_iptables(runner, IPv4, "filter -D FORWARD -o vmtap0 -j ACCEPT -w");
774 Verify_iptables(runner, IPv4, "filter -D FORWARD -i vmtap0 -j ACCEPT -w");
775 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900776 "mangle -D PREROUTING -i vmtap0 -j PREROUTING_vmtap0 -w");
777 Verify_iptables(runner, Dual, "mangle -F PREROUTING_vmtap0 -w");
778 Verify_iptables(runner, Dual, "mangle -X PREROUTING_vmtap0 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900779
780 Datapath datapath(&runner, &firewall);
781 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900782 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900783}
784
Hugo Benichi76be34a2020-08-26 22:35:54 +0900785TEST(DatapathTest, StartStopConnectionPinning) {
786 MockProcessRunner runner;
787 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +0900788
789 // Setup
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900790 Verify_iptables(runner, Dual, "mangle -N POSTROUTING_eth0 -w");
791 Verify_iptables(runner, Dual, "mangle -F POSTROUTING_eth0 -w",
792 2 /* Start and Stop */);
Hugo Benichi860ef532021-01-25 17:19:36 +0900793 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900794 "mangle -A POSTROUTING -o eth0 -j POSTROUTING_eth0 -w");
795 Verify_iptables(runner, Dual,
796 "mangle -A POSTROUTING_eth0 -j CONNMARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900797 "0x03eb0000/0xffff0000 -w");
798 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900799 "mangle -A POSTROUTING_eth0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900800 "--save-mark --mask 0x00003f00 -w");
801 Verify_iptables(runner, Dual,
802 "mangle -A PREROUTING -i eth0 -j CONNMARK "
803 "--restore-mark --mask 0x00003f00 -w");
Hugo Benichi155de002021-01-19 16:45:46 +0900804
Hugo Benichi1af52392020-11-27 18:09:32 +0900805 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900806 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900807 "mangle -D POSTROUTING -o eth0 -j POSTROUTING_eth0 -w");
808 Verify_iptables(runner, Dual, "mangle -X POSTROUTING_eth0 -w");
809 Verify_iptables(runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900810 "mangle -D PREROUTING -i eth0 -j CONNMARK "
811 "--restore-mark --mask 0x00003f00 -w");
Hugo Benichi1af52392020-11-27 18:09:32 +0900812
Hugo Benichi76be34a2020-08-26 22:35:54 +0900813 Datapath datapath(&runner, &firewall);
814 datapath.SetIfnameIndex("eth0", 3);
815 datapath.StartConnectionPinning("eth0");
816 datapath.StopConnectionPinning("eth0");
817}
818
Hugo Benichibfc49112020-12-14 12:54:44 +0900819TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +0900820 MockProcessRunner runner;
821 MockFirewall firewall;
822
823 // Setup
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900824 Verify_iptables(runner, Dual, "mangle -N POSTROUTING_arcbr0 -w");
825 Verify_iptables(runner, Dual, "mangle -F POSTROUTING_arcbr0 -w",
826 2 /* Start and Stop */);
827 Verify_iptables(runner, Dual,
828 "mangle -A POSTROUTING -o arcbr0 -j POSTROUTING_arcbr0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900829 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900830 "mangle -A POSTROUTING_arcbr0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900831 "--set-mark 0x03ed0000/0xffff0000 -w");
832 Verify_iptables(
833 runner, Dual,
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900834 "mangle -A apply_vpn_mark -m mark ! --mark 0x0/0xffff0000 -j ACCEPT -w");
835 Verify_iptables(
836 runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900837 "mangle -A apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
838 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900839 "mangle -A POSTROUTING_arcbr0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900840 "--save-mark --mask 0x00003f00 -w");
841 Verify_iptables(runner, Dual,
842 "mangle -A PREROUTING -i arcbr0 -j CONNMARK "
843 "--restore-mark --mask 0x00003f00 -w");
844 Verify_iptables(runner, IPv4,
845 "nat -A POSTROUTING -o arcbr0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900846 Verify_iptables(runner, IPv4,
847 "nat -A OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
848 "redirect_dns -w");
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900849 Verify_iptables(runner, Dual,
850 "filter -A vpn_accept -m mark "
851 "--mark 0x03ed0000/0xffff0000 -j ACCEPT -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900852
Hugo Benichi2a940542020-10-26 18:50:49 +0900853 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900854 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900855 "mangle -D POSTROUTING -o arcbr0 -j POSTROUTING_arcbr0 -w");
856 Verify_iptables(runner, Dual, "mangle -X POSTROUTING_arcbr0 -w");
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900857 Verify_iptables(runner, Dual, "mangle -F apply_vpn_mark -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900858 Verify_iptables(runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900859 "mangle -D PREROUTING -i arcbr0 -j CONNMARK "
860 "--restore-mark --mask 0x00003f00 -w");
861 Verify_iptables(runner, IPv4,
862 "nat -D POSTROUTING -o arcbr0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900863 Verify_iptables(runner, IPv4,
864 "nat -D OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
865 "redirect_dns -w");
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900866 Verify_iptables(runner, Dual, "filter -F vpn_accept -w");
Hugo Benichi2a940542020-10-26 18:50:49 +0900867
868 Datapath datapath(&runner, &firewall);
869 datapath.SetIfnameIndex("arcbr0", 5);
870 datapath.StartVpnRouting("arcbr0");
871 datapath.StopVpnRouting("arcbr0");
872}
873
Hugo Benichibfc49112020-12-14 12:54:44 +0900874TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
875 MockProcessRunner runner;
876 MockFirewall firewall;
877
878 // Setup
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900879 Verify_iptables(runner, Dual, "mangle -N POSTROUTING_tun0 -w");
880 Verify_iptables(runner, Dual, "mangle -F POSTROUTING_tun0 -w",
881 2 /* Start and Stop */);
882 Verify_iptables(runner, Dual,
883 "mangle -A POSTROUTING -o tun0 -j POSTROUTING_tun0 -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900884 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900885 "mangle -A POSTROUTING_tun0 -j CONNMARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900886 "0x03ed0000/0xffff0000 -w");
887 Verify_iptables(
888 runner, Dual,
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900889 "mangle -A apply_vpn_mark -m mark ! --mark 0x0/0xffff0000 -j ACCEPT -w");
890 Verify_iptables(
891 runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900892 "mangle -A apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
893 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900894 "mangle -A POSTROUTING_tun0 -j CONNMARK "
Hugo Benichi860ef532021-01-25 17:19:36 +0900895 "--save-mark --mask 0x00003f00 -w");
896 Verify_iptables(runner, Dual,
897 "mangle -A PREROUTING -i tun0 -j CONNMARK "
898 "--restore-mark --mask 0x00003f00 -w");
899 Verify_iptables(runner, IPv4, "nat -A POSTROUTING -o tun0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900900 Verify_iptables(runner, IPv4,
901 "nat -A OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
902 "redirect_dns -w");
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900903 Verify_iptables(runner, Dual,
904 "filter -A vpn_accept -m mark "
905 "--mark 0x03ed0000/0xffff0000 -j ACCEPT -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900906 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900907 Verify_iptables(runner, Dual,
Hugo Benichi50fe47f2021-03-29 11:33:25 +0900908 "mangle -D POSTROUTING -o tun0 -j POSTROUTING_tun0 -w");
909 Verify_iptables(runner, Dual, "mangle -X POSTROUTING_tun0 -w");
Hugo Benichi3540c7f2021-03-29 13:14:42 +0900910 Verify_iptables(runner, Dual, "mangle -F apply_vpn_mark -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900911 Verify_iptables(runner, Dual,
Hugo Benichi860ef532021-01-25 17:19:36 +0900912 "mangle -D PREROUTING -i tun0 -j CONNMARK "
913 "--restore-mark --mask 0x00003f00 -w");
914 Verify_iptables(runner, IPv4, "nat -D POSTROUTING -o tun0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900915 Verify_iptables(runner, IPv4,
916 "nat -D OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
917 "redirect_dns -w");
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900918 Verify_iptables(runner, Dual, "filter -F vpn_accept -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900919 // Start tun0 <-> arcbr0 routing
Hugo Benichi860ef532021-01-25 17:19:36 +0900920 Verify_iptables(runner, IPv4,
921 "filter -A FORWARD -i tun0 -o arcbr0 -j ACCEPT -w");
922 Verify_iptables(runner, IPv4,
923 "filter -A FORWARD -i arcbr0 -o tun0 -j ACCEPT -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900924 Verify_iptables(runner, Dual, "mangle -N PREROUTING_arcbr0 -w");
925 Verify_iptables(runner, Dual, "mangle -F PREROUTING_arcbr0 -w",
926 2 /* Start and Stop */);
Hugo Benichi860ef532021-01-25 17:19:36 +0900927 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900928 "mangle -A PREROUTING -i arcbr0 -j PREROUTING_arcbr0 -w");
Hugo Benichi7a066242021-04-07 23:47:32 +0900929 Verify_iptables(runner, IPv4,
930 "mangle -A PREROUTING_arcbr0 -j MARK --set-mark "
931 "0x00000001/0x00000001 -w");
Hugo Benichid872d3d2021-03-29 10:20:53 +0900932 Verify_iptables(runner, Dual,
933 "mangle -A PREROUTING_arcbr0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900934 "0x00002000/0x00003f00 -w");
935 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900936 "mangle -A PREROUTING_arcbr0 -j MARK --set-mark "
Hugo Benichi860ef532021-01-25 17:19:36 +0900937 "0x03ed0000/0xffff0000 -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900938 // Stop tun0 <-> arcbr0 routing
Hugo Benichi860ef532021-01-25 17:19:36 +0900939 Verify_iptables(runner, IPv4,
940 "filter -D FORWARD -i tun0 -o arcbr0 -j ACCEPT -w");
941 Verify_iptables(runner, IPv4,
942 "filter -D FORWARD -i arcbr0 -o tun0 -j ACCEPT -w");
943 Verify_iptables(runner, Dual,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900944 "mangle -D PREROUTING -i arcbr0 -j PREROUTING_arcbr0 -w");
945 Verify_iptables(runner, Dual, "mangle -X PREROUTING_arcbr0 -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900946
947 Datapath datapath(&runner, &firewall);
948 datapath.SetIfnameIndex("tun0", 5);
949 datapath.StartVpnRouting("tun0");
950 datapath.StopVpnRouting("tun0");
951}
952
Garrick Evansf0ab7132019-06-18 14:50:42 +0900953TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900954 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900955 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900956 Verify_iptables(
957 runner, IPv4,
958 "nat -A PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
959 Verify_iptables(
960 runner, IPv4,
961 "nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
962 Verify_iptables(
963 runner, IPv4,
964 "nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
965
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900966 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900967 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900968}
969
970TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900971 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900972 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900973 Verify_iptables(
974 runner, IPv4,
975 "nat -D PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
976 Verify_iptables(
977 runner, IPv4,
978 "nat -D PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
979 Verify_iptables(
980 runner, IPv4,
981 "nat -D PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
982
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900983 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900984 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900985}
986
Garrick Evans664a82f2019-12-17 12:18:05 +0900987TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900988 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900989 MockFirewall firewall;
990 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +0900991
Garrick Evans664a82f2019-12-17 12:18:05 +0900992 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +0900993 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +0900994 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +0900995 EXPECT_EQ(ioctl_reqs, expected);
996 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900997 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +0900998}
999
1000TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001001 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001002 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001003 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001004 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1005 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1006 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001007 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001008 .WillOnce(Return(1));
1009 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1010 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1011 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001012 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001013 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1014 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1015 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001016 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001017 .WillOnce(Return(1));
1018 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1019 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1020 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001021 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001022 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001023 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001024}
1025
Taoyu Lica49c832019-12-06 17:56:43 +09001026TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001027 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001028 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001029 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1030 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1031 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001032 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001033 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1034 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1035 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001036 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001037 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001038 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001039}
1040
Taoyu Li90c13912019-11-26 17:56:54 +09001041TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001042 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001043 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +09001044 Verify_iptables(runner, IPv6,
1045 "filter -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
1046 Verify_iptables(runner, IPv6,
1047 "filter -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001048 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001049 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001050}
1051
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001052TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001053 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001054 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +09001055 Verify_ip6(runner, "route replace 2001:da8:e00::1234/128 dev eth0");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001056 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001057 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001058}
1059
Hugo Benichie8758b52020-04-03 14:49:01 +09001060TEST(DatapathTest, AddIPv4Route) {
1061 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001062 MockFirewall firewall;
1063 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001064
1065 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1066 Ipv4Addr(255, 255, 255, 0));
1067 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1068 Ipv4Addr(255, 255, 255, 0));
1069 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1070 Ipv4Addr(255, 255, 255, 252));
1071 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1072 Ipv4Addr(255, 255, 255, 252));
1073
1074 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1075 SIOCDELRT};
1076 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001077
1078 std::string route1 =
1079 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1080 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1081 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1082 "RTF_GATEWAY}";
1083 std::string route2 =
1084 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1085 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1086 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1087 std::vector<std::string> captured_routes;
1088 for (const auto& route : ioctl_rtentry_args) {
1089 std::ostringstream stream;
1090 stream << route.second;
1091 captured_routes.emplace_back(stream.str());
1092 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001093 EXPECT_EQ(route1, captured_routes[0]);
1094 EXPECT_EQ(route1, captured_routes[1]);
1095 EXPECT_EQ(route2, captured_routes[2]);
1096 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001097 ioctl_reqs.clear();
1098 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001099}
1100
Hugo Benichi1e0656f2021-02-15 15:43:38 +09001101TEST(DatapathTest, RedirectDnsRules) {
1102 MockProcessRunner runner;
1103 MockFirewall firewall;
1104
1105 Verify_iptables(runner, IPv4,
1106 "nat -I redirect_dns -p tcp --dport 53 -o eth0 -j DNAT "
1107 "--to-destination 192.168.1.1 -w");
1108 Verify_iptables(runner, IPv4,
1109 "nat -I redirect_dns -p udp --dport 53 -o eth0 -j DNAT "
1110 "--to-destination 192.168.1.1 -w");
1111 Verify_iptables(runner, IPv4,
1112 "nat -I redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1113 "--to-destination 1.1.1.1 -w");
1114 Verify_iptables(runner, IPv4,
1115 "nat -I redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1116 "--to-destination 1.1.1.1 -w");
1117 Verify_iptables(runner, IPv4,
1118 "nat -D redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1119 "--to-destination 1.1.1.1 -w");
1120 Verify_iptables(runner, IPv4,
1121 "nat -D redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1122 "--to-destination 1.1.1.1 -w");
1123 Verify_iptables(runner, IPv4,
1124 "nat -I redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1125 "--to-destination 8.8.8.8 -w");
1126 Verify_iptables(runner, IPv4,
1127 "nat -I redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1128 "--to-destination 8.8.8.8 -w");
1129 Verify_iptables(runner, IPv4,
1130 "nat -D redirect_dns -p tcp --dport 53 -o eth0 -j DNAT "
1131 "--to-destination 192.168.1.1 -w");
1132 Verify_iptables(runner, IPv4,
1133 "nat -D redirect_dns -p udp --dport 53 -o eth0 -j DNAT "
1134 "--to-destination 192.168.1.1 -w");
1135 Verify_iptables(runner, IPv4,
1136 "nat -D redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1137 "--to-destination 8.8.8.8 -w");
1138 Verify_iptables(runner, IPv4,
1139 "nat -D redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1140 "--to-destination 8.8.8.8 -w");
1141
1142 Datapath datapath(&runner, &firewall);
1143 datapath.RemoveRedirectDnsRule("wlan0");
1144 datapath.RemoveRedirectDnsRule("unknown");
1145 datapath.AddRedirectDnsRule("eth0", "192.168.1.1");
1146 datapath.AddRedirectDnsRule("wlan0", "1.1.1.1");
1147 datapath.AddRedirectDnsRule("wlan0", "8.8.8.8");
1148 datapath.RemoveRedirectDnsRule("eth0");
1149 datapath.RemoveRedirectDnsRule("wlan0");
1150}
1151
Hugo Benichibb38bdd2021-05-14 10:36:11 +09001152TEST(DatapathTest, SetVpnLockdown) {
1153 MockProcessRunner runner;
1154 MockFirewall firewall;
1155
1156 Verify_iptables(runner, Dual,
1157 "filter -A vpn_lockdown -m mark --mark 0x00008000/0x0000c000 "
1158 "-j REJECT -w");
1159 Verify_iptables(runner, Dual, "filter -F vpn_lockdown -w");
1160
1161 Datapath datapath(&runner, &firewall);
1162 datapath.SetVpnLockdown(true);
1163 datapath.SetVpnLockdown(false);
1164}
1165
Garrick Evans2f581a02020-05-11 10:43:35 +09001166TEST(DatapathTest, ArcVethHostName) {
1167 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1168 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1169 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1170 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1171 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1172 EXPECT_EQ("vethexceeds_ify", ifname);
1173 EXPECT_LT(ifname.length(), IFNAMSIZ);
1174}
1175
Garrick Evans8a067562020-05-11 12:47:30 +09001176TEST(DatapathTest, ArcBridgeName) {
1177 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1178 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1179 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1180 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1181 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1182 EXPECT_EQ("arc_exceeds_ify", ifname);
1183 EXPECT_LT(ifname.length(), IFNAMSIZ);
1184}
1185
Garrick Evans3388a032020-03-24 11:25:55 +09001186} // namespace patchpanel