blob: 1d3f817b2e4382f9cb5b55438e2ccaa1a4edae00 [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
5#include "arc/network/datapath.h"
6
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
11#include <set>
Garrick Evansf0ab7132019-06-18 14:50:42 +090012#include <utility>
13#include <vector>
14
Garrick Evansc7ae82c2019-09-04 16:25:10 +090015#include <base/bind.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090016#include <base/strings/string_util.h>
Garrick Evansf0ab7132019-06-18 14:50:42 +090017#include <gtest/gtest.h>
18
19#include "arc/network/fake_process_runner.h"
Garrick Evansc7ae82c2019-09-04 16:25:10 +090020#include "arc/network/net_util.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090021
22namespace arc_networkd {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090023namespace {
24
Taoyu Li90c13912019-11-26 17:56:54 +090025std::set<ioctl_req_t> ioctl_reqs;
Garrick Evansc7ae82c2019-09-04 16:25:10 +090026
27// Capture all ioctls and succeed.
Taoyu Li90c13912019-11-26 17:56:54 +090028int ioctl_req_cap(int fd, ioctl_req_t req, ...) {
Garrick Evansc7ae82c2019-09-04 16:25:10 +090029 ioctl_reqs.insert(req);
30 return 0;
31}
32
33} // namespace
34
35TEST(DatapathTest, AddTAP) {
36 FakeProcessRunner runner;
37 Datapath datapath(&runner, ioctl_req_cap);
38 MacAddress mac = {1, 2, 3, 4, 5, 6};
39 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::Bind(&base::DoNothing));
40 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +090041 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +090042 EXPECT_EQ(ifname, "foo0");
Taoyu Li90c13912019-11-26 17:56:54 +090043 std::set<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR,
44 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS,
45 SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +090046 EXPECT_EQ(ioctl_reqs, expected);
47 ioctl_reqs.clear();
48}
49
50TEST(DatapathTest, AddTAPWithOwner) {
51 FakeProcessRunner runner;
52 Datapath datapath(&runner, ioctl_req_cap);
53 MacAddress mac = {1, 2, 3, 4, 5, 6};
54 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::Bind(&base::DoNothing));
55 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +090056 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +090057 EXPECT_EQ(ifname, "foo0");
Taoyu Li90c13912019-11-26 17:56:54 +090058 std::set<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, TUNSETOWNER,
59 SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFHWADDR,
60 SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +090061 EXPECT_EQ(ioctl_reqs, expected);
62 ioctl_reqs.clear();
63}
64
Garrick Evans621ed262019-11-13 12:28:43 +090065TEST(DatapathTest, AddTAPNoAddrs) {
66 FakeProcessRunner runner;
67 Datapath datapath(&runner, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +090068 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +090069 EXPECT_EQ(ifname, "foo0");
Taoyu Li90c13912019-11-26 17:56:54 +090070 std::set<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
Garrick Evans4dec0c42019-11-29 12:51:57 +090071 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +090072 EXPECT_EQ(ioctl_reqs, expected);
73 ioctl_reqs.clear();
74}
75
Garrick Evansc7ae82c2019-09-04 16:25:10 +090076TEST(DatapathTest, RemoveTAP) {
77 FakeProcessRunner runner;
78 runner.Capture(true);
79 Datapath datapath(&runner);
80 datapath.RemoveTAP("foo0");
81 runner.VerifyRuns({"/bin/ip tuntap del foo0 mode tap"});
82}
Garrick Evansf0ab7132019-06-18 14:50:42 +090083
Garrick Evans8a949dc2019-07-18 16:17:53 +090084TEST(DatapathTest, AddBridge) {
85 FakeProcessRunner runner;
86 runner.Capture(true);
87 Datapath datapath(&runner);
88 datapath.AddBridge("br", "1.2.3.4");
89 runner.VerifyRuns(
90 {"/sbin/brctl addbr br",
91 "/bin/ifconfig br 1.2.3.4 netmask 255.255.255.252 up",
92 "/sbin/iptables -t mangle -A PREROUTING -i br -j MARK --set-mark 1 -w"});
93}
94
Garrick Evans54861622019-07-19 09:05:09 +090095TEST(DatapathTest, AddVirtualBridgedInterface) {
96 FakeProcessRunner runner;
97 runner.Capture(true);
98 Datapath datapath(&runner);
99 std::string peer =
100 datapath.AddVirtualBridgedInterface("foo", "00:11:22", "brfoo");
101 EXPECT_EQ(peer, "peer_foo");
102 runner.VerifyRuns(
103 {"/bin/ip link delete veth_foo", // RemoveInterface is run first
104 "/bin/ip link add veth_foo type veth peer name peer_foo",
105 "/bin/ifconfig veth_foo up",
106 "/bin/ip link set dev peer_foo addr 00:11:22 down",
107 "/sbin/brctl addif brfoo veth_foo"});
108}
109
110TEST(DatapathTest, RemoveInterface) {
111 FakeProcessRunner runner;
112 runner.Capture(true);
113 Datapath datapath(&runner);
114 datapath.RemoveInterface("foo");
115 runner.VerifyRuns({"/bin/ip link delete foo"});
116}
117
Garrick Evans8a949dc2019-07-18 16:17:53 +0900118TEST(DatapathTest, RemoveBridge) {
119 FakeProcessRunner runner;
120 runner.Capture(true);
121 Datapath datapath(&runner);
122 datapath.RemoveBridge("br");
123 runner.VerifyRuns(
124 {"/sbin/iptables -t mangle -D PREROUTING -i br -j MARK --set-mark 1 -w",
125 "/bin/ifconfig br down", "/sbin/brctl delbr br"});
126}
127
Garrick Evans54861622019-07-19 09:05:09 +0900128TEST(DatapathTest, AddInterfaceToContainer) {
129 FakeProcessRunner runner;
130 runner.Capture(true);
131 Datapath datapath(&runner);
132 datapath.AddInterfaceToContainer(123, "src", "dst", "1.2.3.4", true);
133 runner.VerifyRuns({"/bin/ip link set src netns 123"});
134 runner.VerifyAddInterface("src", "dst", "1.2.3.4", "255.255.255.252", true,
135 "123");
136}
137
Garrick Evansf0ab7132019-06-18 14:50:42 +0900138TEST(DatapathTest, AddLegacyIPv4DNAT) {
139 FakeProcessRunner runner;
140 runner.Capture(true);
141 Datapath datapath(&runner);
142 datapath.AddLegacyIPv4DNAT("1.2.3.4");
143 runner.VerifyRuns(
144 {"/sbin/iptables -t nat -N dnat_arc -w",
145 "/sbin/iptables -t nat -A dnat_arc -j DNAT --to-destination "
146 "1.2.3.4 -w",
147 "/sbin/iptables -t nat -N try_arc -w",
148 "/sbin/iptables -t nat -A PREROUTING -m socket --nowildcard -j ACCEPT "
149 "-w",
150 "/sbin/iptables -t nat -A PREROUTING -p tcp -j try_arc -w",
151 "/sbin/iptables -t nat -A PREROUTING -p udp -j try_arc -w"});
152}
153
154TEST(DatapathTest, RemoveLegacyIPv4DNAT) {
155 FakeProcessRunner runner;
156 runner.Capture(true);
157 Datapath datapath(&runner);
158 datapath.RemoveLegacyIPv4DNAT();
159 runner.VerifyRuns(
160 {"/sbin/iptables -t nat -D PREROUTING -p udp -j try_arc -w",
161 "/sbin/iptables -t nat -D PREROUTING -p tcp -j try_arc -w",
162 "/sbin/iptables -t nat -D PREROUTING -m socket --nowildcard -j "
163 "ACCEPT -w",
164 "/sbin/iptables -t nat -F try_arc -w",
165 "/sbin/iptables -t nat -X try_arc -w",
166 "/sbin/iptables -t nat -F dnat_arc -w",
167 "/sbin/iptables -t nat -X dnat_arc -w"});
168}
169
Garrick Evans54861622019-07-19 09:05:09 +0900170TEST(DatapathTest, AddLegacyIPv4InboundDNAT) {
171 FakeProcessRunner runner;
172 runner.Capture(true);
173 Datapath datapath(&runner);
174 datapath.AddLegacyIPv4InboundDNAT("wlan0");
175 runner.VerifyRuns(
176 {"/sbin/iptables -t nat -A try_arc -i wlan0 -j dnat_arc -w"});
177}
178
179TEST(DatapathTest, RemoveLegacyIPv4InboundDNAT) {
180 FakeProcessRunner runner;
181 runner.Capture(true);
182 Datapath datapath(&runner);
183 datapath.RemoveLegacyIPv4InboundDNAT();
184 runner.VerifyRuns({"/sbin/iptables -t nat -F try_arc -w"});
185}
186
Garrick Evansf0ab7132019-06-18 14:50:42 +0900187TEST(DatapathTest, AddInboundIPv4DNAT) {
188 FakeProcessRunner runner;
189 runner.Capture(true);
190 Datapath datapath(&runner);
191 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
192 runner.VerifyRuns(
193 {"/sbin/iptables -t nat -A PREROUTING -i eth0 -m socket --nowildcard -j "
194 "ACCEPT "
195 "-w",
196 "/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -j DNAT "
197 "--to-destination 1.2.3.4 -w",
198 "/sbin/iptables -t nat -A PREROUTING -i eth0 -p udp -j DNAT "
199 "--to-destination 1.2.3.4 -w"});
200}
201
202TEST(DatapathTest, RemoveInboundIPv4DNAT) {
203 FakeProcessRunner runner;
204 runner.Capture(true);
205 Datapath datapath(&runner);
206 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
207 runner.VerifyRuns(
208 {"/sbin/iptables -t nat -D PREROUTING -i eth0 -p udp -j DNAT "
209 "--to-destination 1.2.3.4 -w",
210 "/sbin/iptables -t nat -D PREROUTING -i eth0 -p tcp -j DNAT "
211 "--to-destination 1.2.3.4 -w",
212 "/sbin/iptables -t nat -D PREROUTING -i eth0 -m socket --nowildcard "
213 "-j ACCEPT -w"});
214}
215
216TEST(DatapathTest, AddOutboundIPv4) {
217 FakeProcessRunner runner;
218 runner.Capture(true);
219 Datapath datapath(&runner);
220 datapath.AddOutboundIPv4("eth0");
221 runner.VerifyRuns(
222 {"/sbin/iptables -t filter -A FORWARD -o eth0 -j ACCEPT -w"});
223}
224
225TEST(DatapathTest, RemoveInboundIPv4) {
226 FakeProcessRunner runner;
227 runner.Capture(true);
228 Datapath datapath(&runner);
229 datapath.RemoveOutboundIPv4("eth0");
230 runner.VerifyRuns(
231 {"/sbin/iptables -t filter -D FORWARD -o eth0 -j ACCEPT -w"});
232}
233
Taoyu Li90c13912019-11-26 17:56:54 +0900234TEST(DatapathTest, SetInterfaceFlag) {
235 FakeProcessRunner runner;
236 Datapath datapath(&runner, ioctl_req_cap);
237 bool result = datapath.SetInterfaceFlag("foo0", IFF_DEBUG);
238 EXPECT_TRUE(result);
239 std::set<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
240 EXPECT_EQ(ioctl_reqs, expected);
241 ioctl_reqs.clear();
242}
243
244TEST(DatapathTest, AddIPv6Forwarding) {
245 FakeProcessRunner runner;
246 runner.Capture(true);
247 Datapath datapath(&runner);
Taoyu Lica49c832019-12-06 17:56:43 +0900248 // Return 1 on iptables -C to simulate rule not existing case
249 auto fake_iptables_run = [](const std::vector<std::string>& argv) {
250 return std::find(argv.begin(), argv.end(), "-C") == argv.end() ? 0 : 1;
251 };
252 runner.SetRunOverride(base::Bind(fake_iptables_run));
Taoyu Li90c13912019-11-26 17:56:54 +0900253 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
254 runner.VerifyRuns(
Taoyu Lica49c832019-12-06 17:56:43 +0900255 {"/sbin/ip6tables -C FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w",
256 "/sbin/ip6tables -A FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w",
257 "/sbin/ip6tables -C FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w",
Taoyu Li90c13912019-11-26 17:56:54 +0900258 "/sbin/ip6tables -A FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w"});
259}
260
Taoyu Lica49c832019-12-06 17:56:43 +0900261TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
262 FakeProcessRunner runner;
263 runner.Capture(true);
264 Datapath datapath(&runner);
265 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
266 runner.VerifyRuns(
267 {"/sbin/ip6tables -C FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w",
268 "/sbin/ip6tables -C FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w"});
269}
270
Taoyu Li90c13912019-11-26 17:56:54 +0900271TEST(DatapathTest, RemoveIPv6Forwarding) {
272 FakeProcessRunner runner;
273 runner.Capture(true);
274 Datapath datapath(&runner);
275 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
276 runner.VerifyRuns(
277 {"/sbin/ip6tables -D FORWARD -i eth0 -o arc_eth0 -j ACCEPT -w",
278 "/sbin/ip6tables -D FORWARD -i arc_eth0 -o eth0 -j ACCEPT -w"});
279}
280
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900281TEST(DatapathTest, AddIPv6HostRoute) {
282 FakeProcessRunner runner;
283 runner.Capture(true);
284 Datapath datapath(&runner);
285 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
286 runner.VerifyRuns(
287 {"/bin/ip -6 route replace 2001:da8:e00::1234/128 dev eth0"});
288}
289
Garrick Evansf0ab7132019-06-18 14:50:42 +0900290} // namespace arc_networkd