blob: 51e17e981188a366a0f2d04543b1180591fe24ba [file] [log] [blame]
Garrick Evansf0ab7132019-06-18 14:50:42 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/datapath.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +09006
Garrick Evansc7ae82c2019-09-04 16:25:10 +09007#include <linux/if_tun.h>
Taoyu Li90c13912019-11-26 17:56:54 +09008#include <net/if.h>
Garrick Evansc7ae82c2019-09-04 16:25:10 +09009#include <sys/ioctl.h>
10
Garrick Evansf0ab7132019-06-18 14:50:42 +090011#include <utility>
12#include <vector>
13
Garrick Evansc7ae82c2019-09-04 16:25:10 +090014#include <base/bind.h>
Qijiang Fane90b8792020-03-09 16:15:41 +090015#include <base/bind_helpers.h>
Hugo Benichic72b07e2021-01-22 22:55:05 +090016#include <base/strings/string_split.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090017#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090018#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090019#include <gtest/gtest.h>
20
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090021#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090022#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090023
Garrick Evans8e8e3472020-01-23 14:03:50 +090024using testing::_;
25using testing::ElementsAre;
Hugo Benichic72b07e2021-01-22 22:55:05 +090026using testing::ElementsAreArray;
Garrick Evans8e8e3472020-01-23 14:03:50 +090027using testing::Return;
28using testing::StrEq;
29
Garrick Evans3388a032020-03-24 11:25:55 +090030namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090031namespace {
32
Hugo Benichi76675592020-04-08 14:29:57 +090033// TODO(hugobenichi) Centralize this constant definition
34constexpr pid_t kTestPID = -2;
35
Hugo Benichie8758b52020-04-03 14:49:01 +090036std::vector<ioctl_req_t> ioctl_reqs;
37std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090038
39// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090040int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090041 ioctl_reqs.push_back(req);
42 return 0;
43}
44
45// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
46int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
47 ioctl_reqs.push_back(req);
48 ioctl_rtentry_args.push_back({"", *arg});
49 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
50 // this value to ioctl() on the stack.
51 if (arg->rt_dev) {
52 auto& cap = ioctl_rtentry_args.back();
53 cap.first = std::string(arg->rt_dev);
54 cap.second.rt_dev = (char*)cap.first.c_str();
55 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090056 return 0;
57}
58
59} // namespace
60
Hugo Benichic72b07e2021-01-22 22:55:05 +090061using IpFamily::Dual;
62using IpFamily::IPv4;
63using IpFamily::IPv6;
64
Garrick Evans8e8e3472020-01-23 14:03:50 +090065class MockProcessRunner : public MinijailedProcessRunner {
66 public:
67 MockProcessRunner() = default;
68 ~MockProcessRunner() = default;
69
Garrick Evans2470caa2020-03-04 14:15:41 +090070 MOCK_METHOD1(WriteSentinelToContainer, int(pid_t pid));
Garrick Evans8e8e3472020-01-23 14:03:50 +090071 MOCK_METHOD3(brctl,
72 int(const std::string& cmd,
73 const std::vector<std::string>& argv,
74 bool log_failures));
75 MOCK_METHOD4(chown,
76 int(const std::string& uid,
77 const std::string& gid,
78 const std::string& file,
79 bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +090080 MOCK_METHOD4(ip,
81 int(const std::string& obj,
82 const std::string& cmd,
83 const std::vector<std::string>& args,
84 bool log_failures));
85 MOCK_METHOD4(ip6,
86 int(const std::string& obj,
87 const std::string& cmd,
88 const std::vector<std::string>& args,
89 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090090 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090091 int(const std::string& table,
92 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090093 bool log_failures,
94 std::string* output));
95 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090096 int(const std::string& table,
97 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090098 bool log_failures,
99 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900100 MOCK_METHOD2(modprobe_all,
101 int(const std::vector<std::string>& modules, bool log_failures));
102 MOCK_METHOD3(sysctl_w,
103 int(const std::string& key,
104 const std::string& value,
105 bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900106 MOCK_METHOD3(ip_netns_attach,
107 int(const std::string& netns_name,
108 pid_t netns_pid,
109 bool log_failures));
110 MOCK_METHOD2(ip_netns_delete,
111 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900112};
113
Hugo Benichic72b07e2021-01-22 22:55:05 +0900114void Verify_iptables(MockProcessRunner& runner,
115 IpFamily family,
116 const std::string& command) {
117 auto args =
118 base::SplitString(command, " ", base::WhitespaceHandling::TRIM_WHITESPACE,
119 base::SplitResult::SPLIT_WANT_NONEMPTY);
120 const auto table = args[0];
121 args.erase(args.begin());
122 if (family & IPv4)
123 EXPECT_CALL(runner,
124 iptables(StrEq(table), ElementsAreArray(args), _, nullptr));
125 if (family & IPv6)
126 EXPECT_CALL(runner,
127 ip6tables(StrEq(table), ElementsAreArray(args), _, nullptr));
128}
129
Hugo Benichid82d8832020-08-14 10:05:03 +0900130TEST(DatapathTest, IpFamily) {
Hugo Benichic72b07e2021-01-22 22:55:05 +0900131 EXPECT_EQ(Dual, IPv4 | IPv6);
132 EXPECT_EQ(Dual & IPv4, IPv4);
133 EXPECT_EQ(Dual & IPv6, IPv6);
134 EXPECT_NE(Dual, IPv4);
135 EXPECT_NE(Dual, IPv6);
136 EXPECT_NE(IPv4, IPv6);
Hugo Benichid82d8832020-08-14 10:05:03 +0900137}
138
Hugo Benichibf811c62020-09-07 17:30:45 +0900139TEST(DatapathTest, Start) {
140 MockProcessRunner runner;
141 MockFirewall firewall;
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900142
Hugo Benichibf811c62020-09-07 17:30:45 +0900143 // Asserts for sysctl modifications
144 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("1"), true));
145 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
146 StrEq("32768 47103"), true));
147 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
148 StrEq("1"), true));
Hugo Benichic72b07e2021-01-22 22:55:05 +0900149
150 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
151 // Asserts for iptables chain reset.
152 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
153 {Dual, "filter -F FORWARD -w"},
154 {Dual, "mangle -F FORWARD -w"},
155 {Dual, "mangle -F INPUT -w"},
156 {Dual, "mangle -F OUTPUT -w"},
157 {Dual, "mangle -F POSTROUTING -w"},
158 {Dual, "mangle -F PREROUTING -w"},
159 {Dual, "mangle -L apply_local_source_mark -w"},
160 {Dual, "mangle -F apply_local_source_mark -w"},
161 {Dual, "mangle -X apply_local_source_mark -w"},
162 {Dual, "mangle -L apply_vpn_mark -w"},
163 {Dual, "mangle -F apply_vpn_mark -w"},
164 {Dual, "mangle -X apply_vpn_mark -w"},
165 {Dual, "mangle -L check_routing_mark -w"},
166 {Dual, "mangle -F check_routing_mark -w"},
167 {Dual, "mangle -X check_routing_mark -w"},
168 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
169 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
170 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
171 {IPv4, "nat -F POSTROUTING -w"},
172 // Asserts for SNAT rules.
173 {IPv4,
174 "filter -A FORWARD -m mark --mark 1/1 -m state --state INVALID -j DROP "
175 "-w"},
176 {IPv4, "nat -A POSTROUTING -m mark --mark 1/1 -j MASQUERADE -w"},
177 // Asserts for AddForwardEstablishedRule
178 {IPv4,
179 "filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT -w"},
180 // Asserts for AddSourceIPv4DropRule() calls.
181 {IPv4, "filter -N drop_guest_ipv4_prefix -w"},
182 {IPv4, "filter -I OUTPUT -j drop_guest_ipv4_prefix -w"},
183 {IPv4,
184 "filter -I drop_guest_ipv4_prefix -o eth+ -s 100.115.92.0/23 -j DROP "
185 "-w"},
186 {IPv4,
187 "filter -I drop_guest_ipv4_prefix -o wlan+ -s 100.115.92.0/23 -j DROP "
188 "-w"},
189 {IPv4,
190 "filter -I drop_guest_ipv4_prefix -o mlan+ -s 100.115.92.0/23 -j DROP "
191 "-w"},
192 {IPv4,
193 "filter -I drop_guest_ipv4_prefix -o usb+ -s 100.115.92.0/23 -j DROP "
194 "-w"},
195 {IPv4,
196 "filter -I drop_guest_ipv4_prefix -o wwan+ -s 100.115.92.0/23 -j DROP "
197 "-w"},
198 {IPv4,
199 "filter -I drop_guest_ipv4_prefix -o rmnet+ -s 100.115.92.0/23 -j DROP "
200 "-w"},
201 // Asserts for AddOutboundIPv4SNATMark("vmtap+")
202 {IPv4, "mangle -A PREROUTING -i vmtap+ -j MARK --set-mark 1/1 -w"},
203 // Asserts for OUTPUT ndp connmark bypass rule
204 {IPv6,
205 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT "
206 "-w"},
207 {IPv6,
208 "mangle -I OUTPUT -p icmpv6 --icmpv6-type router-advertisement -j "
209 "ACCEPT -w"},
210 {IPv6,
211 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j "
212 "ACCEPT -w"},
213 {IPv6,
214 "mangle -I OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j "
215 "ACCEPT -w"},
216 {IPv6,
217 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
218 "router-solicitation -j RETURN -w"},
219 {IPv6,
220 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
221 "router-advertisement -j RETURN -w"},
222 {IPv6,
223 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
224 "neighbour-solicitation -j RETURN -w"},
225 {IPv6,
226 "mangle -I check_routing_mark -p icmpv6 --icmpv6-type "
227 "neighbour-advertisement -j RETURN -w"},
228 // Asserts for OUTPUT CONNMARK restore rule
229 {Dual,
230 "mangle -A OUTPUT -j CONNMARK --restore-mark --mask 0xffff0000 -w"},
231 // Asserts for apply_local_source_mark chain
232 {Dual, "mangle -N apply_local_source_mark -w"},
233 {Dual, "mangle -A OUTPUT -j apply_local_source_mark -w"},
234 {Dual,
235 "mangle -A apply_local_source_mark -m owner --uid-owner chronos -j MARK "
236 "--set-mark 0x00008100/0x0000ff00 -w"},
237 {Dual,
238 "mangle -A apply_local_source_mark -m owner --uid-owner debugd -j MARK "
239 "--set-mark 0x00008200/0x0000ff00 -w"},
240 {Dual,
241 "mangle -A apply_local_source_mark -m owner --uid-owner cups -j MARK "
242 "--set-mark 0x00008200/0x0000ff00 -w"},
243 {Dual,
244 "mangle -A apply_local_source_mark -m owner --uid-owner lpadmin -j MARK "
245 "--set-mark 0x00008200/0x0000ff00 -w"},
246 {Dual,
247 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd -j "
248 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
249 {Dual,
250 "mangle -A apply_local_source_mark -m owner --uid-owner kerberosd-exec "
251 "-j MARK --set-mark 0x00008400/0x0000ff00 -w"},
252 {Dual,
253 "mangle -A apply_local_source_mark -m owner --uid-owner tlsdate -j MARK "
254 "--set-mark 0x00008400/0x0000ff00 -w"},
255 {Dual,
256 "mangle -A apply_local_source_mark -m owner --uid-owner pluginvm -j "
257 "MARK --set-mark 0x00008200/0x0000ff00 -w"},
258 {Dual,
259 "mangle -A apply_local_source_mark -m owner --uid-owner fuse-smbfs -j "
260 "MARK --set-mark 0x00008400/0x0000ff00 -w"},
261 {Dual,
262 "mangle -A apply_local_source_mark -m cgroup --cgroup 0x00010001 -j "
263 "MARK --set-mark 0x00000300/0x0000ff00 -w"},
264 {Dual,
265 "mangle -A apply_local_source_mark -m mark --mark 0x0/0x00003f00 -j "
266 "MARK --set-mark 0x00000400/0x00003f00 -w"},
267 // Asserts for apply_vpn_mark chain
268 {Dual, "mangle -N apply_vpn_mark -w"},
269 {Dual,
270 "mangle -A OUTPUT -m mark --mark 0x00008000/0x0000c000 -j "
271 "apply_vpn_mark -w"},
272 {Dual,
273 "mangle -A apply_vpn_mark -m mark ! --mark 0x0/0xffff0000 -j ACCEPT -w"},
274 // Asserts for check_routing_mark chain
275 {Dual, "mangle -N check_routing_mark -w"},
276 {Dual,
277 "mangle -A POSTROUTING -j CONNMARK --restore-mark --mask 0xffff0000 -w"},
278 {Dual,
279 "mangle -A POSTROUTING -m mark ! --mark 0x0/0xffff0000 -j "
280 "check_routing_mark -w"},
281 };
282 for (const auto& c : iptables_commands) {
283 Verify_iptables(runner, c.first, c.second);
284 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900285
286 Datapath datapath(&runner, &firewall);
287 datapath.Start();
288}
289
290TEST(DatapathTest, Stop) {
291 MockProcessRunner runner;
292 MockFirewall firewall;
293 // Asserts for sysctl modifications
294 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
295 StrEq("32768 61000"), true));
296 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
297 StrEq("0"), true));
298 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
Hugo Benichic72b07e2021-01-22 22:55:05 +0900299
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900300 // Asserts for iptables chain reset.
Hugo Benichic72b07e2021-01-22 22:55:05 +0900301 std::vector<std::pair<IpFamily, std::string>> iptables_commands = {
302 {IPv4, "filter -D OUTPUT -j drop_guest_ipv4_prefix -w"},
303 {Dual, "filter -F FORWARD -w"},
304 {Dual, "mangle -F FORWARD -w"},
305 {Dual, "mangle -F INPUT -w"},
306 {Dual, "mangle -F OUTPUT -w"},
307 {Dual, "mangle -F POSTROUTING -w"},
308 {Dual, "mangle -F PREROUTING -w"},
309 {Dual, "mangle -L apply_local_source_mark -w"},
310 {Dual, "mangle -F apply_local_source_mark -w"},
311 {Dual, "mangle -X apply_local_source_mark -w"},
312 {Dual, "mangle -L apply_vpn_mark -w"},
313 {Dual, "mangle -F apply_vpn_mark -w"},
314 {Dual, "mangle -X apply_vpn_mark -w"},
315 {Dual, "mangle -L check_routing_mark -w"},
316 {Dual, "mangle -F check_routing_mark -w"},
317 {Dual, "mangle -X check_routing_mark -w"},
318 {IPv4, "filter -L drop_guest_ipv4_prefix -w"},
319 {IPv4, "filter -F drop_guest_ipv4_prefix -w"},
320 {IPv4, "filter -X drop_guest_ipv4_prefix -w"},
321 {IPv4, "nat -F POSTROUTING -w"},
322 };
323 for (const auto& c : iptables_commands) {
324 Verify_iptables(runner, c.first, c.second);
325 }
Hugo Benichibf811c62020-09-07 17:30:45 +0900326
327 Datapath datapath(&runner, &firewall);
328 datapath.Stop();
329}
330
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900331TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900332 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900333 MockFirewall firewall;
334 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900335 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900336 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900337 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900338 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900339 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900340 std::vector<ioctl_req_t> expected = {
341 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
342 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900343 EXPECT_EQ(ioctl_reqs, expected);
344 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900345 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900346}
347
348TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900349 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900350 MockFirewall firewall;
351 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900352 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900353 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900354 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900355 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900356 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900357 std::vector<ioctl_req_t> expected = {
358 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
359 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900360 EXPECT_EQ(ioctl_reqs, expected);
361 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900362 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900363}
364
Garrick Evans621ed262019-11-13 12:28:43 +0900365TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900366 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900367 MockFirewall firewall;
368 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900369 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900370 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900371 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
372 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900373 EXPECT_EQ(ioctl_reqs, expected);
374 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900375 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900376}
377
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900378TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900379 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900380 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900381 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
382 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900383 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900384 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900385}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900386
Hugo Benichi33860d72020-07-09 16:34:01 +0900387TEST(DatapathTest, NetnsAttachName) {
388 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900389 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900390 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
391 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900392 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900393 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
394}
395
396TEST(DatapathTest, NetnsDeleteName) {
397 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900398 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900399 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900400 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900401 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
402}
403
Garrick Evans8a949dc2019-07-18 16:17:53 +0900404TEST(DatapathTest, AddBridge) {
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);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900408 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900409 EXPECT_CALL(
410 runner,
411 ip(StrEq("addr"), StrEq("add"),
412 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900413 EXPECT_CALL(runner,
414 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900415 EXPECT_CALL(runner, iptables(StrEq("mangle"),
416 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900417 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900418 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900419 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900420}
421
Hugo Benichi76675592020-04-08 14:29:57 +0900422TEST(DatapathTest, ConnectVethPair) {
423 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900424 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900425 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
426 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900427 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900428 true));
429 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
430 ElementsAre("100.115.92.169/30", "brd",
431 "100.115.92.171", "dev", "peer_foo"),
432 true))
433 .WillOnce(Return(0));
434 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
435 ElementsAre("dev", "peer_foo", "up", "addr",
436 "01:02:03:04:05:06", "multicast", "on"),
437 true))
438 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900439 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
440 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900441 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900442 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
443 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900444 Ipv4Addr(100, 115, 92, 169), 30, true));
445}
446
Garrick Evans2470caa2020-03-04 14:15:41 +0900447TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900448 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900449 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900450 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
451 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900452 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900453 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900454 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900455 EXPECT_TRUE(
456 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900457}
458
459TEST(DatapathTest, ToggleInterface) {
460 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900461 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900462 EXPECT_CALL(runner,
463 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900464 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900465 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900466 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900467 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
468 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
469}
470
471TEST(DatapathTest, ConfigureInterface) {
472 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900473 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900474 EXPECT_CALL(
475 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900476 ip(StrEq("addr"), StrEq("add"),
477 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
478 .WillOnce(Return(0));
479 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
480 ElementsAre("dev", "foo", "up", "addr",
481 "02:02:02:02:02:02", "multicast", "on"),
482 true))
483 .WillOnce(Return(0));
484
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900485 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900486 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
487 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
488 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900489}
490
491TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900492 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900493 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900494 EXPECT_CALL(runner,
495 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900496 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900497 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900498}
499
Garrick Evans8a949dc2019-07-18 16:17:53 +0900500TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900501 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900502 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900503 EXPECT_CALL(runner, iptables(StrEq("mangle"),
504 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900505 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900506 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900507 EXPECT_CALL(runner,
508 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900509 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900510 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900511 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900512}
513
Hugo Benichi321f23b2020-09-25 15:42:05 +0900514TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
515 MockProcessRunner runner;
516 MockFirewall firewall;
517 EXPECT_CALL(runner,
518 iptables(StrEq("filter"),
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900519 ElementsAre("-I", "drop_guest_ipv4_prefix", "-o", "eth+",
520 "-s", "100.115.92.0/24", "-j", "DROP", "-w"),
Hugo Benichi321f23b2020-09-25 15:42:05 +0900521 true, nullptr));
522 EXPECT_CALL(runner,
523 iptables(StrEq("filter"),
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900524 ElementsAre("-D", "drop_guest_ipv4_prefix", "-o", "eth+",
525 "-s", "100.115.92.0/24", "-j", "DROP", "-w"),
Hugo Benichi321f23b2020-09-25 15:42:05 +0900526 true, nullptr));
527 Datapath datapath(&runner, &firewall);
528 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
529 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
530}
531
Hugo Benichi7c342672020-09-08 09:18:14 +0900532TEST(DatapathTest, StartRoutingNamespace) {
533 MockProcessRunner runner;
534 MockFirewall firewall;
535 MacAddress mac = {1, 2, 3, 4, 5, 6};
536
537 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
538 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
539 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
540 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
541 "veth0", "netns", "netns_foo"),
542 true));
543 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
544 ElementsAre("100.115.92.130/30", "brd",
545 "100.115.92.131", "dev", "veth0"),
546 true))
547 .WillOnce(Return(0));
548 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
549 ElementsAre("dev", "veth0", "up", "addr",
550 "01:02:03:04:05:06", "multicast", "off"),
551 true))
552 .WillOnce(Return(0));
553 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
554 ElementsAre("arc_ns0", "up"), true));
555 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
556 ElementsAre("100.115.92.129/30", "brd",
557 "100.115.92.131", "dev", "arc_ns0"),
558 true))
559 .WillOnce(Return(0));
560 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
561 ElementsAre("dev", "arc_ns0", "up", "addr",
562 "01:02:03:04:05:06", "multicast", "off"),
563 true))
564 .WillOnce(Return(0));
565 EXPECT_CALL(runner, iptables(StrEq("filter"),
566 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
567 "-j", "ACCEPT", "-w"),
568 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900569 EXPECT_CALL(runner, iptables(StrEq("filter"),
570 ElementsAre("-A", "FORWARD", "-i", "arc_ns0",
571 "-j", "ACCEPT", "-w"),
572 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900573 EXPECT_CALL(runner,
574 iptables(StrEq("mangle"),
575 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
576 "MARK", "--set-mark", "1/1", "-w"),
577 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900578 EXPECT_CALL(runner, iptables(StrEq("mangle"),
579 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
580 "-j", "MARK", "--set-mark",
581 "0x00000200/0x00003f00", "-w"),
582 true, nullptr));
583 EXPECT_CALL(runner, iptables(StrEq("mangle"),
584 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
585 "-j", "CONNMARK", "--restore-mark",
586 "--mask", "0xffff0000", "-w"),
587 true, nullptr));
588 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
589 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
590 "-j", "MARK", "--set-mark",
591 "0x00000200/0x00003f00", "-w"),
592 true, nullptr));
593 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
594 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
595 "-j", "CONNMARK", "--restore-mark",
596 "--mask", "0xffff0000", "-w"),
597 true, nullptr));
598 EXPECT_CALL(runner, iptables(StrEq("mangle"),
599 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
600 "-j", "apply_vpn_mark", "-w"),
601 true, nullptr));
602 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
603 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0",
604 "-j", "apply_vpn_mark", "-w"),
605 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900606
Hugo Benichifcf81022020-12-04 11:01:37 +0900607 ConnectedNamespace nsinfo = {};
608 nsinfo.pid = kTestPID;
609 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900610 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900611 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900612 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900613 nsinfo.host_ifname = "arc_ns0";
614 nsinfo.peer_ifname = "veth0";
615 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
616 base::DoNothing());
617 nsinfo.peer_mac_addr = mac;
Hugo Benichi7c342672020-09-08 09:18:14 +0900618 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichifcf81022020-12-04 11:01:37 +0900619 datapath.StartRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900620 ioctl_reqs.clear();
621 ioctl_rtentry_args.clear();
622}
623
624TEST(DatapathTest, StopRoutingNamespace) {
625 MockProcessRunner runner;
626 MockFirewall firewall;
627
628 EXPECT_CALL(runner, iptables(StrEq("filter"),
629 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
630 "-j", "ACCEPT", "-w"),
631 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900632 EXPECT_CALL(runner, iptables(StrEq("filter"),
633 ElementsAre("-D", "FORWARD", "-i", "arc_ns0",
634 "-j", "ACCEPT", "-w"),
635 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900636 EXPECT_CALL(runner,
637 iptables(StrEq("mangle"),
638 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
639 "MARK", "--set-mark", "1/1", "-w"),
640 true, nullptr));
Hugo Benichi93306e52020-12-04 16:08:00 +0900641 EXPECT_CALL(runner, iptables(StrEq("mangle"),
642 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
643 "-j", "MARK", "--set-mark",
644 "0x00000200/0x00003f00", "-w"),
645 true, nullptr));
646 EXPECT_CALL(runner, iptables(StrEq("mangle"),
647 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
648 "-j", "CONNMARK", "--restore-mark",
649 "--mask", "0xffff0000", "-w"),
650 true, nullptr));
651 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
652 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
653 "-j", "MARK", "--set-mark",
654 "0x00000200/0x00003f00", "-w"),
655 true, nullptr));
656 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
657 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
658 "-j", "CONNMARK", "--restore-mark",
659 "--mask", "0xffff0000", "-w"),
660 true, nullptr));
661 EXPECT_CALL(runner, iptables(StrEq("mangle"),
662 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
663 "-j", "apply_vpn_mark", "-w"),
664 true, nullptr));
665 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
666 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0",
667 "-j", "apply_vpn_mark", "-w"),
668 true, nullptr));
Hugo Benichi7c342672020-09-08 09:18:14 +0900669 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
670 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
671 false));
672
Hugo Benichifcf81022020-12-04 11:01:37 +0900673 ConnectedNamespace nsinfo = {};
674 nsinfo.pid = kTestPID;
675 nsinfo.netns_name = "netns_foo";
Hugo Benichi93306e52020-12-04 16:08:00 +0900676 nsinfo.source = TrafficSource::USER;
Hugo Benichifcf81022020-12-04 11:01:37 +0900677 nsinfo.outbound_ifname = "";
Hugo Benichi93306e52020-12-04 16:08:00 +0900678 nsinfo.route_on_vpn = true;
Hugo Benichifcf81022020-12-04 11:01:37 +0900679 nsinfo.host_ifname = "arc_ns0";
680 nsinfo.peer_ifname = "veth0";
681 nsinfo.peer_subnet = std::make_unique<Subnet>(Ipv4Addr(100, 115, 92, 128), 30,
682 base::DoNothing());
Hugo Benichi7c342672020-09-08 09:18:14 +0900683 Datapath datapath(&runner, &firewall);
Hugo Benichifcf81022020-12-04 11:01:37 +0900684 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900685}
686
Hugo Benichi8d622b52020-08-13 15:24:12 +0900687TEST(DatapathTest, StartRoutingDevice_Arc) {
688 MockProcessRunner runner;
689 MockFirewall firewall;
690 EXPECT_CALL(runner, iptables(StrEq("nat"),
691 ElementsAre("-A", "PREROUTING", "-i", "eth0",
692 "-m", "socket", "--nowildcard", "-j",
693 "ACCEPT", "-w"),
694 true, nullptr));
695 EXPECT_CALL(runner, iptables(StrEq("nat"),
696 ElementsAre("-A", "PREROUTING", "-i", "eth0",
697 "-p", "tcp", "-j", "DNAT",
698 "--to-destination", "1.2.3.4", "-w"),
699 true, nullptr));
700 EXPECT_CALL(runner, iptables(StrEq("nat"),
701 ElementsAre("-A", "PREROUTING", "-i", "eth0",
702 "-p", "udp", "-j", "DNAT",
703 "--to-destination", "1.2.3.4", "-w"),
704 true, nullptr));
705 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900706 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
707 "arc_eth0", "-j", "ACCEPT", "-w"),
708 true, nullptr));
709 EXPECT_CALL(runner, iptables(StrEq("filter"),
710 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
711 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +0900712 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900713 EXPECT_CALL(runner, iptables(StrEq("mangle"),
714 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
715 "-j", "MARK", "--set-mark",
716 "0x00002000/0x00003f00", "-w"),
717 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900718 EXPECT_CALL(runner, iptables(StrEq("mangle"),
719 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
720 "-j", "MARK", "--set-mark",
721 "0x03ea0000/0xffff0000", "-w"),
722 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900723 EXPECT_CALL(
724 runner,
725 ip6tables(StrEq("mangle"),
726 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
727 "--set-mark", "0x00002000/0x00003f00", "-w"),
728 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900729 EXPECT_CALL(
730 runner,
731 ip6tables(StrEq("mangle"),
732 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
733 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
734 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900735
736 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900737 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900738 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900739 TrafficSource::ARC, false);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900740}
741
742TEST(DatapathTest, StartRoutingDevice_CrosVM) {
743 MockProcessRunner runner;
744 MockFirewall firewall;
745 EXPECT_CALL(runner, iptables(StrEq("filter"),
746 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
747 "-j", "ACCEPT", "-w"),
748 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900749 EXPECT_CALL(runner, iptables(StrEq("filter"),
750 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
751 "-j", "ACCEPT", "-w"),
752 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900753 EXPECT_CALL(runner, iptables(StrEq("mangle"),
754 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
755 "-j", "MARK", "--set-mark",
756 "0x00002100/0x00003f00", "-w"),
757 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900758 EXPECT_CALL(runner, iptables(StrEq("mangle"),
759 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
760 "-j", "CONNMARK", "--restore-mark",
761 "--mask", "0xffff0000", "-w"),
762 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900763 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
764 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
765 "-j", "MARK", "--set-mark",
766 "0x00002100/0x00003f00", "-w"),
767 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900768 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
769 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
770 "-j", "CONNMARK", "--restore-mark",
771 "--mask", "0xffff0000", "-w"),
772 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900773 EXPECT_CALL(runner, iptables(StrEq("mangle"),
774 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
775 "-j", "apply_vpn_mark", "-w"),
776 true, nullptr));
777 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
778 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
779 "-j", "apply_vpn_mark", "-w"),
780 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900781
782 Datapath datapath(&runner, &firewall);
783 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900784 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900785}
786
787TEST(DatapathTest, StopRoutingDevice_Arc) {
788 MockProcessRunner runner;
789 MockFirewall firewall;
790 EXPECT_CALL(runner, iptables(StrEq("nat"),
791 ElementsAre("-D", "PREROUTING", "-i", "eth0",
792 "-m", "socket", "--nowildcard", "-j",
793 "ACCEPT", "-w"),
794 true, nullptr));
795 EXPECT_CALL(runner, iptables(StrEq("nat"),
796 ElementsAre("-D", "PREROUTING", "-i", "eth0",
797 "-p", "tcp", "-j", "DNAT",
798 "--to-destination", "1.2.3.4", "-w"),
799 true, nullptr));
800 EXPECT_CALL(runner, iptables(StrEq("nat"),
801 ElementsAre("-D", "PREROUTING", "-i", "eth0",
802 "-p", "udp", "-j", "DNAT",
803 "--to-destination", "1.2.3.4", "-w"),
804 true, nullptr));
805 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900806 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
807 "arc_eth0", "-j", "ACCEPT", "-w"),
808 true, nullptr));
809 EXPECT_CALL(runner, iptables(StrEq("filter"),
810 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
811 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +0900812 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900813 EXPECT_CALL(runner, iptables(StrEq("mangle"),
814 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
815 "-j", "MARK", "--set-mark",
816 "0x00002000/0x00003f00", "-w"),
817 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900818 EXPECT_CALL(runner, iptables(StrEq("mangle"),
819 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
820 "-j", "MARK", "--set-mark",
821 "0x03ea0000/0xffff0000", "-w"),
822 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900823 EXPECT_CALL(
824 runner,
825 ip6tables(StrEq("mangle"),
826 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
827 "--set-mark", "0x00002000/0x00003f00", "-w"),
828 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900829 EXPECT_CALL(
830 runner,
831 ip6tables(StrEq("mangle"),
832 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
833 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
834 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900835
836 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900837 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900838 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900839 TrafficSource::ARC, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900840}
841
842TEST(DatapathTest, StopRoutingDevice_CrosVM) {
843 MockProcessRunner runner;
844 MockFirewall firewall;
845 EXPECT_CALL(runner, iptables(StrEq("filter"),
846 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
847 "-j", "ACCEPT", "-w"),
848 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900849 EXPECT_CALL(runner, iptables(StrEq("filter"),
850 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
851 "-j", "ACCEPT", "-w"),
852 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900853 EXPECT_CALL(runner, iptables(StrEq("mangle"),
854 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
855 "-j", "MARK", "--set-mark",
856 "0x00002100/0x00003f00", "-w"),
857 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900858 EXPECT_CALL(runner, iptables(StrEq("mangle"),
859 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
860 "-j", "CONNMARK", "--restore-mark",
861 "--mask", "0xffff0000", "-w"),
862 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900863 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
864 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
865 "-j", "MARK", "--set-mark",
866 "0x00002100/0x00003f00", "-w"),
867 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900868 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
869 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
870 "-j", "CONNMARK", "--restore-mark",
871 "--mask", "0xffff0000", "-w"),
872 true, nullptr));
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900873 EXPECT_CALL(runner, iptables(StrEq("mangle"),
874 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
875 "-j", "apply_vpn_mark", "-w"),
876 true, nullptr));
877 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
878 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
879 "-j", "apply_vpn_mark", "-w"),
880 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900881
882 Datapath datapath(&runner, &firewall);
883 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
Hugo Benichi93306e52020-12-04 16:08:00 +0900884 TrafficSource::CROSVM, true);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900885}
886
Hugo Benichid82d8832020-08-14 10:05:03 +0900887TEST(DatapathTest, StartStopIpForwarding) {
888 struct {
889 IpFamily family;
890 std::string iif;
891 std::string oif;
892 std::vector<std::string> start_args;
893 std::vector<std::string> stop_args;
894 bool result;
895 } testcases[] = {
896 {IpFamily::IPv4, "", "", {}, {}, false},
897 {IpFamily::NONE, "foo", "bar", {}, {}, false},
898 {IpFamily::IPv4,
899 "foo",
900 "bar",
901 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
902 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
903 true},
904 {IpFamily::IPv4,
905 "",
906 "bar",
907 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
908 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
909 true},
910 {IpFamily::IPv4,
911 "foo",
912 "",
913 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
914 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
915 true},
916 {IpFamily::IPv6,
917 "foo",
918 "bar",
919 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
920 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
921 true},
922 {IpFamily::IPv6,
923 "",
924 "bar",
925 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
926 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
927 true},
928 {IpFamily::IPv6,
929 "foo",
930 "",
931 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
932 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
933 true},
934 {IpFamily::Dual,
935 "foo",
936 "bar",
937 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
938 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
939 true},
940 {IpFamily::Dual,
941 "",
942 "bar",
943 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
944 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
945 true},
946 {IpFamily::Dual,
947 "foo",
948 "",
949 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
950 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
951 true},
952 };
953
954 for (const auto& tt : testcases) {
955 MockProcessRunner runner;
956 MockFirewall firewall;
957 if (tt.result) {
958 if (tt.family & IpFamily::IPv4) {
959 EXPECT_CALL(runner,
960 iptables(StrEq("filter"), tt.start_args, true, nullptr))
961 .WillOnce(Return(0));
962 EXPECT_CALL(runner,
963 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
964 .WillOnce(Return(0));
965 }
966 if (tt.family & IpFamily::IPv6) {
967 EXPECT_CALL(runner,
968 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
969 .WillOnce(Return(0));
970 EXPECT_CALL(runner,
971 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
972 .WillOnce(Return(0));
973 }
974 }
975 Datapath datapath(&runner, &firewall);
976
977 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
978 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
979 }
980}
981
Hugo Benichi76be34a2020-08-26 22:35:54 +0900982TEST(DatapathTest, StartStopConnectionPinning) {
983 MockProcessRunner runner;
984 MockFirewall firewall;
Hugo Benichi1af52392020-11-27 18:09:32 +0900985
986 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +0900987 EXPECT_CALL(runner,
988 iptables(StrEq("mangle"),
989 ElementsAre("-A", "check_routing_mark", "-o", "eth0",
990 "-m", "mark", "!", "--mark",
991 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
992 true, nullptr));
993 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
994 ElementsAre("-A", "check_routing_mark", "-o",
995 "eth0", "-m", "mark", "!", "--mark",
996 "0x03eb0000/0xffff0000", "-j",
997 "DROP", "-w"),
998 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +0900999 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1000 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1001 "-j", "CONNMARK", "--set-mark",
1002 "0x03eb0000/0xffff0000", "-w"),
1003 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001004 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1005 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1006 "-j", "CONNMARK", "--set-mark",
1007 "0x03eb0000/0xffff0000", "-w"),
1008 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001009 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1010 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1011 "-j", "CONNMARK", "--save-mark",
1012 "--mask", "0x00003f00", "-w"),
1013 true, nullptr));
1014 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1015 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
1016 "-j", "CONNMARK", "--save-mark",
1017 "--mask", "0x00003f00", "-w"),
1018 true, nullptr));
1019 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1020 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1021 "-j", "CONNMARK", "--restore-mark",
1022 "--mask", "0x00003f00", "-w"),
1023 true, nullptr));
1024 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1025 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1026 "-j", "CONNMARK", "--restore-mark",
1027 "--mask", "0x00003f00", "-w"),
1028 true, nullptr));
Hugo Benichi155de002021-01-19 16:45:46 +09001029
Hugo Benichi1af52392020-11-27 18:09:32 +09001030 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001031 EXPECT_CALL(runner,
1032 iptables(StrEq("mangle"),
1033 ElementsAre("-D", "check_routing_mark", "-o", "eth0",
1034 "-m", "mark", "!", "--mark",
1035 "0x03eb0000/0xffff0000", "-j", "DROP", "-w"),
1036 true, nullptr));
1037 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1038 ElementsAre("-D", "check_routing_mark", "-o",
1039 "eth0", "-m", "mark", "!", "--mark",
1040 "0x03eb0000/0xffff0000", "-j",
1041 "DROP", "-w"),
1042 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001043 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1044 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1045 "-j", "CONNMARK", "--set-mark",
1046 "0x03eb0000/0xffff0000", "-w"),
1047 true, nullptr));
Hugo Benichi76be34a2020-08-26 22:35:54 +09001048 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1049 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1050 "-j", "CONNMARK", "--set-mark",
1051 "0x03eb0000/0xffff0000", "-w"),
1052 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001053 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1054 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1055 "-j", "CONNMARK", "--save-mark",
1056 "--mask", "0x00003f00", "-w"),
1057 true, nullptr));
1058 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1059 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
1060 "-j", "CONNMARK", "--save-mark",
1061 "--mask", "0x00003f00", "-w"),
1062 true, nullptr));
1063 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1064 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1065 "-j", "CONNMARK", "--restore-mark",
1066 "--mask", "0x00003f00", "-w"),
1067 true, nullptr));
1068 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1069 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1070 "-j", "CONNMARK", "--restore-mark",
1071 "--mask", "0x00003f00", "-w"),
1072 true, nullptr));
1073
Hugo Benichi76be34a2020-08-26 22:35:54 +09001074 Datapath datapath(&runner, &firewall);
1075 datapath.SetIfnameIndex("eth0", 3);
1076 datapath.StartConnectionPinning("eth0");
1077 datapath.StopConnectionPinning("eth0");
1078}
1079
Hugo Benichibfc49112020-12-14 12:54:44 +09001080TEST(DatapathTest, StartStopVpnRouting_ArcVpn) {
Hugo Benichi2a940542020-10-26 18:50:49 +09001081 MockProcessRunner runner;
1082 MockFirewall firewall;
1083
1084 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001085 EXPECT_CALL(runner,
1086 iptables(StrEq("mangle"),
1087 ElementsAre("-A", "check_routing_mark", "-o", "arcbr0",
1088 "-m", "mark", "!", "--mark",
1089 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1090 true, nullptr));
1091 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1092 ElementsAre("-A", "check_routing_mark", "-o",
1093 "arcbr0", "-m", "mark", "!",
1094 "--mark", "0x03ed0000/0xffff0000",
1095 "-j", "DROP", "-w"),
1096 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001097 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1098 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1099 "-j", "CONNMARK", "--set-mark",
1100 "0x03ed0000/0xffff0000", "-w"),
1101 true, nullptr));
1102 EXPECT_CALL(runner,
1103 iptables(StrEq("mangle"),
1104 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1105 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1106 true, nullptr));
1107 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1108 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1109 "-j", "CONNMARK", "--set-mark",
1110 "0x03ed0000/0xffff0000", "-w"),
1111 true, nullptr));
1112 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1113 ElementsAre("-A", "apply_vpn_mark", "-j",
1114 "MARK", "--set-mark",
1115 "0x03ed0000/0xffff0000", "-w"),
1116 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001117 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1118 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1119 "-j", "CONNMARK", "--save-mark",
1120 "--mask", "0x00003f00", "-w"),
1121 true, nullptr));
1122 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1123 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1124 "-j", "CONNMARK", "--save-mark",
1125 "--mask", "0x00003f00", "-w"),
1126 true, nullptr));
1127 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1128 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1129 "-j", "CONNMARK", "--restore-mark",
1130 "--mask", "0x00003f00", "-w"),
1131 true, nullptr));
1132 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1133 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1134 "-j", "CONNMARK", "--restore-mark",
1135 "--mask", "0x00003f00", "-w"),
1136 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001137 EXPECT_CALL(runner, iptables(StrEq("nat"),
1138 ElementsAre("-A", "POSTROUTING", "-o", "arcbr0",
1139 "-j", "MASQUERADE", "-w"),
1140 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001141 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001142 EXPECT_CALL(runner,
1143 iptables(StrEq("mangle"),
1144 ElementsAre("-D", "check_routing_mark", "-o", "arcbr0",
1145 "-m", "mark", "!", "--mark",
1146 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1147 true, nullptr));
1148 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1149 ElementsAre("-D", "check_routing_mark", "-o",
1150 "arcbr0", "-m", "mark", "!",
1151 "--mark", "0x03ed0000/0xffff0000",
1152 "-j", "DROP", "-w"),
1153 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001154 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1155 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1156 "-j", "CONNMARK", "--set-mark",
1157 "0x03ed0000/0xffff0000", "-w"),
1158 true, nullptr));
1159 EXPECT_CALL(runner,
1160 iptables(StrEq("mangle"),
1161 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1162 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1163 true, nullptr));
1164 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1165 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1166 "-j", "CONNMARK", "--set-mark",
1167 "0x03ed0000/0xffff0000", "-w"),
1168 true, nullptr));
1169 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1170 ElementsAre("-D", "apply_vpn_mark", "-j",
1171 "MARK", "--set-mark",
1172 "0x03ed0000/0xffff0000", "-w"),
1173 true, nullptr));
Hugo Benichi1af52392020-11-27 18:09:32 +09001174 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1175 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1176 "-j", "CONNMARK", "--save-mark",
1177 "--mask", "0x00003f00", "-w"),
1178 true, nullptr));
1179 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1180 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1181 "-j", "CONNMARK", "--save-mark",
1182 "--mask", "0x00003f00", "-w"),
1183 true, nullptr));
1184 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1185 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1186 "-j", "CONNMARK", "--restore-mark",
1187 "--mask", "0x00003f00", "-w"),
1188 true, nullptr));
1189 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1190 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1191 "-j", "CONNMARK", "--restore-mark",
1192 "--mask", "0x00003f00", "-w"),
1193 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001194 EXPECT_CALL(runner, iptables(StrEq("nat"),
1195 ElementsAre("-D", "POSTROUTING", "-o", "arcbr0",
1196 "-j", "MASQUERADE", "-w"),
1197 true, nullptr));
Hugo Benichi2a940542020-10-26 18:50:49 +09001198
1199 Datapath datapath(&runner, &firewall);
1200 datapath.SetIfnameIndex("arcbr0", 5);
1201 datapath.StartVpnRouting("arcbr0");
1202 datapath.StopVpnRouting("arcbr0");
1203}
1204
Hugo Benichibfc49112020-12-14 12:54:44 +09001205TEST(DatapathTest, StartStopVpnRouting_HostVpn) {
1206 MockProcessRunner runner;
1207 MockFirewall firewall;
1208
1209 // Setup
Hugo Benichi155de002021-01-19 16:45:46 +09001210 EXPECT_CALL(runner,
1211 iptables(StrEq("mangle"),
1212 ElementsAre("-A", "check_routing_mark", "-o", "tun0",
1213 "-m", "mark", "!", "--mark",
1214
1215 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1216 true, nullptr));
1217 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1218 ElementsAre("-A", "check_routing_mark", "-o",
1219 "tun0", "-m", "mark", "!", "--mark",
1220
1221 "0x03ed0000/0xffff0000", "-j",
1222 "DROP", "-w"),
1223 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001224 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1225 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1226 "-j", "CONNMARK", "--set-mark",
1227 "0x03ed0000/0xffff0000", "-w"),
1228 true, nullptr));
1229 EXPECT_CALL(runner,
1230 iptables(StrEq("mangle"),
1231 ElementsAre("-A", "apply_vpn_mark", "-j", "MARK",
1232 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1233 true, nullptr));
1234 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1235 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1236 "-j", "CONNMARK", "--set-mark",
1237 "0x03ed0000/0xffff0000", "-w"),
1238 true, nullptr));
1239 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1240 ElementsAre("-A", "apply_vpn_mark", "-j",
1241 "MARK", "--set-mark",
1242 "0x03ed0000/0xffff0000", "-w"),
1243 true, nullptr));
1244 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1245 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1246 "-j", "CONNMARK", "--save-mark",
1247 "--mask", "0x00003f00", "-w"),
1248 true, nullptr));
1249 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1250 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1251 "-j", "CONNMARK", "--save-mark",
1252 "--mask", "0x00003f00", "-w"),
1253 true, nullptr));
1254 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1255 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1256 "-j", "CONNMARK", "--restore-mark",
1257 "--mask", "0x00003f00", "-w"),
1258 true, nullptr));
1259 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1260 ElementsAre("-A", "PREROUTING", "-i", "tun0",
1261 "-j", "CONNMARK", "--restore-mark",
1262 "--mask", "0x00003f00", "-w"),
1263 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001264 EXPECT_CALL(runner, iptables(StrEq("nat"),
1265 ElementsAre("-A", "POSTROUTING", "-o", "tun0",
1266 "-j", "MASQUERADE", "-w"),
1267 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001268 // Teardown
Hugo Benichi155de002021-01-19 16:45:46 +09001269 EXPECT_CALL(runner,
1270 iptables(StrEq("mangle"),
1271 ElementsAre("-D", "check_routing_mark", "-o", "tun0",
1272 "-m", "mark", "!", "--mark",
1273
1274 "0x03ed0000/0xffff0000", "-j", "DROP", "-w"),
1275 true, nullptr));
1276 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1277 ElementsAre("-D", "check_routing_mark", "-o",
1278 "tun0", "-m", "mark", "!", "--mark",
1279
1280 "0x03ed0000/0xffff0000", "-j",
1281 "DROP", "-w"),
1282 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001283 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1284 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1285 "-j", "CONNMARK", "--set-mark",
1286 "0x03ed0000/0xffff0000", "-w"),
1287 true, nullptr));
1288 EXPECT_CALL(runner,
1289 iptables(StrEq("mangle"),
1290 ElementsAre("-D", "apply_vpn_mark", "-j", "MARK",
1291 "--set-mark", "0x03ed0000/0xffff0000", "-w"),
1292 true, nullptr));
1293 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1294 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1295 "-j", "CONNMARK", "--set-mark",
1296 "0x03ed0000/0xffff0000", "-w"),
1297 true, nullptr));
1298 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1299 ElementsAre("-D", "apply_vpn_mark", "-j",
1300 "MARK", "--set-mark",
1301 "0x03ed0000/0xffff0000", "-w"),
1302 true, nullptr));
1303 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1304 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1305 "-j", "CONNMARK", "--save-mark",
1306 "--mask", "0x00003f00", "-w"),
1307 true, nullptr));
1308 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1309 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1310 "-j", "CONNMARK", "--save-mark",
1311 "--mask", "0x00003f00", "-w"),
1312 true, nullptr));
1313 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1314 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1315 "-j", "CONNMARK", "--restore-mark",
1316 "--mask", "0x00003f00", "-w"),
1317 true, nullptr));
1318 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1319 ElementsAre("-D", "PREROUTING", "-i", "tun0",
1320 "-j", "CONNMARK", "--restore-mark",
1321 "--mask", "0x00003f00", "-w"),
1322 true, nullptr));
Hugo Benichi891275e2020-12-16 10:35:34 +09001323 EXPECT_CALL(runner, iptables(StrEq("nat"),
1324 ElementsAre("-D", "POSTROUTING", "-o", "tun0",
1325 "-j", "MASQUERADE", "-w"),
1326 true, nullptr));
Hugo Benichibfc49112020-12-14 12:54:44 +09001327 // Start tun0 <-> arcbr0 routing
1328 EXPECT_CALL(runner, iptables(StrEq("filter"),
1329 ElementsAre("-A", "FORWARD", "-i", "tun0", "-o",
1330 "arcbr0", "-j", "ACCEPT", "-w"),
1331 true, nullptr));
1332 EXPECT_CALL(runner, iptables(StrEq("filter"),
1333 ElementsAre("-A", "FORWARD", "-i", "arcbr0",
1334 "-o", "tun0", "-j", "ACCEPT", "-w"),
1335 true, nullptr));
1336 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1337 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1338 "-j", "MARK", "--set-mark",
1339 "0x00002000/0x00003f00", "-w"),
1340 true, nullptr));
1341 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1342 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1343 "-j", "MARK", "--set-mark",
1344 "0x03ed0000/0xffff0000", "-w"),
1345 true, nullptr));
1346 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1347 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1348 "-j", "MARK", "--set-mark",
1349 "0x00002000/0x00003f00", "-w"),
1350 true, nullptr));
1351 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1352 ElementsAre("-A", "PREROUTING", "-i", "arcbr0",
1353 "-j", "MARK", "--set-mark",
1354 "0x03ed0000/0xffff0000", "-w"),
1355 true, nullptr));
1356 // Stop tun0 <-> arcbr0 routing
1357 EXPECT_CALL(runner, iptables(StrEq("filter"),
1358 ElementsAre("-D", "FORWARD", "-i", "tun0", "-o",
1359 "arcbr0", "-j", "ACCEPT", "-w"),
1360 true, nullptr));
1361 EXPECT_CALL(runner, iptables(StrEq("filter"),
1362 ElementsAre("-D", "FORWARD", "-i", "arcbr0",
1363 "-o", "tun0", "-j", "ACCEPT", "-w"),
1364 true, nullptr));
1365 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1366 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1367 "-j", "MARK", "--set-mark",
1368 "0x00002000/0x00003f00", "-w"),
1369 true, nullptr));
1370 EXPECT_CALL(runner, iptables(StrEq("mangle"),
1371 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1372 "-j", "MARK", "--set-mark",
1373 "0x03ed0000/0xffff0000", "-w"),
1374 true, nullptr));
1375 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1376 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1377 "-j", "MARK", "--set-mark",
1378 "0x00002000/0x00003f00", "-w"),
1379 true, nullptr));
1380 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
1381 ElementsAre("-D", "PREROUTING", "-i", "arcbr0",
1382 "-j", "MARK", "--set-mark",
1383 "0x03ed0000/0xffff0000", "-w"),
1384 true, nullptr));
1385
1386 Datapath datapath(&runner, &firewall);
1387 datapath.SetIfnameIndex("tun0", 5);
1388 datapath.StartVpnRouting("tun0");
1389 datapath.StopVpnRouting("tun0");
1390}
1391
Garrick Evansf0ab7132019-06-18 14:50:42 +09001392TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001393 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001394 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001395 EXPECT_CALL(runner, iptables(StrEq("nat"),
1396 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1397 "-m", "socket", "--nowildcard", "-j",
1398 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001399 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001400 EXPECT_CALL(runner, iptables(StrEq("nat"),
1401 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1402 "-p", "tcp", "-j", "DNAT",
1403 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001404 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001405 EXPECT_CALL(runner, iptables(StrEq("nat"),
1406 ElementsAre("-A", "PREROUTING", "-i", "eth0",
1407 "-p", "udp", "-j", "DNAT",
1408 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001409 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001410 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001411 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001412}
1413
1414TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001415 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001416 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001417 EXPECT_CALL(runner, iptables(StrEq("nat"),
1418 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1419 "-m", "socket", "--nowildcard", "-j",
1420 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001421 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001422 EXPECT_CALL(runner, iptables(StrEq("nat"),
1423 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1424 "-p", "tcp", "-j", "DNAT",
1425 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001426 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001427 EXPECT_CALL(runner, iptables(StrEq("nat"),
1428 ElementsAre("-D", "PREROUTING", "-i", "eth0",
1429 "-p", "udp", "-j", "DNAT",
1430 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001431 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001432 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +09001433 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +09001434}
1435
Garrick Evans664a82f2019-12-17 12:18:05 +09001436TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001437 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001438 MockFirewall firewall;
1439 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +09001440
Garrick Evans664a82f2019-12-17 12:18:05 +09001441 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +09001442 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +09001443 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +09001444 EXPECT_EQ(ioctl_reqs, expected);
1445 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +09001446 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +09001447}
1448
1449TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001450 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001451 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +09001452 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +09001453 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1454 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1455 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001456 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001457 .WillOnce(Return(1));
1458 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1459 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
1460 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001461 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001462 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1463 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1464 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001465 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +09001466 .WillOnce(Return(1));
1467 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1468 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
1469 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001470 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001471 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001472 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001473}
1474
Taoyu Lica49c832019-12-06 17:56:43 +09001475TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001476 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001477 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001478 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1479 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
1480 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001481 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001482 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1483 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
1484 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001485 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001486 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +09001487 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +09001488}
1489
Taoyu Li90c13912019-11-26 17:56:54 +09001490TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001491 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001492 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001493 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1494 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
1495 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001496 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +09001497 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
1498 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
1499 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001500 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001501 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +09001502 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +09001503}
1504
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001505TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +09001506 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001507 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +09001508 EXPECT_CALL(runner,
1509 ip6(StrEq("route"), StrEq("replace"),
1510 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001511 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001512 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +09001513}
1514
Hugo Benichie8758b52020-04-03 14:49:01 +09001515TEST(DatapathTest, AddIPv4Route) {
1516 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001517 MockFirewall firewall;
1518 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +09001519
1520 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1521 Ipv4Addr(255, 255, 255, 0));
1522 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1523 Ipv4Addr(255, 255, 255, 0));
1524 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1525 Ipv4Addr(255, 255, 255, 252));
1526 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1527 Ipv4Addr(255, 255, 255, 252));
1528
1529 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1530 SIOCDELRT};
1531 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001532
1533 std::string route1 =
1534 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1535 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1536 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1537 "RTF_GATEWAY}";
1538 std::string route2 =
1539 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1540 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1541 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1542 std::vector<std::string> captured_routes;
1543 for (const auto& route : ioctl_rtentry_args) {
1544 std::ostringstream stream;
1545 stream << route.second;
1546 captured_routes.emplace_back(stream.str());
1547 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001548 EXPECT_EQ(route1, captured_routes[0]);
1549 EXPECT_EQ(route1, captured_routes[1]);
1550 EXPECT_EQ(route2, captured_routes[2]);
1551 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001552 ioctl_reqs.clear();
1553 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001554}
1555
Garrick Evans2f581a02020-05-11 10:43:35 +09001556TEST(DatapathTest, ArcVethHostName) {
1557 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1558 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1559 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1560 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1561 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1562 EXPECT_EQ("vethexceeds_ify", ifname);
1563 EXPECT_LT(ifname.length(), IFNAMSIZ);
1564}
1565
Garrick Evans8a067562020-05-11 12:47:30 +09001566TEST(DatapathTest, ArcBridgeName) {
1567 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1568 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1569 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1570 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1571 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1572 EXPECT_EQ("arc_exceeds_ify", ifname);
1573 EXPECT_LT(ifname.length(), IFNAMSIZ);
1574}
1575
Garrick Evans3388a032020-03-24 11:25:55 +09001576} // namespace patchpanel