blob: 93c062f48f6ec5ca8ac75ce26387eb63ded6af59 [file] [log] [blame]
Garrick Evansf0ab7132019-06-18 14:50:42 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/datapath.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +09006
Garrick Evansc7ae82c2019-09-04 16:25:10 +09007#include <linux/if_tun.h>
Taoyu Li90c13912019-11-26 17:56:54 +09008#include <net/if.h>
Garrick Evansc7ae82c2019-09-04 16:25:10 +09009#include <sys/ioctl.h>
10
Garrick Evansf0ab7132019-06-18 14:50:42 +090011#include <utility>
12#include <vector>
13
Garrick Evansc7ae82c2019-09-04 16:25:10 +090014#include <base/bind.h>
Qijiang Fane90b8792020-03-09 16:15:41 +090015#include <base/bind_helpers.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090016#include <base/strings/string_util.h>
Garrick Evans8e8e3472020-01-23 14:03:50 +090017#include <gmock/gmock.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090018#include <gtest/gtest.h>
19
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090020#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090021#include "patchpanel/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090022
Garrick Evans8e8e3472020-01-23 14:03:50 +090023using testing::_;
24using testing::ElementsAre;
25using testing::Return;
26using testing::StrEq;
27
Garrick Evans3388a032020-03-24 11:25:55 +090028namespace patchpanel {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090029namespace {
30
Hugo Benichi76675592020-04-08 14:29:57 +090031// TODO(hugobenichi) Centralize this constant definition
32constexpr pid_t kTestPID = -2;
33
Hugo Benichie8758b52020-04-03 14:49:01 +090034std::vector<ioctl_req_t> ioctl_reqs;
35std::vector<std::pair<std::string, struct rtentry>> ioctl_rtentry_args;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090036
37// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090038int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Hugo Benichie8758b52020-04-03 14:49:01 +090039 ioctl_reqs.push_back(req);
40 return 0;
41}
42
43// Capture ioctls for SIOCADDRT and SIOCDELRT and succeed.
44int ioctl_rtentry_cap(int fd, ioctl_req_t req, struct rtentry* arg) {
45 ioctl_reqs.push_back(req);
46 ioctl_rtentry_args.push_back({"", *arg});
47 // Copy the string poited by rtentry.rt_dev because Add/DeleteIPv4Route pass
48 // this value to ioctl() on the stack.
49 if (arg->rt_dev) {
50 auto& cap = ioctl_rtentry_args.back();
51 cap.first = std::string(arg->rt_dev);
52 cap.second.rt_dev = (char*)cap.first.c_str();
53 }
Garrick Evansc7ae82c2019-09-04 16:25:10 +090054 return 0;
55}
56
57} // namespace
58
Garrick Evans8e8e3472020-01-23 14:03:50 +090059class MockProcessRunner : public MinijailedProcessRunner {
60 public:
61 MockProcessRunner() = default;
62 ~MockProcessRunner() = default;
63
Garrick Evans2470caa2020-03-04 14:15:41 +090064 MOCK_METHOD1(WriteSentinelToContainer, int(pid_t pid));
Garrick Evans8e8e3472020-01-23 14:03:50 +090065 MOCK_METHOD3(brctl,
66 int(const std::string& cmd,
67 const std::vector<std::string>& argv,
68 bool log_failures));
69 MOCK_METHOD4(chown,
70 int(const std::string& uid,
71 const std::string& gid,
72 const std::string& file,
73 bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +090074 MOCK_METHOD4(ip,
75 int(const std::string& obj,
76 const std::string& cmd,
77 const std::vector<std::string>& args,
78 bool log_failures));
79 MOCK_METHOD4(ip6,
80 int(const std::string& obj,
81 const std::string& cmd,
82 const std::vector<std::string>& args,
83 bool log_failures));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090084 MOCK_METHOD4(iptables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090085 int(const std::string& table,
86 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090087 bool log_failures,
88 std::string* output));
89 MOCK_METHOD4(ip6tables,
Garrick Evans8e8e3472020-01-23 14:03:50 +090090 int(const std::string& table,
91 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090092 bool log_failures,
93 std::string* output));
Garrick Evans8e8e3472020-01-23 14:03:50 +090094 MOCK_METHOD2(modprobe_all,
95 int(const std::vector<std::string>& modules, bool log_failures));
96 MOCK_METHOD3(sysctl_w,
97 int(const std::string& key,
98 const std::string& value,
99 bool log_failures));
Hugo Benichi33860d72020-07-09 16:34:01 +0900100 MOCK_METHOD3(ip_netns_attach,
101 int(const std::string& netns_name,
102 pid_t netns_pid,
103 bool log_failures));
104 MOCK_METHOD2(ip_netns_delete,
105 int(const std::string& netns_name, bool log_failures));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900106};
107
Hugo Benichid82d8832020-08-14 10:05:03 +0900108TEST(DatapathTest, IpFamily) {
109 EXPECT_EQ(IpFamily::Dual, IpFamily::IPv4 | IpFamily::IPv6);
110 EXPECT_EQ(IpFamily::Dual & IpFamily::IPv4, IpFamily::IPv4);
111 EXPECT_EQ(IpFamily::Dual & IpFamily::IPv6, IpFamily::IPv6);
112 EXPECT_NE(IpFamily::Dual, IpFamily::IPv4);
113 EXPECT_NE(IpFamily::Dual, IpFamily::IPv6);
114 EXPECT_NE(IpFamily::IPv4, IpFamily::IPv6);
115}
116
Hugo Benichibf811c62020-09-07 17:30:45 +0900117TEST(DatapathTest, Start) {
118 MockProcessRunner runner;
119 MockFirewall firewall;
120 // Asserts for sysctl modifications
121 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("1"), true));
122 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
123 StrEq("32768 47103"), true));
124 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
125 StrEq("1"), true));
126 // Asserts for AddSNATMarkRules
127 EXPECT_CALL(
128 runner,
129 iptables(StrEq("filter"),
130 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
131 "state", "--state", "INVALID", "-j", "DROP", "-w"),
132 true, nullptr));
133 EXPECT_CALL(runner,
134 iptables(StrEq("filter"),
135 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark",
136 "1/1", "-j", "ACCEPT", "-w"),
137 true, nullptr));
138 EXPECT_CALL(runner,
139 iptables(StrEq("nat"),
140 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
141 "1/1", "-j", "MASQUERADE", "-w"),
142 true, nullptr));
143 // Asserts for AddForwardEstablishedRule
144 EXPECT_CALL(runner,
145 iptables(StrEq("filter"),
146 ElementsAre("-A", "FORWARD", "-m", "state", "--state",
147 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
148 true, nullptr));
149 // Asserts for AddSourceIPv4DropRule() calls.
150 EXPECT_CALL(runner,
151 iptables(StrEq("filter"),
152 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
153 "100.115.92.0/23", "-j", "DROP", "-w"),
154 true, nullptr));
155 EXPECT_CALL(runner,
156 iptables(StrEq("filter"),
157 ElementsAre("-I", "OUTPUT", "-o", "wlan+", "-s",
158 "100.115.92.0/23", "-j", "DROP", "-w"),
159 true, nullptr));
160 EXPECT_CALL(runner,
161 iptables(StrEq("filter"),
162 ElementsAre("-I", "OUTPUT", "-o", "mlan+", "-s",
163 "100.115.92.0/23", "-j", "DROP", "-w"),
164 true, nullptr));
165 EXPECT_CALL(runner,
166 iptables(StrEq("filter"),
167 ElementsAre("-I", "OUTPUT", "-o", "usb+", "-s",
168 "100.115.92.0/23", "-j", "DROP", "-w"),
169 true, nullptr));
170 EXPECT_CALL(runner,
171 iptables(StrEq("filter"),
172 ElementsAre("-I", "OUTPUT", "-o", "wwan+", "-s",
173 "100.115.92.0/23", "-j", "DROP", "-w"),
174 true, nullptr));
175 EXPECT_CALL(runner,
176 iptables(StrEq("filter"),
177 ElementsAre("-I", "OUTPUT", "-o", "rmnet+", "-s",
178 "100.115.92.0/23", "-j", "DROP", "-w"),
179 true, nullptr));
180 // Asserts for AddOutboundIPv4SNATMark("vmtap+")
181 EXPECT_CALL(runner,
182 iptables(StrEq("mangle"),
183 ElementsAre("-A", "PREROUTING", "-i", "vmtap+", "-j",
184 "MARK", "--set-mark", "1/1", "-w"),
185 true, nullptr));
186
187 Datapath datapath(&runner, &firewall);
188 datapath.Start();
189}
190
191TEST(DatapathTest, Stop) {
192 MockProcessRunner runner;
193 MockFirewall firewall;
194 // Asserts for sysctl modifications
195 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_local_port_range"),
196 StrEq("32768 61000"), true));
197 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv6.conf.all.forwarding"),
198 StrEq("0"), true));
199 EXPECT_CALL(runner, sysctl_w(StrEq("net.ipv4.ip_forward"), StrEq("0"), true));
200 // Asserts for RemoveOutboundIPv4SNATMark("vmtap+")
201 EXPECT_CALL(runner,
202 iptables(StrEq("mangle"),
203 ElementsAre("-D", "PREROUTING", "-i", "vmtap+", "-j",
204 "MARK", "--set-mark", "1/1", "-w"),
205 true, nullptr));
206 // Asserts for RemoveForwardEstablishedRule
207 EXPECT_CALL(runner,
208 iptables(StrEq("filter"),
209 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
210 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
211 true, nullptr));
212 // Asserts for RemoveSNATMarkRules
213 EXPECT_CALL(
214 runner,
215 iptables(StrEq("filter"),
216 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
217 "state", "--state", "INVALID", "-j", "DROP", "-w"),
218 true, nullptr));
219 EXPECT_CALL(runner,
220 iptables(StrEq("filter"),
221 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
222 "1/1", "-j", "ACCEPT", "-w"),
223 true, nullptr));
224 EXPECT_CALL(runner,
225 iptables(StrEq("nat"),
226 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
227 "1/1", "-j", "MASQUERADE", "-w"),
228 true, nullptr));
229 // Asserts for RemoveSourceIPv4DropRule() calls.
230 EXPECT_CALL(runner,
231 iptables(StrEq("filter"),
232 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
233 "100.115.92.0/23", "-j", "DROP", "-w"),
234 true, nullptr));
235 EXPECT_CALL(runner,
236 iptables(StrEq("filter"),
237 ElementsAre("-D", "OUTPUT", "-o", "wlan+", "-s",
238 "100.115.92.0/23", "-j", "DROP", "-w"),
239 true, nullptr));
240 EXPECT_CALL(runner,
241 iptables(StrEq("filter"),
242 ElementsAre("-D", "OUTPUT", "-o", "mlan+", "-s",
243 "100.115.92.0/23", "-j", "DROP", "-w"),
244 true, nullptr));
245 EXPECT_CALL(runner,
246 iptables(StrEq("filter"),
247 ElementsAre("-D", "OUTPUT", "-o", "usb+", "-s",
248 "100.115.92.0/23", "-j", "DROP", "-w"),
249 true, nullptr));
250 EXPECT_CALL(runner,
251 iptables(StrEq("filter"),
252 ElementsAre("-D", "OUTPUT", "-o", "wwan+", "-s",
253 "100.115.92.0/23", "-j", "DROP", "-w"),
254 true, nullptr));
255 EXPECT_CALL(runner,
256 iptables(StrEq("filter"),
257 ElementsAre("-D", "OUTPUT", "-o", "rmnet+", "-s",
258 "100.115.92.0/23", "-j", "DROP", "-w"),
259 true, nullptr));
260
261 Datapath datapath(&runner, &firewall);
262 datapath.Stop();
263}
264
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900265TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900266 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900267 MockFirewall firewall;
268 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900269 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900270 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900271 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900272 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900273 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900274 std::vector<ioctl_req_t> expected = {
275 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
276 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900277 EXPECT_EQ(ioctl_reqs, expected);
278 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900279 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900280}
281
282TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900283 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900284 MockFirewall firewall;
285 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900286 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900287 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900288 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900289 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900290 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900291 std::vector<ioctl_req_t> expected = {
292 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
293 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900294 EXPECT_EQ(ioctl_reqs, expected);
295 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900296 ioctl_rtentry_args.clear();
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900297}
298
Garrick Evans621ed262019-11-13 12:28:43 +0900299TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900300 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900301 MockFirewall firewall;
302 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900303 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900304 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900305 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
306 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900307 EXPECT_EQ(ioctl_reqs, expected);
308 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900309 ioctl_rtentry_args.clear();
Garrick Evans621ed262019-11-13 12:28:43 +0900310}
311
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900312TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900313 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900314 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900315 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
316 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900317 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900318 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900319}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900320
Hugo Benichi33860d72020-07-09 16:34:01 +0900321TEST(DatapathTest, NetnsAttachName) {
322 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900323 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900324 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
325 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900326 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900327 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
328}
329
330TEST(DatapathTest, NetnsDeleteName) {
331 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900332 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900333 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900334 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900335 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
336}
337
Garrick Evans8a949dc2019-07-18 16:17:53 +0900338TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900339 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900340 MockFirewall firewall;
341 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900342 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900343 EXPECT_CALL(
344 runner,
345 ip(StrEq("addr"), StrEq("add"),
346 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900347 EXPECT_CALL(runner,
348 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900349 EXPECT_CALL(runner, iptables(StrEq("mangle"),
350 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900351 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900352 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900353 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900354}
355
Hugo Benichi76675592020-04-08 14:29:57 +0900356TEST(DatapathTest, ConnectVethPair) {
357 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900358 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900359 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
360 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900361 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900362 true));
363 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
364 ElementsAre("100.115.92.169/30", "brd",
365 "100.115.92.171", "dev", "peer_foo"),
366 true))
367 .WillOnce(Return(0));
368 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
369 ElementsAre("dev", "peer_foo", "up", "addr",
370 "01:02:03:04:05:06", "multicast", "on"),
371 true))
372 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900373 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
374 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900375 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900376 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
377 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900378 Ipv4Addr(100, 115, 92, 169), 30, true));
379}
380
Garrick Evans2470caa2020-03-04 14:15:41 +0900381TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900382 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900383 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900384 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
385 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900386 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900387 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900388 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900389 EXPECT_TRUE(
390 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900391}
392
393TEST(DatapathTest, ToggleInterface) {
394 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900395 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900396 EXPECT_CALL(runner,
397 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900398 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900399 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900400 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900401 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
402 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
403}
404
405TEST(DatapathTest, ConfigureInterface) {
406 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900407 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900408 EXPECT_CALL(
409 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900410 ip(StrEq("addr"), StrEq("add"),
411 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
412 .WillOnce(Return(0));
413 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
414 ElementsAre("dev", "foo", "up", "addr",
415 "02:02:02:02:02:02", "multicast", "on"),
416 true))
417 .WillOnce(Return(0));
418
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900419 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900420 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
421 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
422 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900423}
424
425TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900426 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900427 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900428 EXPECT_CALL(runner,
429 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900430 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900431 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900432}
433
Garrick Evans8a949dc2019-07-18 16:17:53 +0900434TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900435 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900436 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900437 EXPECT_CALL(runner, iptables(StrEq("mangle"),
438 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900439 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900440 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900441 EXPECT_CALL(runner,
442 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900443 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900444 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900445 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900446}
447
Hugo Benichi321f23b2020-09-25 15:42:05 +0900448TEST(DatapathTest, AddRemoveSourceIPv4DropRule) {
449 MockProcessRunner runner;
450 MockFirewall firewall;
451 EXPECT_CALL(runner,
452 iptables(StrEq("filter"),
453 ElementsAre("-I", "OUTPUT", "-o", "eth+", "-s",
454 "100.115.92.0/24", "-j", "DROP", "-w"),
455 true, nullptr));
456 EXPECT_CALL(runner,
457 iptables(StrEq("filter"),
458 ElementsAre("-D", "OUTPUT", "-o", "eth+", "-s",
459 "100.115.92.0/24", "-j", "DROP", "-w"),
460 true, nullptr));
461 Datapath datapath(&runner, &firewall);
462 datapath.AddSourceIPv4DropRule("eth+", "100.115.92.0/24");
463 datapath.RemoveSourceIPv4DropRule("eth+", "100.115.92.0/24");
464}
465
Hugo Benichi7c342672020-09-08 09:18:14 +0900466TEST(DatapathTest, StartRoutingNamespace) {
467 MockProcessRunner runner;
468 MockFirewall firewall;
469 MacAddress mac = {1, 2, 3, 4, 5, 6};
470
471 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
472 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), kTestPID, true));
473 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
474 ElementsAre("arc_ns0", "type", "veth", "peer", "name",
475 "veth0", "netns", "netns_foo"),
476 true));
477 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
478 ElementsAre("100.115.92.130/30", "brd",
479 "100.115.92.131", "dev", "veth0"),
480 true))
481 .WillOnce(Return(0));
482 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
483 ElementsAre("dev", "veth0", "up", "addr",
484 "01:02:03:04:05:06", "multicast", "off"),
485 true))
486 .WillOnce(Return(0));
487 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
488 ElementsAre("arc_ns0", "up"), true));
489 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
490 ElementsAre("100.115.92.129/30", "brd",
491 "100.115.92.131", "dev", "arc_ns0"),
492 true))
493 .WillOnce(Return(0));
494 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
495 ElementsAre("dev", "arc_ns0", "up", "addr",
496 "01:02:03:04:05:06", "multicast", "off"),
497 true))
498 .WillOnce(Return(0));
499 EXPECT_CALL(runner, iptables(StrEq("filter"),
500 ElementsAre("-A", "FORWARD", "-o", "arc_ns0",
501 "-j", "ACCEPT", "-w"),
502 true, nullptr));
503 EXPECT_CALL(runner,
504 iptables(StrEq("mangle"),
505 ElementsAre("-A", "PREROUTING", "-i", "arc_ns0", "-j",
506 "MARK", "--set-mark", "1/1", "-w"),
507 true, nullptr));
508
509 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
510 datapath.StartRoutingNamespace(
511 kTestPID, "netns_foo", "arc_ns0", "veth0", Ipv4Addr(100, 115, 92, 128),
512 30, Ipv4Addr(100, 115, 92, 129), Ipv4Addr(100, 115, 92, 130), mac);
513 ioctl_reqs.clear();
514 ioctl_rtentry_args.clear();
515}
516
517TEST(DatapathTest, StopRoutingNamespace) {
518 MockProcessRunner runner;
519 MockFirewall firewall;
520
521 EXPECT_CALL(runner, iptables(StrEq("filter"),
522 ElementsAre("-D", "FORWARD", "-o", "arc_ns0",
523 "-j", "ACCEPT", "-w"),
524 true, nullptr));
525 EXPECT_CALL(runner,
526 iptables(StrEq("mangle"),
527 ElementsAre("-D", "PREROUTING", "-i", "arc_ns0", "-j",
528 "MARK", "--set-mark", "1/1", "-w"),
529 true, nullptr));
530 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
531 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("delete"), ElementsAre("arc_ns0"),
532 false));
533
534 Datapath datapath(&runner, &firewall);
535 datapath.StopRoutingNamespace("netns_foo", "arc_ns0",
536 Ipv4Addr(100, 115, 92, 128), 30,
537 Ipv4Addr(100, 115, 92, 129));
538}
539
Hugo Benichi8d622b52020-08-13 15:24:12 +0900540TEST(DatapathTest, StartRoutingDevice_Arc) {
541 MockProcessRunner runner;
542 MockFirewall firewall;
543 EXPECT_CALL(runner, iptables(StrEq("nat"),
544 ElementsAre("-A", "PREROUTING", "-i", "eth0",
545 "-m", "socket", "--nowildcard", "-j",
546 "ACCEPT", "-w"),
547 true, nullptr));
548 EXPECT_CALL(runner, iptables(StrEq("nat"),
549 ElementsAre("-A", "PREROUTING", "-i", "eth0",
550 "-p", "tcp", "-j", "DNAT",
551 "--to-destination", "1.2.3.4", "-w"),
552 true, nullptr));
553 EXPECT_CALL(runner, iptables(StrEq("nat"),
554 ElementsAre("-A", "PREROUTING", "-i", "eth0",
555 "-p", "udp", "-j", "DNAT",
556 "--to-destination", "1.2.3.4", "-w"),
557 true, nullptr));
558 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900559 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
560 "arc_eth0", "-j", "ACCEPT", "-w"),
561 true, nullptr));
562 EXPECT_CALL(runner, iptables(StrEq("filter"),
563 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
564 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +0900565 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900566 EXPECT_CALL(runner, iptables(StrEq("mangle"),
567 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
568 "-j", "MARK", "--set-mark",
569 "0x00002000/0x00003f00", "-w"),
570 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900571 EXPECT_CALL(runner, iptables(StrEq("mangle"),
572 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0",
573 "-j", "MARK", "--set-mark",
574 "0x03ea0000/0xffff0000", "-w"),
575 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900576 EXPECT_CALL(
577 runner,
578 ip6tables(StrEq("mangle"),
579 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
580 "--set-mark", "0x00002000/0x00003f00", "-w"),
581 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900582 EXPECT_CALL(
583 runner,
584 ip6tables(StrEq("mangle"),
585 ElementsAre("-A", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
586 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
587 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900588
589 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900590 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900591 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
592 TrafficSource::ARC);
593}
594
595TEST(DatapathTest, StartRoutingDevice_CrosVM) {
596 MockProcessRunner runner;
597 MockFirewall firewall;
598 EXPECT_CALL(runner, iptables(StrEq("filter"),
599 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
600 "-j", "ACCEPT", "-w"),
601 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900602 EXPECT_CALL(runner, iptables(StrEq("filter"),
603 ElementsAre("-A", "FORWARD", "-i", "vmtap0",
604 "-j", "ACCEPT", "-w"),
605 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900606 EXPECT_CALL(runner, iptables(StrEq("mangle"),
607 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
608 "-j", "MARK", "--set-mark",
609 "0x00002100/0x00003f00", "-w"),
610 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900611 EXPECT_CALL(runner, iptables(StrEq("mangle"),
612 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
613 "-j", "CONNMARK", "--restore-mark",
614 "--mask", "0xffff0000", "-w"),
615 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900616 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
617 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
618 "-j", "MARK", "--set-mark",
619 "0x00002100/0x00003f00", "-w"),
620 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900621 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
622 ElementsAre("-A", "PREROUTING", "-i", "vmtap0",
623 "-j", "CONNMARK", "--restore-mark",
624 "--mask", "0xffff0000", "-w"),
625 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900626
627 Datapath datapath(&runner, &firewall);
628 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
629 TrafficSource::CROSVM);
630}
631
632TEST(DatapathTest, StopRoutingDevice_Arc) {
633 MockProcessRunner runner;
634 MockFirewall firewall;
635 EXPECT_CALL(runner, iptables(StrEq("nat"),
636 ElementsAre("-D", "PREROUTING", "-i", "eth0",
637 "-m", "socket", "--nowildcard", "-j",
638 "ACCEPT", "-w"),
639 true, nullptr));
640 EXPECT_CALL(runner, iptables(StrEq("nat"),
641 ElementsAre("-D", "PREROUTING", "-i", "eth0",
642 "-p", "tcp", "-j", "DNAT",
643 "--to-destination", "1.2.3.4", "-w"),
644 true, nullptr));
645 EXPECT_CALL(runner, iptables(StrEq("nat"),
646 ElementsAre("-D", "PREROUTING", "-i", "eth0",
647 "-p", "udp", "-j", "DNAT",
648 "--to-destination", "1.2.3.4", "-w"),
649 true, nullptr));
650 EXPECT_CALL(runner, iptables(StrEq("filter"),
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900651 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
652 "arc_eth0", "-j", "ACCEPT", "-w"),
653 true, nullptr));
654 EXPECT_CALL(runner, iptables(StrEq("filter"),
655 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
656 "-o", "eth0", "-j", "ACCEPT", "-w"),
Hugo Benichi8d622b52020-08-13 15:24:12 +0900657 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900658 EXPECT_CALL(runner, iptables(StrEq("mangle"),
659 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
660 "-j", "MARK", "--set-mark",
661 "0x00002000/0x00003f00", "-w"),
662 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900663 EXPECT_CALL(runner, iptables(StrEq("mangle"),
664 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0",
665 "-j", "MARK", "--set-mark",
666 "0x03ea0000/0xffff0000", "-w"),
667 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900668 EXPECT_CALL(
669 runner,
670 ip6tables(StrEq("mangle"),
671 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
672 "--set-mark", "0x00002000/0x00003f00", "-w"),
673 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900674 EXPECT_CALL(
675 runner,
676 ip6tables(StrEq("mangle"),
677 ElementsAre("-D", "PREROUTING", "-i", "arc_eth0", "-j", "MARK",
678 "--set-mark", "0x03ea0000/0xffff0000", "-w"),
679 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900680
681 Datapath datapath(&runner, &firewall);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900682 datapath.SetIfnameIndex("eth0", 2);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900683 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
684 TrafficSource::ARC);
685}
686
687TEST(DatapathTest, StopRoutingDevice_CrosVM) {
688 MockProcessRunner runner;
689 MockFirewall firewall;
690 EXPECT_CALL(runner, iptables(StrEq("filter"),
691 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
692 "-j", "ACCEPT", "-w"),
693 true, nullptr));
Hugo Benichic6ae67c2020-08-14 15:02:13 +0900694 EXPECT_CALL(runner, iptables(StrEq("filter"),
695 ElementsAre("-D", "FORWARD", "-i", "vmtap0",
696 "-j", "ACCEPT", "-w"),
697 true, nullptr));
Hugo Benichi9be19b12020-08-14 15:33:40 +0900698 EXPECT_CALL(runner, iptables(StrEq("mangle"),
699 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
700 "-j", "MARK", "--set-mark",
701 "0x00002100/0x00003f00", "-w"),
702 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900703 EXPECT_CALL(runner, iptables(StrEq("mangle"),
704 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
705 "-j", "CONNMARK", "--restore-mark",
706 "--mask", "0xffff0000", "-w"),
707 true, nullptr));
Hugo Benichi5c9c11c2020-09-15 17:25:26 +0900708 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
709 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
710 "-j", "MARK", "--set-mark",
711 "0x00002100/0x00003f00", "-w"),
712 true, nullptr));
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900713 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
714 ElementsAre("-D", "PREROUTING", "-i", "vmtap0",
715 "-j", "CONNMARK", "--restore-mark",
716 "--mask", "0xffff0000", "-w"),
717 true, nullptr));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900718
719 Datapath datapath(&runner, &firewall);
720 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
721 TrafficSource::CROSVM);
722}
723
Hugo Benichid82d8832020-08-14 10:05:03 +0900724TEST(DatapathTest, StartStopIpForwarding) {
725 struct {
726 IpFamily family;
727 std::string iif;
728 std::string oif;
729 std::vector<std::string> start_args;
730 std::vector<std::string> stop_args;
731 bool result;
732 } testcases[] = {
733 {IpFamily::IPv4, "", "", {}, {}, false},
734 {IpFamily::NONE, "foo", "bar", {}, {}, false},
735 {IpFamily::IPv4,
736 "foo",
737 "bar",
738 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
739 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
740 true},
741 {IpFamily::IPv4,
742 "",
743 "bar",
744 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
745 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
746 true},
747 {IpFamily::IPv4,
748 "foo",
749 "",
750 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
751 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
752 true},
753 {IpFamily::IPv6,
754 "foo",
755 "bar",
756 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
757 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
758 true},
759 {IpFamily::IPv6,
760 "",
761 "bar",
762 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
763 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
764 true},
765 {IpFamily::IPv6,
766 "foo",
767 "",
768 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
769 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
770 true},
771 {IpFamily::Dual,
772 "foo",
773 "bar",
774 {"-A", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
775 {"-D", "FORWARD", "-i", "foo", "-o", "bar", "-j", "ACCEPT", "-w"},
776 true},
777 {IpFamily::Dual,
778 "",
779 "bar",
780 {"-A", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
781 {"-D", "FORWARD", "-o", "bar", "-j", "ACCEPT", "-w"},
782 true},
783 {IpFamily::Dual,
784 "foo",
785 "",
786 {"-A", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
787 {"-D", "FORWARD", "-i", "foo", "-j", "ACCEPT", "-w"},
788 true},
789 };
790
791 for (const auto& tt : testcases) {
792 MockProcessRunner runner;
793 MockFirewall firewall;
794 if (tt.result) {
795 if (tt.family & IpFamily::IPv4) {
796 EXPECT_CALL(runner,
797 iptables(StrEq("filter"), tt.start_args, true, nullptr))
798 .WillOnce(Return(0));
799 EXPECT_CALL(runner,
800 iptables(StrEq("filter"), tt.stop_args, true, nullptr))
801 .WillOnce(Return(0));
802 }
803 if (tt.family & IpFamily::IPv6) {
804 EXPECT_CALL(runner,
805 ip6tables(StrEq("filter"), tt.start_args, true, nullptr))
806 .WillOnce(Return(0));
807 EXPECT_CALL(runner,
808 ip6tables(StrEq("filter"), tt.stop_args, true, nullptr))
809 .WillOnce(Return(0));
810 }
811 }
812 Datapath datapath(&runner, &firewall);
813
814 EXPECT_EQ(tt.result, datapath.StartIpForwarding(tt.family, tt.iif, tt.oif));
815 EXPECT_EQ(tt.result, datapath.StopIpForwarding(tt.family, tt.iif, tt.oif));
816 }
817}
818
Hugo Benichi76be34a2020-08-26 22:35:54 +0900819TEST(DatapathTest, StartStopConnectionPinning) {
820 MockProcessRunner runner;
821 MockFirewall firewall;
822 EXPECT_CALL(runner, iptables(StrEq("mangle"),
823 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
824 "-j", "CONNMARK", "--set-mark",
825 "0x03eb0000/0xffff0000", "-w"),
826 true, nullptr));
827 EXPECT_CALL(runner, iptables(StrEq("mangle"),
828 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
829 "-j", "CONNMARK", "--set-mark",
830 "0x03eb0000/0xffff0000", "-w"),
831 true, nullptr));
832 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
833 ElementsAre("-A", "POSTROUTING", "-o", "eth0",
834 "-j", "CONNMARK", "--set-mark",
835 "0x03eb0000/0xffff0000", "-w"),
836 true, nullptr));
837 EXPECT_CALL(runner, ip6tables(StrEq("mangle"),
838 ElementsAre("-D", "POSTROUTING", "-o", "eth0",
839 "-j", "CONNMARK", "--set-mark",
840 "0x03eb0000/0xffff0000", "-w"),
841 true, nullptr));
842 Datapath datapath(&runner, &firewall);
843 datapath.SetIfnameIndex("eth0", 3);
844 datapath.StartConnectionPinning("eth0");
845 datapath.StopConnectionPinning("eth0");
846}
847
Garrick Evansf0ab7132019-06-18 14:50:42 +0900848TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900849 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900850 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900851 EXPECT_CALL(runner, iptables(StrEq("nat"),
852 ElementsAre("-A", "PREROUTING", "-i", "eth0",
853 "-m", "socket", "--nowildcard", "-j",
854 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900855 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900856 EXPECT_CALL(runner, iptables(StrEq("nat"),
857 ElementsAre("-A", "PREROUTING", "-i", "eth0",
858 "-p", "tcp", "-j", "DNAT",
859 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900860 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900861 EXPECT_CALL(runner, iptables(StrEq("nat"),
862 ElementsAre("-A", "PREROUTING", "-i", "eth0",
863 "-p", "udp", "-j", "DNAT",
864 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900865 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900866 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900867 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900868}
869
870TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900871 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900872 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900873 EXPECT_CALL(runner, iptables(StrEq("nat"),
874 ElementsAre("-D", "PREROUTING", "-i", "eth0",
875 "-m", "socket", "--nowildcard", "-j",
876 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900877 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900878 EXPECT_CALL(runner, iptables(StrEq("nat"),
879 ElementsAre("-D", "PREROUTING", "-i", "eth0",
880 "-p", "tcp", "-j", "DNAT",
881 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900882 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900883 EXPECT_CALL(runner, iptables(StrEq("nat"),
884 ElementsAre("-D", "PREROUTING", "-i", "eth0",
885 "-p", "udp", "-j", "DNAT",
886 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900887 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900888 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900889 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900890}
891
892TEST(DatapathTest, AddOutboundIPv4) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900893 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900894 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900895 EXPECT_CALL(runner, iptables(StrEq("filter"),
896 ElementsAre("-A", "FORWARD", "-o", "eth0", "-j",
897 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900898 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900899 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900900 datapath.AddOutboundIPv4("eth0");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900901}
902
903TEST(DatapathTest, RemoveInboundIPv4) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900904 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900905 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900906 EXPECT_CALL(runner, iptables(StrEq("filter"),
907 ElementsAre("-D", "FORWARD", "-o", "eth0", "-j",
908 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900909 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900910 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900911 datapath.RemoveOutboundIPv4("eth0");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900912}
913
Garrick Evans664a82f2019-12-17 12:18:05 +0900914TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900915 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900916 MockFirewall firewall;
917 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Hugo Benichi7c342672020-09-08 09:18:14 +0900918
Garrick Evans664a82f2019-12-17 12:18:05 +0900919 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +0900920 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +0900921 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +0900922 EXPECT_EQ(ioctl_reqs, expected);
923 ioctl_reqs.clear();
Hugo Benichi7c342672020-09-08 09:18:14 +0900924 ioctl_rtentry_args.clear();
Taoyu Li90c13912019-11-26 17:56:54 +0900925}
926
927TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900928 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900929 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +0900930 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +0900931 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
932 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
933 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900934 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +0900935 .WillOnce(Return(1));
936 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
937 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
938 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900939 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900940 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
941 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
942 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900943 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +0900944 .WillOnce(Return(1));
945 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
946 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
947 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900948 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900949 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +0900950 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +0900951}
952
Taoyu Lica49c832019-12-06 17:56:43 +0900953TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900954 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900955 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900956 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
957 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
958 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900959 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900960 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
961 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
962 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900963 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900964 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +0900965 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +0900966}
967
Taoyu Li90c13912019-11-26 17:56:54 +0900968TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900969 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900970 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900971 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
972 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
973 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900974 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900975 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
976 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
977 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900978 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900979 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +0900980 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +0900981}
982
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900983TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900984 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900985 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900986 EXPECT_CALL(runner,
987 ip6(StrEq("route"), StrEq("replace"),
988 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900989 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900990 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900991}
992
Hugo Benichie8758b52020-04-03 14:49:01 +0900993TEST(DatapathTest, AddIPv4Route) {
994 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900995 MockFirewall firewall;
996 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +0900997
998 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
999 Ipv4Addr(255, 255, 255, 0));
1000 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
1001 Ipv4Addr(255, 255, 255, 0));
1002 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1003 Ipv4Addr(255, 255, 255, 252));
1004 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
1005 Ipv4Addr(255, 255, 255, 252));
1006
1007 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
1008 SIOCDELRT};
1009 EXPECT_EQ(expected_reqs, ioctl_reqs);
Hugo Benichie8758b52020-04-03 14:49:01 +09001010
1011 std::string route1 =
1012 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
1013 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
1014 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
1015 "RTF_GATEWAY}";
1016 std::string route2 =
1017 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
1018 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
1019 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
1020 std::vector<std::string> captured_routes;
1021 for (const auto& route : ioctl_rtentry_args) {
1022 std::ostringstream stream;
1023 stream << route.second;
1024 captured_routes.emplace_back(stream.str());
1025 }
Hugo Benichie8758b52020-04-03 14:49:01 +09001026 EXPECT_EQ(route1, captured_routes[0]);
1027 EXPECT_EQ(route1, captured_routes[1]);
1028 EXPECT_EQ(route2, captured_routes[2]);
1029 EXPECT_EQ(route2, captured_routes[3]);
Hugo Benichi7c342672020-09-08 09:18:14 +09001030 ioctl_reqs.clear();
1031 ioctl_rtentry_args.clear();
Hugo Benichie8758b52020-04-03 14:49:01 +09001032}
1033
Garrick Evansd291af62020-05-25 10:39:06 +09001034TEST(DatapathTest, AddSNATMarkRules) {
1035 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001036 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +09001037 EXPECT_CALL(
1038 runner,
1039 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +09001040 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +09001041 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001042 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +09001043 EXPECT_CALL(runner,
1044 iptables(StrEq("filter"),
1045 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark",
1046 "1/1", "-j", "ACCEPT", "-w"),
1047 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +09001048 EXPECT_CALL(runner,
1049 iptables(StrEq("nat"),
1050 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +09001051 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001052 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001053 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001054 datapath.AddSNATMarkRules();
1055}
1056
1057TEST(DatapathTest, RemoveSNATMarkRules) {
1058 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001059 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +09001060 EXPECT_CALL(
1061 runner,
1062 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +09001063 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +09001064 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001065 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +09001066 EXPECT_CALL(runner,
1067 iptables(StrEq("filter"),
1068 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
1069 "1/1", "-j", "ACCEPT", "-w"),
1070 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +09001071 EXPECT_CALL(runner,
1072 iptables(StrEq("nat"),
1073 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +09001074 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001075 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001076 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001077 datapath.RemoveSNATMarkRules();
1078}
1079
1080TEST(DatapathTest, AddForwardEstablishedRule) {
1081 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001082 MockFirewall firewall;
Garrick Evansd291af62020-05-25 10:39:06 +09001083 EXPECT_CALL(runner,
1084 iptables(StrEq("filter"),
1085 ElementsAre("-A", "FORWARD", "-m", "state", "--state",
1086 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001087 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001088 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001089 datapath.AddForwardEstablishedRule();
1090}
1091
1092TEST(DatapathTest, RemoveForwardEstablishedRule) {
1093 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001094 MockFirewall firewall;
Garrick Evansd291af62020-05-25 10:39:06 +09001095 EXPECT_CALL(runner,
1096 iptables(StrEq("filter"),
1097 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
1098 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001099 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001100 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +09001101 datapath.RemoveForwardEstablishedRule();
1102}
1103
Garrick Evansff6e37f2020-05-25 10:54:47 +09001104TEST(DatapathTest, AddInterfaceSNAT) {
1105 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001106 MockFirewall firewall;
Garrick Evansff6e37f2020-05-25 10:54:47 +09001107 EXPECT_CALL(runner, iptables(StrEq("nat"),
1108 ElementsAre("-A", "POSTROUTING", "-o", "wwan+",
1109 "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001110 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001111 Datapath datapath(&runner, &firewall);
Garrick Evansff6e37f2020-05-25 10:54:47 +09001112 datapath.AddInterfaceSNAT("wwan+");
1113}
1114
1115TEST(DatapathTest, RemoveInterfaceSNAT) {
1116 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001117 MockFirewall firewall;
Garrick Evansff6e37f2020-05-25 10:54:47 +09001118 EXPECT_CALL(runner, iptables(StrEq("nat"),
1119 ElementsAre("-D", "POSTROUTING", "-o", "wwan+",
1120 "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09001121 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +09001122 Datapath datapath(&runner, &firewall);
Garrick Evansff6e37f2020-05-25 10:54:47 +09001123 datapath.RemoveInterfaceSNAT("wwan+");
1124}
1125
Garrick Evans2f581a02020-05-11 10:43:35 +09001126TEST(DatapathTest, ArcVethHostName) {
1127 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
1128 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
1129 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
1130 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
1131 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
1132 EXPECT_EQ("vethexceeds_ify", ifname);
1133 EXPECT_LT(ifname.length(), IFNAMSIZ);
1134}
1135
Garrick Evans8a067562020-05-11 12:47:30 +09001136TEST(DatapathTest, ArcBridgeName) {
1137 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
1138 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
1139 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
1140 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
1141 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
1142 EXPECT_EQ("arc_exceeds_ify", ifname);
1143 EXPECT_LT(ifname.length(), IFNAMSIZ);
1144}
1145
Garrick Evans3388a032020-03-24 11:25:55 +09001146} // namespace patchpanel