blob: 042486b83dcd67b847f1c459b0baa48109aaea6a [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
Garrick Evansf0ab7132019-06-18 14:50:42 +090012#include <utility>
13#include <vector>
14
Garrick Evansc7ae82c2019-09-04 16:25:10 +090015#include <base/bind.h>
Qijiang Fane90b8792020-03-09 16:15:41 +090016#include <base/bind_helpers.h>
Hugo Benichic72b07e2021-01-22 22:55:05 +090017#include <base/strings/string_split.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090018#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090019#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090020#include <gtest/gtest.h>
21
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090022#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090023#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090024
Garrick Evans8e8e3472020-01-23 14:03:50 +090025using testing::_;
26using testing::ElementsAre;
Hugo Benichic72b07e2021-01-22 22:55:05 +090027using testing::ElementsAreArray;
Garrick Evans8e8e3472020-01-23 14:03:50 +090028using testing::Return;
29using testing::StrEq;
30
Garrick Evans3388a032020-03-24 11:25:55 +090031namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090032namespace {
33
Hugo Benichi76675592020-04-08 14:29:57 +090034// TODO(hugobenichi) Centralize this constant definition
35constexpr pid_t kTestPID = -2;
36
Hugo Benichie8758b52020-04-03 14:49:01 +090037std::vector<ioctl_req_t> ioctl_reqs;
38std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Hugo Benichiaba7e2e2021-02-22 14:47:11 +090039std::vector<std::pair<std::string, struct ifreq>> ioctl_ifreq_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090040
41// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090042int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090043 ioctl_reqs.push_back(req);
44 return 0;
45}
46
47// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
48int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
49 ioctl_reqs.push_back(req);
50 ioctl_rtentry_args.push_back({"", *arg});
51 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
52 // this value to ioctl() on the stack.
53 if (arg->rt_dev) {
54 auto& cap = ioctl_rtentry_args.back();
55 cap.first = std::string(arg->rt_dev);
56 cap.second.rt_dev = (char*)cap.first.c_str();
57 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090058 return 0;
59}
60
Hugo Benichiaba7e2e2021-02-22 14:47:11 +090061// Capture ifreq ioctls operations and succeed.
62int ioctl_ifreq_cap(int fd, ioctl_req_t req, void* arg) {
63 ioctl_reqs.push_back(req);
64 switch (req) {
65 case SIOCBRADDBR:
66 case SIOCBRDELBR: {
67 ioctl_ifreq_args.push_back({std::string(static_cast<char*>(arg)), {}});
68 break;
69 }
70 case SIOCBRADDIF: {
71 struct ifreq* ifr = static_cast<struct ifreq*>(arg);
72 ioctl_ifreq_args.push_back({std::string(ifr->ifr_name), *ifr});
73 break;
74 }
75 }
76 return 0;
77}
78
Hugo Benichi1e3bab52021-01-25 22:41:58 +090079std::vector<std::string> SplitCommand(const std::string& command) {
80 return base::SplitString(command, " ",
81 base::WhitespaceHandling::TRIM_WHITESPACE,
82 base::SplitResult::SPLIT_WANT_NONEMPTY);
83}
84
Garrick Evansc7ae82c2019-09-04 16:25:10 +090085} // namespace
86
Hugo Benichic72b07e2021-01-22 22:55:05 +090087using IpFamily::Dual;
88using IpFamily::IPv4;
89using IpFamily::IPv6;
90
Garrick Evans8e8e3472020-01-23 14:03:50 +090091class MockProcessRunner : public MinijailedProcessRunner {
92 public:
93 MockProcessRunner() = default;
94 ~MockProcessRunner() = default;
95
Garrick Evans8e8e3472020-01-23 14:03:50 +090096 MOCK_METHOD4(ip,
97 int(const std::string& obj,
98 const std::string& cmd,
99 const std::vector<std::string>& args,
100 bool log_failures));
101 MOCK_METHOD4(ip6,
102 int(const std::string& obj,
103 const std::string& cmd,
104 const std::vector<std::string>& args,
105 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900106 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +0900107 int(const std::string& table,
108 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900109 bool log_failures,
110 std::string* output));
111 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +0900112 int(const std::string& table,
113 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900114 bool log_failures,
115 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900116 MOCK_METHOD3(sysctl_w,
117 int(const std::string& key,
118 const std::string& value,
119 bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900120 MOCK_METHOD3(ip_netns_attach,
121 int(const std::string& netns_name,
122 pid_t netns_pid,
123 bool log_failures));
124 MOCK_METHOD2(ip_netns_delete,
125 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900126};
127
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900128void Verify_ip(MockProcessRunner& runner, const std::string& command) {
129 auto args = SplitCommand(command);
130 const auto object = args[0];
131 const auto action = args[1];
132 args.erase(args.begin());
133 args.erase(args.begin());
134 EXPECT_CALL(runner,
135 ip(StrEq(object), StrEq(action), ElementsAreArray(args), _));
136}
137
138void Verify_ip6(MockProcessRunner& runner, const std::string& command) {
139 auto args = SplitCommand(command);
140 const auto object = args[0];
141 const auto action = args[1];
142 args.erase(args.begin());
143 args.erase(args.begin());
144 EXPECT_CALL(runner,
145 ip6(StrEq(object), StrEq(action), ElementsAreArray(args), _));
146}
147
Hugo Benichic72b07e2021-01-22 22:55:05 +0900148void Verify_iptables(MockProcessRunner& runner,
149 IpFamily family,
150 const std::string& command) {
151 auto args =
152 base::SplitString(command, " ", base::WhitespaceHandling::TRIM_WHITESPACE,
153 base::SplitResult::SPLIT_WANT_NONEMPTY);
154 const auto table = args[0];
155 args.erase(args.begin());
156 if (family & IPv4)
157 EXPECT_CALL(runner,
158 iptables(StrEq(table), ElementsAreArray(args), _, nullptr));
159 if (family & IPv6)
160 EXPECT_CALL(runner,
161 ip6tables(StrEq(table), ElementsAreArray(args), _, nullptr));
162}
163
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900164void Verify_sysctl_w(MockProcessRunner& runner,
165 const std::string& key,
166 const std::string& value) {
167 EXPECT_CALL(runner, sysctl_w(StrEq(key), StrEq(value), _));
168}
169
170void Verify_ip_netns_attach(MockProcessRunner& runner,
171 const std::string& netns_name,
172 pid_t pid) {
173 EXPECT_CALL(runner, ip_netns_attach(StrEq(netns_name), pid, _));
174}
175
176void Verify_ip_netns_delete(MockProcessRunner& runner,
177 const std::string& netns_name) {
178 EXPECT_CALL(runner, ip_netns_delete(StrEq(netns_name), _));
179}
180
Hugo Benichid82d8832020-08-14 10:05:03 +0900181TEST(DatapathTest, IpFamily) {
Hugo Benichic72b07e2021-01-22 22:55:05 +0900182 EXPECT_EQ(Dual, IPv4 | IPv6);
183 EXPECT_EQ(Dual & IPv4, IPv4);
184 EXPECT_EQ(Dual & IPv6, IPv6);
185 EXPECT_NE(Dual, IPv4);
186 EXPECT_NE(Dual, IPv6);
187 EXPECT_NE(IPv4, IPv6);
Hugo Benichid82d8832020-08-14 10:05:03 +0900188}
189
Hugo Benichibf811c62020-09-07 17:30:45 +0900190TEST(DatapathTest, Start) {
191 MockProcessRunner runner;
192 MockFirewall firewall;
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900193
Hugo Benichibf811c62020-09-07 17:30:45 +0900194 // Asserts for sysctl modifications
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900195 Verify_sysctl_w(runner, "net.ipv4.ip_forward", "1");
196 Verify_sysctl_w(runner, "net.ipv4.ip_local_port_range", "32768 47103");
197 Verify_sysctl_w(runner, "net.ipv6.conf.all.forwarding", "1");
Hugo Benichic72b07e2021-01-22 22:55:05 +0900198
199 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
200 // Asserts for iptables chain reset.
201 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
202 {Dual, "filter -F FORWARD -w"},
203 {Dual, "mangle -F FORWARD -w"},
204 {Dual, "mangle -F INPUT -w"},
205 {Dual, "mangle -F OUTPUT -w"},
206 {Dual, "mangle -F POSTROUTING -w"},
207 {Dual, "mangle -F PREROUTING -w"},
208 {Dual, "mangle -L apply_local_source_mark -w"},
209 {Dual, "mangle -F apply_local_source_mark -w"},
210 {Dual, "mangle -X apply_local_source_mark -w"},
211 {Dual, "mangle -L apply_vpn_mark -w"},
212 {Dual, "mangle -F apply_vpn_mark -w"},
213 {Dual, "mangle -X apply_vpn_mark -w"},
214 {Dual, "mangle -L check_routing_mark -w"},
215 {Dual, "mangle -F check_routing_mark -w"},
216 {Dual, "mangle -X check_routing_mark -w"},
217 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
218 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
219 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900220 {IPv4, "nat -L redirect_dns -w"},
221 {IPv4, "nat -F redirect_dns -w"},
222 {IPv4, "nat -X redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900223 {IPv4, "nat -F POSTROUTING -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900224 {IPv4, "nat -F OUTPUT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900225 // Asserts for SNAT rules.
226 {IPv4,
227 "filter -A FORWARD -m mark --mark 1/1 -m state --state INVALID -j DROP "
228 "-w"},
229 {IPv4, "nat -A POSTROUTING -m mark --mark 1/1 -j MASQUERADE -w"},
230 // Asserts for AddForwardEstablishedRule
231 {IPv4,
232 "filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT -w"},
233 // Asserts for AddSourceIPv4DropRule() calls.
234 {IPv4, "filter -N drop_guest_ipv4_prefix -w"},
235 {IPv4, "filter -I OUTPUT -j drop_guest_ipv4_prefix -w"},
236 {IPv4,
237 "filter -I drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/23 -j DROP "
238 "-w"},
239 {IPv4,
240 "filter -I drop_guest_ipv4_prefix -o wlan+ -s 100.115.92.0/23 -j DROP "
241 "-w"},
242 {IPv4,
243 "filter -I drop_guest_ipv4_prefix -o mlan+ -s 100.115.92.0/23 -j DROP "
244 "-w"},
245 {IPv4,
246 "filter -I drop_guest_ipv4_prefix -o usb+ -s 100.115.92.0/23 -j DROP "
247 "-w"},
248 {IPv4,
249 "filter -I drop_guest_ipv4_prefix -o wwan+ -s 100.115.92.0/23 -j DROP "
250 "-w"},
251 {IPv4,
252 "filter -I drop_guest_ipv4_prefix -o rmnet+ -s 100.115.92.0/23 -j DROP "
253 "-w"},
254 // Asserts for AddOutboundIPv4SNATMark("vmtap+")
255 {IPv4, "mangle -A PREROUTING -i vmtap+ -j MARK --set-mark 1/1 -w"},
256 // Asserts for OUTPUT ndp connmark bypass rule
257 {IPv6,
258 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT "
259 "-w"},
260 {IPv6,
261 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-advertisement -j "
262 "ACCEPT -w"},
263 {IPv6,
264 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j "
265 "ACCEPT -w"},
266 {IPv6,
267 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j "
268 "ACCEPT -w"},
269 {IPv6,
270 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
271 "router-solicitation -j RETURN -w"},
272 {IPv6,
273 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
274 "router-advertisement -j RETURN -w"},
275 {IPv6,
276 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
277 "neighbour-solicitation -j RETURN -w"},
278 {IPv6,
279 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
280 "neighbour-advertisement -j RETURN -w"},
281 // Asserts for OUTPUT CONNMARK restore rule
282 {Dual,
283 "mangle -A OUTPUT -j CONNMARK --restore-mark --mask 0xffff0000 -w"},
284 // Asserts for apply_local_source_mark chain
285 {Dual, "mangle -N apply_local_source_mark -w"},
286 {Dual, "mangle -A OUTPUT -j apply_local_source_mark -w"},
287 {Dual,
288 "mangle -A apply_local_source_mark -m owner --uid-owner chronos -j MARK "
289 "--set-mark 0x00008100/0x0000ff00 -w"},
290 {Dual,
291 "mangle -A apply_local_source_mark -m owner --uid-owner debugd -j MARK "
292 "--set-mark 0x00008200/0x0000ff00 -w"},
293 {Dual,
294 "mangle -A apply_local_source_mark -m owner --uid-owner cups -j MARK "
295 "--set-mark 0x00008200/0x0000ff00 -w"},
296 {Dual,
297 "mangle -A apply_local_source_mark -m owner --uid-owner lpadmin -j MARK "
298 "--set-mark 0x00008200/0x0000ff00 -w"},
299 {Dual,
300 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd -j "
301 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
302 {Dual,
303 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd-exec "
304 "-j MARK --set-mark 0x00008400/0x0000ff00 -w"},
305 {Dual,
306 "mangle -A apply_local_source_mark -m owner --uid-owner tlsdate -j MARK "
307 "--set-mark 0x00008400/0x0000ff00 -w"},
308 {Dual,
309 "mangle -A apply_local_source_mark -m owner --uid-owner pluginvm -j "
310 "MARK --set-mark 0x00008200/0x0000ff00 -w"},
311 {Dual,
312 "mangle -A apply_local_source_mark -m owner --uid-owner fuse-smbfs -j "
313 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
314 {Dual,
315 "mangle -A apply_local_source_mark -m cgroup --cgroup 0x00010001 -j "
316 "MARK --set-mark 0x00000300/0x0000ff00 -w"},
317 {Dual,
318 "mangle -A apply_local_source_mark -m mark --mark 0x0/0x00003f00 -j "
319 "MARK --set-mark 0x00000400/0x00003f00 -w"},
320 // Asserts for apply_vpn_mark chain
321 {Dual, "mangle -N apply_vpn_mark -w"},
322 {Dual,
323 "mangle -A OUTPUT -m mark --mark 0x00008000/0x0000c000 -j "
324 "apply_vpn_mark -w"},
325 {Dual,
326 "mangle -A apply_vpn_mark -m mark ! --mark 0x0/0xffff0000 -j ACCEPT -w"},
327 // Asserts for check_routing_mark chain
328 {Dual, "mangle -N check_routing_mark -w"},
329 {Dual,
330 "mangle -A POSTROUTING -j CONNMARK --restore-mark --mask 0xffff0000 -w"},
331 {Dual,
332 "mangle -A POSTROUTING -m mark ! --mark 0x0/0xffff0000 -j "
333 "check_routing_mark -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900334 // Asserts for redirect_dns chain creation
335 {IPv4, "nat -N redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900336 };
337 for (const auto& c : iptables_commands) {
338 Verify_iptables(runner, c.first, c.second);
339 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900340
341 Datapath datapath(&runner, &firewall);
342 datapath.Start();
343}
344
345TEST(DatapathTest, Stop) {
346 MockProcessRunner runner;
347 MockFirewall firewall;
348 // Asserts for sysctl modifications
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900349 Verify_sysctl_w(runner, "net.ipv4.ip_local_port_range", "32768 61000");
350 Verify_sysctl_w(runner, "net.ipv6.conf.all.forwarding", "0");
351 Verify_sysctl_w(runner, "net.ipv4.ip_forward", "0");
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900352 // Asserts for iptables chain reset.
Hugo Benichic72b07e2021-01-22 22:55:05 +0900353 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
354 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
355 {Dual, "filter -F FORWARD -w"},
356 {Dual, "mangle -F FORWARD -w"},
357 {Dual, "mangle -F INPUT -w"},
358 {Dual, "mangle -F OUTPUT -w"},
359 {Dual, "mangle -F POSTROUTING -w"},
360 {Dual, "mangle -F PREROUTING -w"},
361 {Dual, "mangle -L apply_local_source_mark -w"},
362 {Dual, "mangle -F apply_local_source_mark -w"},
363 {Dual, "mangle -X apply_local_source_mark -w"},
364 {Dual, "mangle -L apply_vpn_mark -w"},
365 {Dual, "mangle -F apply_vpn_mark -w"},
366 {Dual, "mangle -X apply_vpn_mark -w"},
367 {Dual, "mangle -L check_routing_mark -w"},
368 {Dual, "mangle -F check_routing_mark -w"},
369 {Dual, "mangle -X check_routing_mark -w"},
370 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
371 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
372 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900373 {IPv4, "nat -L redirect_dns -w"},
374 {IPv4, "nat -F redirect_dns -w"},
375 {IPv4, "nat -X redirect_dns -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900376 {IPv4, "nat -F POSTROUTING -w"},
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900377 {IPv4, "nat -F OUTPUT -w"},
Hugo Benichic72b07e2021-01-22 22:55:05 +0900378 };
379 for (const auto& c : iptables_commands) {
380 Verify_iptables(runner, c.first, c.second);
381 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900382
383 Datapath datapath(&runner, &firewall);
384 datapath.Stop();
385}
386
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900387TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900388 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900389 MockFirewall firewall;
390 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900391 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900392 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900393 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900394 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900395 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900396 std::vector<ioctl_req_t> expected = {
397 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
398 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900399 EXPECT_EQ(ioctl_reqs, expected);
400 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900401 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900402}
403
404TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900405 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900406 MockFirewall firewall;
407 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900408 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900409 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900410 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900411 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900412 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900413 std::vector<ioctl_req_t> expected = {
414 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
415 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900416 EXPECT_EQ(ioctl_reqs, expected);
417 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900418 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900419}
420
Garrick Evans621ed262019-11-13 12:28:43 +0900421TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900422 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900423 MockFirewall firewall;
424 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900425 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900426 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900427 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
428 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900429 EXPECT_EQ(ioctl_reqs, expected);
430 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900431 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900432}
433
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900434TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900435 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900436 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900437 Verify_ip(runner, "tuntap del foo0 mode tap");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900438 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900439 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900440}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900441
Hugo Benichi33860d72020-07-09 16:34:01 +0900442TEST(DatapathTest, NetnsAttachName) {
443 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900444 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900445 Verify_ip_netns_delete(runner, "netns_foo");
446 Verify_ip_netns_attach(runner, "netns_foo", 1234);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900447 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900448 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
449}
450
451TEST(DatapathTest, NetnsDeleteName) {
452 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900453 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900454 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900455 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900456 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
457}
458
Garrick Evans8a949dc2019-07-18 16:17:53 +0900459TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900460 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900461 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900462 Verify_ip(runner, "addr add 1.1.1.1/30 brd 1.1.1.3 dev br");
463 Verify_ip(runner, "link set br up");
Hugo Benichi860ef532021-01-25 17:19:36 +0900464 Verify_iptables(runner, IPv4,
465 "mangle -A PREROUTING -i br -j MARK --set-mark 1/1 -w");
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900466
467 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900468 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Hugo Benichiaba7e2e2021-02-22 14:47:11 +0900469
470 EXPECT_EQ(1, ioctl_reqs.size());
471 EXPECT_EQ(SIOCBRADDBR, ioctl_reqs[0]);
472 EXPECT_EQ("br", ioctl_ifreq_args[0].first);
473 ioctl_reqs.clear();
474 ioctl_ifreq_args.clear();
475}
476
477TEST(DatapathTest, RemoveBridge) {
478 MockProcessRunner runner;
479 MockFirewall firewall;
480 Verify_iptables(runner, IPv4,
481 "mangle -D PREROUTING -i br -j MARK --set-mark 1/1 -w");
482 Verify_ip(runner, "link set br down");
483
484 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
485 datapath.RemoveBridge("br");
486
487 EXPECT_EQ(1, ioctl_reqs.size());
488 EXPECT_EQ(SIOCBRDELBR, ioctl_reqs[0]);
489 EXPECT_EQ("br", ioctl_ifreq_args[0].first);
490 ioctl_reqs.clear();
491 ioctl_ifreq_args.clear();
492}
493
494TEST(DatapathTest, AddToBridge) {
495 MockProcessRunner runner;
496 MockFirewall firewall;
497
498 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_ifreq_cap);
499 datapath.SetIfnameIndex("vethwlan0", 5);
500 datapath.AddToBridge("arcbr0", "vethwlan0");
501
502 EXPECT_EQ(1, ioctl_reqs.size());
503 EXPECT_EQ(SIOCBRADDIF, ioctl_reqs[0]);
504 EXPECT_EQ("arcbr0", ioctl_ifreq_args[0].first);
505 EXPECT_EQ(5, ioctl_ifreq_args[0].second.ifr_ifindex);
506
507 ioctl_reqs.clear();
508 ioctl_ifreq_args.clear();
Garrick Evans8a949dc2019-07-18 16:17:53 +0900509}
510
Hugo Benichi76675592020-04-08 14:29:57 +0900511TEST(DatapathTest, ConnectVethPair) {
512 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900513 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900514 Verify_ip(runner,
515 "link add veth_foo type veth peer name peer_foo netns netns_foo");
516 Verify_ip(runner,
517 "addr add 100.115.92.169/30 brd 100.115.92.171 dev peer_foo");
518 Verify_ip(runner,
519 "link set dev peer_foo up addr 01:02:03:04:05:06 multicast on");
520 Verify_ip(runner, "link set veth_foo up");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900521 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900522 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
523 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900524 Ipv4Addr(100, 115, 92, 169), 30, true));
525}
526
Garrick Evans2470caa2020-03-04 14:15:41 +0900527TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900528 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900529 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900530 Verify_ip(runner,
531 "link add veth_foo type veth peer name peer_foo netns netns_foo");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900532 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900533 EXPECT_TRUE(
534 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900535}
536
537TEST(DatapathTest, ToggleInterface) {
538 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900539 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900540 Verify_ip(runner, "link set foo up");
541 Verify_ip(runner, "link set bar down");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900542 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900543 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
544 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
545}
546
547TEST(DatapathTest, ConfigureInterface) {
548 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900549 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900550 Verify_ip(runner, "addr add 1.1.1.1/30 brd 1.1.1.3 dev foo");
551 Verify_ip(runner, "link set dev foo up addr 02:02:02:02:02:02 multicast on");
Garrick Evans2470caa2020-03-04 14:15:41 +0900552
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900553 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900554 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
555 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
556 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900557}
558
559TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900560 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900561 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900562 Verify_ip(runner, "link delete foo");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900563 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900564 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900565}
566
Hugo Benichi321f23b2020-09-25 15:42:05 +0900567TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
568 MockProcessRunner runner;
569 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900570 Verify_iptables(
571 runner, IPv4,
572 "filter -I drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/24 -j DROP -w");
573 Verify_iptables(
574 runner, IPv4,
575 "filter -D drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/24 -j DROP -w");
Hugo Benichi321f23b2020-09-25 15:42:05 +0900576 Datapath datapath(&runner, &firewall);
577 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
578 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
579}
580
Hugo Benichi7c342672020-09-08 09:18:14 +0900581TEST(DatapathTest, StartRoutingNamespace) {
582 MockProcessRunner runner;
583 MockFirewall firewall;
584 MacAddress mac = {1, 2, 3, 4, 5, 6};
585
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900586 Verify_ip_netns_delete(runner, "netns_foo");
587 Verify_ip_netns_attach(runner, "netns_foo", kTestPID);
588 Verify_ip(runner,
589 "link add arc_ns0 type veth peer name veth0 netns netns_foo");
590 Verify_ip(runner, "addr add 100.115.92.130/30 brd 100.115.92.131 dev veth0");
591 Verify_ip(runner,
592 "link set dev veth0 up addr 01:02:03:04:05:06 multicast off");
593 Verify_ip(runner, "link set arc_ns0 up");
594 Verify_ip(runner,
595 "addr add 100.115.92.129/30 brd 100.115.92.131 dev arc_ns0");
596 Verify_ip(runner,
597 "link set dev arc_ns0 up addr 01:02:03:04:05:06 multicast off");
Hugo Benichi860ef532021-01-25 17:19:36 +0900598 Verify_iptables(runner, IPv4, "filter -A FORWARD -o arc_ns0 -j ACCEPT -w");
599 Verify_iptables(runner, IPv4, "filter -A FORWARD -i arc_ns0 -j ACCEPT -w");
600 Verify_iptables(runner, IPv4,
601 "mangle -A PREROUTING -i arc_ns0 -j MARK --set-mark 1/1 -w");
602 Verify_iptables(runner, Dual,
603 "mangle -A PREROUTING -i arc_ns0 -j MARK --set-mark "
604 "0x00000200/0x00003f00 -w");
605 Verify_iptables(runner, Dual,
606 "mangle -A PREROUTING -i arc_ns0 -j CONNMARK "
607 "--restore-mark --mask 0xffff0000 -w");
608 Verify_iptables(runner, Dual,
609 "mangle -A PREROUTING -i 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");
634 Verify_iptables(runner, IPv4,
635 "mangle -D PREROUTING -i arc_ns0 -j MARK --set-mark 1/1 -w");
636 Verify_iptables(runner, Dual,
637 "mangle -D PREROUTING -i arc_ns0 -j MARK --set-mark "
638 "0x00000200/0x00003f00 -w");
639 Verify_iptables(runner, Dual,
640 "mangle -D PREROUTING -i arc_ns0 -j CONNMARK "
641 "--restore-mark --mask 0xffff0000 -w");
642 Verify_iptables(runner, Dual,
643 "mangle -D PREROUTING -i arc_ns0 -j apply_vpn_mark -w");
Hugo Benichi1e3bab52021-01-25 22:41:58 +0900644 Verify_ip_netns_delete(runner, "netns_foo");
645 Verify_ip(runner, "link delete arc_ns0");
Hugo Benichi7c342672020-09-08 09:18:14 +0900646
Hugo Benichifcf81022020-12-04 11:01:37 +0900647 ConnectedNamespace nsinfo = {};
648 nsinfo.pid = kTestPID;
649 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900650 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900651 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900652 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900653 nsinfo.host_ifname = "arc_ns0";
654 nsinfo.peer_ifname = "veth0";
655 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
656 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900657 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900658 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900659}
660
Hugo Benichi8d622b52020-08-13 15:24:12 +0900661TEST(DatapathTest, StartRoutingDevice_Arc) {
662 MockProcessRunner runner;
663 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900664 Verify_iptables(
665 runner, IPv4,
666 "nat -A PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
667 Verify_iptables(
668 runner, IPv4,
669 "nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
670 Verify_iptables(
671 runner, IPv4,
672 "nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
673 Verify_iptables(runner, IPv4,
674 "filter -A FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
675 Verify_iptables(runner, IPv4,
676 "filter -A FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
677 Verify_iptables(runner, Dual,
678 "mangle -A PREROUTING -i arc_eth0 -j MARK --set-mark "
679 "0x00002000/0x00003f00 -w");
680 Verify_iptables(runner, Dual,
681 "mangle -A PREROUTING -i arc_eth0 -j MARK --set-mark "
682 "0x03ea0000/0xffff0000 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900683
684 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900685 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900686 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900687 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900688}
689
690TEST(DatapathTest, StartRoutingDevice_CrosVM) {
691 MockProcessRunner runner;
692 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900693 Verify_iptables(runner, IPv4, "filter -A FORWARD -o vmtap0 -j ACCEPT -w");
694 Verify_iptables(runner, IPv4, "filter -A FORWARD -i vmtap0 -j ACCEPT -w");
695 Verify_iptables(runner, Dual,
696 "mangle -A PREROUTING -i vmtap0 -j MARK --set-mark "
697 "0x00002100/0x00003f00 -w");
698 Verify_iptables(runner, Dual,
699 "mangle -A PREROUTING -i vmtap0 -j CONNMARK "
700 "--restore-mark --mask 0xffff0000 -w");
701 Verify_iptables(runner, Dual,
702 "mangle -A PREROUTING -i vmtap0 -j apply_vpn_mark -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900703
704 Datapath datapath(&runner, &firewall);
705 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900706 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900707}
708
709TEST(DatapathTest, StopRoutingDevice_Arc) {
710 MockProcessRunner runner;
711 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900712 Verify_iptables(
713 runner, IPv4,
714 "nat -D PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
715 Verify_iptables(
716 runner, IPv4,
717 "nat -D PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
718 Verify_iptables(
719 runner, IPv4,
720 "nat -D PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
721 Verify_iptables(runner, IPv4,
722 "filter -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
723 Verify_iptables(runner, IPv4,
724 "filter -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
725 Verify_iptables(runner, Dual,
726 "mangle -D PREROUTING -i arc_eth0 -j MARK --set-mark "
727 "0x00002000/0x00003f00 -w");
728 Verify_iptables(runner, Dual,
729 "mangle -D PREROUTING -i arc_eth0 -j MARK --set-mark "
730 "0x03ea0000/0xffff0000 -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900731
732 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900733 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900734 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900735 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900736}
737
738TEST(DatapathTest, StopRoutingDevice_CrosVM) {
739 MockProcessRunner runner;
740 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900741 Verify_iptables(runner, IPv4, "filter -D FORWARD -o vmtap0 -j ACCEPT -w");
742 Verify_iptables(runner, IPv4, "filter -D FORWARD -i vmtap0 -j ACCEPT -w");
743 Verify_iptables(runner, Dual,
744 "mangle -D PREROUTING -i vmtap0 -j MARK --set-mark "
745 "0x00002100/0x00003f00 -w");
746 Verify_iptables(runner, Dual,
747 "mangle -D PREROUTING -i vmtap0 -j CONNMARK "
748 "--restore-mark --mask 0xffff0000 -w");
749 Verify_iptables(runner, Dual,
750 "mangle -D PREROUTING -i vmtap0 -j apply_vpn_mark -w");
Hugo Benichi8d622b52020-08-13 15:24:12 +0900751
752 Datapath datapath(&runner, &firewall);
753 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900754 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900755}
756
Hugo Benichid82d8832020-08-14 10:05:03 +0900757TEST(DatapathTest, StartStopIpForwarding) {
758 struct {
759 IpFamily family;
760 std::string iif;
761 std::string oif;
Hugo Benichi860ef532021-01-25 17:19:36 +0900762 std::string start_args;
763 std::string stop_args;
Hugo Benichid82d8832020-08-14 10:05:03 +0900764 bool result;
765 } testcases[] = {
Hugo Benichi860ef532021-01-25 17:19:36 +0900766 {IPv4, "", "", {}, {}, false},
767 {NONE, "foo", "bar", {}, {}, false},
768 {IPv4, "foo", "bar", "filter -A FORWARD -i foo -o bar -j ACCEPT -w",
769 "filter -D FORWARD -i foo -o bar -j ACCEPT -w", true},
770 {IPv4, "", "bar", "filter -A FORWARD -o bar -j ACCEPT -w",
771 "filter -D FORWARD -o bar -j ACCEPT -w", true},
772 {IPv4, "foo", "", "filter -A FORWARD -i foo -j ACCEPT -w",
773 "filter -D FORWARD -i foo -j ACCEPT -w", true},
774 {IPv6, "foo", "bar", "filter -A FORWARD -i foo -o bar -j ACCEPT -w",
775 "filter -D FORWARD -i foo -o bar -j ACCEPT -w", true},
776 {IPv6, "", "bar", "filter -A FORWARD -o bar -j ACCEPT -w",
777 "filter -D FORWARD -o bar -j ACCEPT -w", true},
778 {IPv6, "foo", "", "filter -A FORWARD -i foo -j ACCEPT -w",
779 "filter -D FORWARD -i foo -j ACCEPT -w", true},
780 {Dual, "foo", "bar", "filter -A FORWARD -i foo -o bar -j ACCEPT -w",
781 "filter -D FORWARD -i foo -o bar -j ACCEPT -w", true},
782 {Dual, "", "bar", "filter -A FORWARD -o bar -j ACCEPT -w",
783 "filter -D FORWARD -o bar -j ACCEPT -w", true},
784 {Dual, "foo", "", "filter -A FORWARD -i foo -j ACCEPT -w",
785 "filter -D FORWARD -i foo -j ACCEPT -w", true},
Hugo Benichid82d8832020-08-14 10:05:03 +0900786 };
787
788 for (const auto& tt : testcases) {
789 MockProcessRunner runner;
790 MockFirewall firewall;
791 if (tt.result) {
Hugo Benichi860ef532021-01-25 17:19:36 +0900792 Verify_iptables(runner, tt.family, tt.start_args);
793 Verify_iptables(runner, tt.family, tt.stop_args);
Hugo Benichid82d8832020-08-14 10:05:03 +0900794 }
795 Datapath datapath(&runner, &firewall);
796
797 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
798 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
799 }
800}
801
Hugo Benichi76be34a2020-08-26 22:35:54 +0900802TEST(DatapathTest, StartStopConnectionPinning) {
803 MockProcessRunner runner;
804 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +0900805
806 // Setup
Hugo Benichi860ef532021-01-25 17:19:36 +0900807 Verify_iptables(runner, Dual,
808 "mangle -A check_routing_mark -o eth0 -m mark ! "
809 "--mark 0x03eb0000/0xffff0000 -j DROP -w");
810 Verify_iptables(runner, Dual,
811 "mangle -A POSTROUTING -o eth0 -j CONNMARK --set-mark "
812 "0x03eb0000/0xffff0000 -w");
813 Verify_iptables(runner, Dual,
814 "mangle -A POSTROUTING -o eth0 -j CONNMARK "
815 "--save-mark --mask 0x00003f00 -w");
816 Verify_iptables(runner, Dual,
817 "mangle -A PREROUTING -i eth0 -j CONNMARK "
818 "--restore-mark --mask 0x00003f00 -w");
Hugo Benichi155de002021-01-19 16:45:46 +0900819
Hugo Benichi1af52392020-11-27 18:09:32 +0900820 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900821 Verify_iptables(runner, Dual,
822 "mangle -D check_routing_mark -o eth0 -m mark ! "
823 "--mark 0x03eb0000/0xffff0000 -j DROP -w");
824 Verify_iptables(runner, Dual,
825 "mangle -D POSTROUTING -o eth0 -j CONNMARK --set-mark "
826 "0x03eb0000/0xffff0000 -w");
827 Verify_iptables(runner, Dual,
828 "mangle -D POSTROUTING -o eth0 -j CONNMARK "
829 "--save-mark --mask 0x00003f00 -w");
830 Verify_iptables(runner, Dual,
831 "mangle -D PREROUTING -i eth0 -j CONNMARK "
832 "--restore-mark --mask 0x00003f00 -w");
Hugo Benichi1af52392020-11-27 18:09:32 +0900833
Hugo Benichi76be34a2020-08-26 22:35:54 +0900834 Datapath datapath(&runner, &firewall);
835 datapath.SetIfnameIndex("eth0", 3);
836 datapath.StartConnectionPinning("eth0");
837 datapath.StopConnectionPinning("eth0");
838}
839
Hugo Benichibfc49112020-12-14 12:54:44 +0900840TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +0900841 MockProcessRunner runner;
842 MockFirewall firewall;
843
844 // Setup
Hugo Benichi860ef532021-01-25 17:19:36 +0900845 Verify_iptables(runner, Dual,
846 "mangle -A check_routing_mark -o arcbr0 -m mark ! "
847 "--mark 0x03ed0000/0xffff0000 -j DROP -w");
848 Verify_iptables(runner, Dual,
849 "mangle -A POSTROUTING -o arcbr0 -j CONNMARK "
850 "--set-mark 0x03ed0000/0xffff0000 -w");
851 Verify_iptables(
852 runner, Dual,
853 "mangle -A apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
854 Verify_iptables(runner, Dual,
855 "mangle -A POSTROUTING -o arcbr0 -j CONNMARK "
856 "--save-mark --mask 0x00003f00 -w");
857 Verify_iptables(runner, Dual,
858 "mangle -A PREROUTING -i arcbr0 -j CONNMARK "
859 "--restore-mark --mask 0x00003f00 -w");
860 Verify_iptables(runner, IPv4,
861 "nat -A POSTROUTING -o arcbr0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900862 Verify_iptables(runner, IPv4,
863 "nat -A OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
864 "redirect_dns -w");
Hugo Benichi860ef532021-01-25 17:19:36 +0900865
Hugo Benichi2a940542020-10-26 18:50:49 +0900866 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900867 Verify_iptables(runner, Dual,
868 "mangle -D check_routing_mark -o arcbr0 -m mark ! "
869 "--mark 0x03ed0000/0xffff0000 -j DROP -w");
870 Verify_iptables(runner, Dual,
871 "mangle -D POSTROUTING -o arcbr0 -j CONNMARK "
872 "--set-mark 0x03ed0000/0xffff0000 -w");
873 Verify_iptables(
874 runner, Dual,
875 "mangle -D apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
876 Verify_iptables(runner, Dual,
877 "mangle -D POSTROUTING -o arcbr0 -j CONNMARK "
878 "--save-mark --mask 0x00003f00 -w");
879 Verify_iptables(runner, Dual,
880 "mangle -D PREROUTING -i arcbr0 -j CONNMARK "
881 "--restore-mark --mask 0x00003f00 -w");
882 Verify_iptables(runner, IPv4,
883 "nat -D POSTROUTING -o arcbr0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900884 Verify_iptables(runner, IPv4,
885 "nat -D OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
886 "redirect_dns -w");
Hugo Benichi2a940542020-10-26 18:50:49 +0900887
888 Datapath datapath(&runner, &firewall);
889 datapath.SetIfnameIndex("arcbr0", 5);
890 datapath.StartVpnRouting("arcbr0");
891 datapath.StopVpnRouting("arcbr0");
892}
893
Hugo Benichibfc49112020-12-14 12:54:44 +0900894TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
895 MockProcessRunner runner;
896 MockFirewall firewall;
897
898 // Setup
Hugo Benichi860ef532021-01-25 17:19:36 +0900899 Verify_iptables(runner, Dual,
900 "mangle -A check_routing_mark -o tun0 -m mark ! "
901 "--mark 0x03ed0000/0xffff0000 -j DROP -w");
902 Verify_iptables(runner, Dual,
903 "mangle -A POSTROUTING -o tun0 -j CONNMARK --set-mark "
904 "0x03ed0000/0xffff0000 -w");
905 Verify_iptables(
906 runner, Dual,
907 "mangle -A apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
908 Verify_iptables(runner, Dual,
909 "mangle -A POSTROUTING -o tun0 -j CONNMARK "
910 "--save-mark --mask 0x00003f00 -w");
911 Verify_iptables(runner, Dual,
912 "mangle -A PREROUTING -i tun0 -j CONNMARK "
913 "--restore-mark --mask 0x00003f00 -w");
914 Verify_iptables(runner, IPv4, "nat -A POSTROUTING -o tun0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900915 Verify_iptables(runner, IPv4,
916 "nat -A OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
917 "redirect_dns -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900918 // Teardown
Hugo Benichi860ef532021-01-25 17:19:36 +0900919 Verify_iptables(runner, Dual,
920 "mangle -D check_routing_mark -o tun0 -m mark ! "
921 "--mark 0x03ed0000/0xffff0000 -j DROP -w");
922 Verify_iptables(runner, Dual,
923 "mangle -D POSTROUTING -o tun0 -j CONNMARK --set-mark "
924 "0x03ed0000/0xffff0000 -w");
925 Verify_iptables(
926 runner, Dual,
927 "mangle -D apply_vpn_mark -j MARK --set-mark 0x03ed0000/0xffff0000 -w");
928 Verify_iptables(runner, Dual,
929 "mangle -D POSTROUTING -o tun0 -j CONNMARK "
930 "--save-mark --mask 0x00003f00 -w");
931 Verify_iptables(runner, Dual,
932 "mangle -D PREROUTING -i tun0 -j CONNMARK "
933 "--restore-mark --mask 0x00003f00 -w");
934 Verify_iptables(runner, IPv4, "nat -D POSTROUTING -o tun0 -j MASQUERADE -w");
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900935 Verify_iptables(runner, IPv4,
936 "nat -D OUTPUT -m mark ! --mark 0x00008000/0x0000c000 -j "
937 "redirect_dns -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900938 // Start tun0 <-> arcbr0 routing
Hugo Benichi860ef532021-01-25 17:19:36 +0900939 Verify_iptables(runner, IPv4,
940 "filter -A FORWARD -i tun0 -o arcbr0 -j ACCEPT -w");
941 Verify_iptables(runner, IPv4,
942 "filter -A FORWARD -i arcbr0 -o tun0 -j ACCEPT -w");
943 Verify_iptables(runner, Dual,
944 "mangle -A PREROUTING -i arcbr0 -j MARK --set-mark "
945 "0x00002000/0x00003f00 -w");
946 Verify_iptables(runner, Dual,
947 "mangle -A PREROUTING -i arcbr0 -j MARK --set-mark "
948 "0x03ed0000/0xffff0000 -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900949 // Stop tun0 <-> arcbr0 routing
Hugo Benichi860ef532021-01-25 17:19:36 +0900950 Verify_iptables(runner, IPv4,
951 "filter -D FORWARD -i tun0 -o arcbr0 -j ACCEPT -w");
952 Verify_iptables(runner, IPv4,
953 "filter -D FORWARD -i arcbr0 -o tun0 -j ACCEPT -w");
954 Verify_iptables(runner, Dual,
955 "mangle -D PREROUTING -i arcbr0 -j MARK --set-mark "
956 "0x00002000/0x00003f00 -w");
957 Verify_iptables(runner, Dual,
958 "mangle -D PREROUTING -i arcbr0 -j MARK --set-mark "
959 "0x03ed0000/0xffff0000 -w");
Hugo Benichibfc49112020-12-14 12:54:44 +0900960
961 Datapath datapath(&runner, &firewall);
962 datapath.SetIfnameIndex("tun0", 5);
963 datapath.StartVpnRouting("tun0");
964 datapath.StopVpnRouting("tun0");
965}
966
Garrick Evansf0ab7132019-06-18 14:50:42 +0900967TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900968 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900969 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900970 Verify_iptables(
971 runner, IPv4,
972 "nat -A PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
973 Verify_iptables(
974 runner, IPv4,
975 "nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
976 Verify_iptables(
977 runner, IPv4,
978 "nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
979
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900980 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900981 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900982}
983
984TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900985 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900986 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +0900987 Verify_iptables(
988 runner, IPv4,
989 "nat -D PREROUTING -i eth0 -m socket --nowildcard -j ACCEPT -w");
990 Verify_iptables(
991 runner, IPv4,
992 "nat -D PREROUTING -i eth0 -p tcp -j DNAT --to-destination 1.2.3.4 -w");
993 Verify_iptables(
994 runner, IPv4,
995 "nat -D PREROUTING -i eth0 -p udp -j DNAT --to-destination 1.2.3.4 -w");
996
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900997 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900998 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900999}
1000
Garrick Evans664a82f2019-12-17 12:18:05 +09001001TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001002 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001003 MockFirewall firewall;
1004 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001005
Garrick Evans664a82f2019-12-17 12:18:05 +09001006 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001007 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001008 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001009 EXPECT_EQ(ioctl_reqs, expected);
1010 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001011 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001012}
1013
1014TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001015 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001016 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001017 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001018 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1019 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1020 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001021 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001022 .WillOnce(Return(1));
1023 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1024 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1025 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001026 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001027 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1028 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1029 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001030 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001031 .WillOnce(Return(1));
1032 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1033 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1034 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001035 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001036 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001037 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001038}
1039
Taoyu Lica49c832019-12-06 17:56:43 +09001040TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001041 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001042 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001043 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1044 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1045 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001046 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001047 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1048 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1049 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001050 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001051 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001052 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001053}
1054
Taoyu Li90c13912019-11-26 17:56:54 +09001055TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001056 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001057 MockFirewall firewall;
Hugo Benichi860ef532021-01-25 17:19:36 +09001058 Verify_iptables(runner, IPv6,
1059 "filter -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w");
1060 Verify_iptables(runner, IPv6,
1061 "filter -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001062 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001063 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001064}
1065
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001066TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001067 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001068 MockFirewall firewall;
Hugo Benichi1e3bab52021-01-25 22:41:58 +09001069 Verify_ip6(runner, "route replace 2001:da8:e00::1234/128 dev eth0");
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001070 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001071 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001072}
1073
Hugo Benichie8758b52020-04-03 14:49:01 +09001074TEST(DatapathTest, AddIPv4Route) {
1075 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001076 MockFirewall firewall;
1077 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001078
1079 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1080 Ipv4Addr(255, 255, 255, 0));
1081 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1082 Ipv4Addr(255, 255, 255, 0));
1083 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1084 Ipv4Addr(255, 255, 255, 252));
1085 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1086 Ipv4Addr(255, 255, 255, 252));
1087
1088 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1089 SIOCDELRT};
1090 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001091
1092 std::string route1 =
1093 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1094 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1095 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1096 "RTF_GATEWAY}";
1097 std::string route2 =
1098 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1099 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1100 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1101 std::vector<std::string> captured_routes;
1102 for (const auto& route : ioctl_rtentry_args) {
1103 std::ostringstream stream;
1104 stream << route.second;
1105 captured_routes.emplace_back(stream.str());
1106 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001107 EXPECT_EQ(route1, captured_routes[0]);
1108 EXPECT_EQ(route1, captured_routes[1]);
1109 EXPECT_EQ(route2, captured_routes[2]);
1110 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001111 ioctl_reqs.clear();
1112 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001113}
1114
Hugo Benichi1e0656f2021-02-15 15:43:38 +09001115TEST(DatapathTest, RedirectDnsRules) {
1116 MockProcessRunner runner;
1117 MockFirewall firewall;
1118
1119 Verify_iptables(runner, IPv4,
1120 "nat -I redirect_dns -p tcp --dport 53 -o eth0 -j DNAT "
1121 "--to-destination 192.168.1.1 -w");
1122 Verify_iptables(runner, IPv4,
1123 "nat -I redirect_dns -p udp --dport 53 -o eth0 -j DNAT "
1124 "--to-destination 192.168.1.1 -w");
1125 Verify_iptables(runner, IPv4,
1126 "nat -I redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1127 "--to-destination 1.1.1.1 -w");
1128 Verify_iptables(runner, IPv4,
1129 "nat -I redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1130 "--to-destination 1.1.1.1 -w");
1131 Verify_iptables(runner, IPv4,
1132 "nat -D redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1133 "--to-destination 1.1.1.1 -w");
1134 Verify_iptables(runner, IPv4,
1135 "nat -D redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1136 "--to-destination 1.1.1.1 -w");
1137 Verify_iptables(runner, IPv4,
1138 "nat -I redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1139 "--to-destination 8.8.8.8 -w");
1140 Verify_iptables(runner, IPv4,
1141 "nat -I redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1142 "--to-destination 8.8.8.8 -w");
1143 Verify_iptables(runner, IPv4,
1144 "nat -D redirect_dns -p tcp --dport 53 -o eth0 -j DNAT "
1145 "--to-destination 192.168.1.1 -w");
1146 Verify_iptables(runner, IPv4,
1147 "nat -D redirect_dns -p udp --dport 53 -o eth0 -j DNAT "
1148 "--to-destination 192.168.1.1 -w");
1149 Verify_iptables(runner, IPv4,
1150 "nat -D redirect_dns -p tcp --dport 53 -o wlan0 -j DNAT "
1151 "--to-destination 8.8.8.8 -w");
1152 Verify_iptables(runner, IPv4,
1153 "nat -D redirect_dns -p udp --dport 53 -o wlan0 -j DNAT "
1154 "--to-destination 8.8.8.8 -w");
1155
1156 Datapath datapath(&runner, &firewall);
1157 datapath.RemoveRedirectDnsRule("wlan0");
1158 datapath.RemoveRedirectDnsRule("unknown");
1159 datapath.AddRedirectDnsRule("eth0", "192.168.1.1");
1160 datapath.AddRedirectDnsRule("wlan0", "1.1.1.1");
1161 datapath.AddRedirectDnsRule("wlan0", "8.8.8.8");
1162 datapath.RemoveRedirectDnsRule("eth0");
1163 datapath.RemoveRedirectDnsRule("wlan0");
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