blob: 14a9f057fabe9f8fbde1f021e4d6c50074434d61 [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
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900108TEST(DatapathTest, AddTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900109 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900110 MockFirewall firewall;
111 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900112 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900113 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900114 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900115 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900116 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900117 std::vector<ioctl_req_t> expected = {
118 TUNSETIFF, TUNSETPERSIST, SIOCSIFADDR, SIOCSIFNETMASK,
119 SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900120 EXPECT_EQ(ioctl_reqs, expected);
121 ioctl_reqs.clear();
122}
123
124TEST(DatapathTest, AddTAPWithOwner) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900125 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900126 MockFirewall firewall;
127 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900128 MacAddress mac = {1, 2, 3, 4, 5, 6};
Qijiang Fane90b8792020-03-09 16:15:41 +0900129 Subnet subnet(Ipv4Addr(100, 115, 92, 4), 30, base::DoNothing());
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900130 auto addr = subnet.AllocateAtOffset(0);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900131 auto ifname = datapath.AddTAP("foo0", &mac, addr.get(), "root");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900132 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900133 std::vector<ioctl_req_t> expected = {
134 TUNSETIFF, TUNSETPERSIST, TUNSETOWNER, SIOCSIFADDR,
135 SIOCSIFNETMASK, SIOCSIFHWADDR, SIOCGIFFLAGS, SIOCSIFFLAGS};
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900136 EXPECT_EQ(ioctl_reqs, expected);
137 ioctl_reqs.clear();
138}
139
Garrick Evans621ed262019-11-13 12:28:43 +0900140TEST(DatapathTest, AddTAPNoAddrs) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900141 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900142 MockFirewall firewall;
143 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900144 auto ifname = datapath.AddTAP("foo0", nullptr, nullptr, "");
Garrick Evans621ed262019-11-13 12:28:43 +0900145 EXPECT_EQ(ifname, "foo0");
Hugo Benichie8758b52020-04-03 14:49:01 +0900146 std::vector<ioctl_req_t> expected = {TUNSETIFF, TUNSETPERSIST, SIOCGIFFLAGS,
147 SIOCSIFFLAGS};
Garrick Evans621ed262019-11-13 12:28:43 +0900148 EXPECT_EQ(ioctl_reqs, expected);
149 ioctl_reqs.clear();
150}
151
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900152TEST(DatapathTest, RemoveTAP) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900153 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900154 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900155 EXPECT_CALL(runner, ip(StrEq("tuntap"), StrEq("del"),
156 ElementsAre("foo0", "mode", "tap"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900157 Datapath datapath(&runner, &firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900158 datapath.RemoveTAP("foo0");
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900159}
Garrick Evansf0ab7132019-06-18 14:50:42 +0900160
Hugo Benichi33860d72020-07-09 16:34:01 +0900161TEST(DatapathTest, NetnsAttachName) {
162 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900163 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900164 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), false));
165 EXPECT_CALL(runner, ip_netns_attach(StrEq("netns_foo"), 1234, true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900166 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900167 EXPECT_TRUE(datapath.NetnsAttachName("netns_foo", 1234));
168}
169
170TEST(DatapathTest, NetnsDeleteName) {
171 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900172 MockFirewall firewall;
Hugo Benichi33860d72020-07-09 16:34:01 +0900173 EXPECT_CALL(runner, ip_netns_delete(StrEq("netns_foo"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900174 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900175 EXPECT_TRUE(datapath.NetnsDeleteName("netns_foo"));
176}
177
Garrick Evans8a949dc2019-07-18 16:17:53 +0900178TEST(DatapathTest, AddBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900179 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900180 MockFirewall firewall;
181 Datapath datapath(&runner, &firewall);
Garrick Evans8e8e3472020-01-23 14:03:50 +0900182 EXPECT_CALL(runner, brctl(StrEq("addbr"), ElementsAre("br"), true));
Garrick Evans6f4fa3a2020-02-10 16:15:09 +0900183 EXPECT_CALL(
184 runner,
185 ip(StrEq("addr"), StrEq("add"),
186 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "br"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900187 EXPECT_CALL(runner,
188 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "up"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900189 EXPECT_CALL(runner, iptables(StrEq("mangle"),
190 ElementsAre("-A", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900191 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900192 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900193 datapath.AddBridge("br", Ipv4Addr(1, 1, 1, 1), 30);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900194}
195
Hugo Benichi76675592020-04-08 14:29:57 +0900196TEST(DatapathTest, ConnectVethPair) {
197 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900198 MockFirewall firewall;
Hugo Benichi76675592020-04-08 14:29:57 +0900199 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
200 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900201 "peer_foo", "netns", "netns_foo"),
Hugo Benichi76675592020-04-08 14:29:57 +0900202 true));
203 EXPECT_CALL(runner, ip(StrEq("addr"), StrEq("add"),
204 ElementsAre("100.115.92.169/30", "brd",
205 "100.115.92.171", "dev", "peer_foo"),
206 true))
207 .WillOnce(Return(0));
208 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
209 ElementsAre("dev", "peer_foo", "up", "addr",
210 "01:02:03:04:05:06", "multicast", "on"),
211 true))
212 .WillOnce(Return(0));
Hugo Benichi76675592020-04-08 14:29:57 +0900213 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
214 ElementsAre("veth_foo", "up"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900215 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900216 EXPECT_TRUE(datapath.ConnectVethPair(kTestPID, "netns_foo", "veth_foo",
217 "peer_foo", {1, 2, 3, 4, 5, 6},
Hugo Benichi76675592020-04-08 14:29:57 +0900218 Ipv4Addr(100, 115, 92, 169), 30, true));
219}
220
Garrick Evans2470caa2020-03-04 14:15:41 +0900221TEST(DatapathTest, AddVirtualInterfacePair) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900222 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900223 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900224 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("add"),
225 ElementsAre("veth_foo", "type", "veth", "peer", "name",
Hugo Benichi33860d72020-07-09 16:34:01 +0900226 "peer_foo", "netns", "netns_foo"),
Garrick Evans8e8e3472020-01-23 14:03:50 +0900227 true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900228 Datapath datapath(&runner, &firewall);
Hugo Benichi33860d72020-07-09 16:34:01 +0900229 EXPECT_TRUE(
230 datapath.AddVirtualInterfacePair("netns_foo", "veth_foo", "peer_foo"));
Garrick Evans2470caa2020-03-04 14:15:41 +0900231}
232
233TEST(DatapathTest, ToggleInterface) {
234 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900235 MockFirewall firewall;
Garrick Evans2470caa2020-03-04 14:15:41 +0900236 EXPECT_CALL(runner,
237 ip(StrEq("link"), StrEq("set"), ElementsAre("foo", "up"), true));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900238 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
Garrick Evans2470caa2020-03-04 14:15:41 +0900239 ElementsAre("bar", "down"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900240 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900241 EXPECT_TRUE(datapath.ToggleInterface("foo", true));
242 EXPECT_TRUE(datapath.ToggleInterface("bar", false));
243}
244
245TEST(DatapathTest, ConfigureInterface) {
246 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900247 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900248 EXPECT_CALL(
249 runner,
Garrick Evans2470caa2020-03-04 14:15:41 +0900250 ip(StrEq("addr"), StrEq("add"),
251 ElementsAre("1.1.1.1/30", "brd", "1.1.1.3", "dev", "foo"), true))
252 .WillOnce(Return(0));
253 EXPECT_CALL(runner, ip(StrEq("link"), StrEq("set"),
254 ElementsAre("dev", "foo", "up", "addr",
255 "02:02:02:02:02:02", "multicast", "on"),
256 true))
257 .WillOnce(Return(0));
258
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900259 Datapath datapath(&runner, &firewall);
Garrick Evans2470caa2020-03-04 14:15:41 +0900260 MacAddress mac_addr = {2, 2, 2, 2, 2, 2};
261 EXPECT_TRUE(datapath.ConfigureInterface("foo", mac_addr, Ipv4Addr(1, 1, 1, 1),
262 30, true, true));
Garrick Evans54861622019-07-19 09:05:09 +0900263}
264
265TEST(DatapathTest, RemoveInterface) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900266 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900267 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900268 EXPECT_CALL(runner,
269 ip(StrEq("link"), StrEq("delete"), ElementsAre("foo"), false));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900270 Datapath datapath(&runner, &firewall);
Garrick Evans54861622019-07-19 09:05:09 +0900271 datapath.RemoveInterface("foo");
Garrick Evans54861622019-07-19 09:05:09 +0900272}
273
Garrick Evans8a949dc2019-07-18 16:17:53 +0900274TEST(DatapathTest, RemoveBridge) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900275 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900276 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900277 EXPECT_CALL(runner, iptables(StrEq("mangle"),
278 ElementsAre("-D", "PREROUTING", "-i", "br", "-j",
Hugo Benichi6c445322020-08-12 16:46:19 +0900279 "MARK", "--set-mark", "1/1", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900280 true, nullptr));
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900281 EXPECT_CALL(runner,
282 ip(StrEq("link"), StrEq("set"), ElementsAre("br", "down"), true));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900283 EXPECT_CALL(runner, brctl(StrEq("delbr"), ElementsAre("br"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900284 Datapath datapath(&runner, &firewall);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900285 datapath.RemoveBridge("br");
Garrick Evans8a949dc2019-07-18 16:17:53 +0900286}
287
Hugo Benichi8d622b52020-08-13 15:24:12 +0900288TEST(DatapathTest, StartRoutingDevice_Arc) {
289 MockProcessRunner runner;
290 MockFirewall firewall;
291 EXPECT_CALL(runner, iptables(StrEq("nat"),
292 ElementsAre("-A", "PREROUTING", "-i", "eth0",
293 "-m", "socket", "--nowildcard", "-j",
294 "ACCEPT", "-w"),
295 true, nullptr));
296 EXPECT_CALL(runner, iptables(StrEq("nat"),
297 ElementsAre("-A", "PREROUTING", "-i", "eth0",
298 "-p", "tcp", "-j", "DNAT",
299 "--to-destination", "1.2.3.4", "-w"),
300 true, nullptr));
301 EXPECT_CALL(runner, iptables(StrEq("nat"),
302 ElementsAre("-A", "PREROUTING", "-i", "eth0",
303 "-p", "udp", "-j", "DNAT",
304 "--to-destination", "1.2.3.4", "-w"),
305 true, nullptr));
306 EXPECT_CALL(runner, iptables(StrEq("filter"),
307 ElementsAre("-A", "FORWARD", "-o", "arc_eth0",
308 "-j", "ACCEPT", "-w"),
309 true, nullptr));
310
311 Datapath datapath(&runner, &firewall);
312 datapath.StartRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
313 TrafficSource::ARC);
314}
315
316TEST(DatapathTest, StartRoutingDevice_CrosVM) {
317 MockProcessRunner runner;
318 MockFirewall firewall;
319 EXPECT_CALL(runner, iptables(StrEq("filter"),
320 ElementsAre("-A", "FORWARD", "-o", "vmtap0",
321 "-j", "ACCEPT", "-w"),
322 true, nullptr));
323
324 Datapath datapath(&runner, &firewall);
325 datapath.StartRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
326 TrafficSource::CROSVM);
327}
328
329TEST(DatapathTest, StopRoutingDevice_Arc) {
330 MockProcessRunner runner;
331 MockFirewall firewall;
332 EXPECT_CALL(runner, iptables(StrEq("nat"),
333 ElementsAre("-D", "PREROUTING", "-i", "eth0",
334 "-m", "socket", "--nowildcard", "-j",
335 "ACCEPT", "-w"),
336 true, nullptr));
337 EXPECT_CALL(runner, iptables(StrEq("nat"),
338 ElementsAre("-D", "PREROUTING", "-i", "eth0",
339 "-p", "tcp", "-j", "DNAT",
340 "--to-destination", "1.2.3.4", "-w"),
341 true, nullptr));
342 EXPECT_CALL(runner, iptables(StrEq("nat"),
343 ElementsAre("-D", "PREROUTING", "-i", "eth0",
344 "-p", "udp", "-j", "DNAT",
345 "--to-destination", "1.2.3.4", "-w"),
346 true, nullptr));
347 EXPECT_CALL(runner, iptables(StrEq("filter"),
348 ElementsAre("-D", "FORWARD", "-o", "arc_eth0",
349 "-j", "ACCEPT", "-w"),
350 true, nullptr));
351
352 Datapath datapath(&runner, &firewall);
353 datapath.StopRoutingDevice("eth0", "arc_eth0", Ipv4Addr(1, 2, 3, 4),
354 TrafficSource::ARC);
355}
356
357TEST(DatapathTest, StopRoutingDevice_CrosVM) {
358 MockProcessRunner runner;
359 MockFirewall firewall;
360 EXPECT_CALL(runner, iptables(StrEq("filter"),
361 ElementsAre("-D", "FORWARD", "-o", "vmtap0",
362 "-j", "ACCEPT", "-w"),
363 true, nullptr));
364
365 Datapath datapath(&runner, &firewall);
366 datapath.StopRoutingDevice("", "vmtap0", Ipv4Addr(1, 2, 3, 4),
367 TrafficSource::CROSVM);
368}
369
Garrick Evansf0ab7132019-06-18 14:50:42 +0900370TEST(DatapathTest, AddInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900371 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900372 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900373 EXPECT_CALL(runner, iptables(StrEq("nat"),
374 ElementsAre("-A", "PREROUTING", "-i", "eth0",
375 "-m", "socket", "--nowildcard", "-j",
376 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900377 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900378 EXPECT_CALL(runner, iptables(StrEq("nat"),
379 ElementsAre("-A", "PREROUTING", "-i", "eth0",
380 "-p", "tcp", "-j", "DNAT",
381 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900382 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900383 EXPECT_CALL(runner, iptables(StrEq("nat"),
384 ElementsAre("-A", "PREROUTING", "-i", "eth0",
385 "-p", "udp", "-j", "DNAT",
386 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900387 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900388 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900389 datapath.AddInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900390}
391
392TEST(DatapathTest, RemoveInboundIPv4DNAT) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900393 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900394 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900395 EXPECT_CALL(runner, iptables(StrEq("nat"),
396 ElementsAre("-D", "PREROUTING", "-i", "eth0",
397 "-m", "socket", "--nowildcard", "-j",
398 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900399 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900400 EXPECT_CALL(runner, iptables(StrEq("nat"),
401 ElementsAre("-D", "PREROUTING", "-i", "eth0",
402 "-p", "tcp", "-j", "DNAT",
403 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900404 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900405 EXPECT_CALL(runner, iptables(StrEq("nat"),
406 ElementsAre("-D", "PREROUTING", "-i", "eth0",
407 "-p", "udp", "-j", "DNAT",
408 "--to-destination", "1.2.3.4", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900409 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900410 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900411 datapath.RemoveInboundIPv4DNAT("eth0", "1.2.3.4");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900412}
413
414TEST(DatapathTest, AddOutboundIPv4) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900415 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900416 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900417 EXPECT_CALL(runner, iptables(StrEq("filter"),
418 ElementsAre("-A", "FORWARD", "-o", "eth0", "-j",
419 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900420 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900421 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900422 datapath.AddOutboundIPv4("eth0");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900423}
424
425TEST(DatapathTest, RemoveInboundIPv4) {
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, iptables(StrEq("filter"),
429 ElementsAre("-D", "FORWARD", "-o", "eth0", "-j",
430 "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900431 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900432 Datapath datapath(&runner, &firewall);
Garrick Evansf0ab7132019-06-18 14:50:42 +0900433 datapath.RemoveOutboundIPv4("eth0");
Garrick Evansf0ab7132019-06-18 14:50:42 +0900434}
435
Garrick Evans664a82f2019-12-17 12:18:05 +0900436TEST(DatapathTest, MaskInterfaceFlags) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900437 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900438 MockFirewall firewall;
439 Datapath datapath(&runner, &firewall, ioctl_req_cap);
Garrick Evans664a82f2019-12-17 12:18:05 +0900440 bool result = datapath.MaskInterfaceFlags("foo0", IFF_DEBUG);
Taoyu Li90c13912019-11-26 17:56:54 +0900441 EXPECT_TRUE(result);
Hugo Benichie8758b52020-04-03 14:49:01 +0900442 std::vector<ioctl_req_t> expected = {SIOCGIFFLAGS, SIOCSIFFLAGS};
Taoyu Li90c13912019-11-26 17:56:54 +0900443 EXPECT_EQ(ioctl_reqs, expected);
444 ioctl_reqs.clear();
445}
446
447TEST(DatapathTest, AddIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900448 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900449 MockFirewall firewall;
Taoyu Lica49c832019-12-06 17:56:43 +0900450 // Return 1 on iptables -C to simulate rule not existing case
Garrick Evans8e8e3472020-01-23 14:03:50 +0900451 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
452 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
453 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900454 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +0900455 .WillOnce(Return(1));
456 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
457 ElementsAre("-A", "FORWARD", "-i", "eth0", "-o",
458 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900459 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900460 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
461 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
462 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900463 false, nullptr))
Garrick Evans8e8e3472020-01-23 14:03:50 +0900464 .WillOnce(Return(1));
465 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
466 ElementsAre("-A", "FORWARD", "-i", "arc_eth0",
467 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900468 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900469 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +0900470 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +0900471}
472
Taoyu Lica49c832019-12-06 17:56:43 +0900473TEST(DatapathTest, AddIPv6ForwardingRuleExists) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900474 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900475 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900476 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
477 ElementsAre("-C", "FORWARD", "-i", "eth0", "-o",
478 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900479 false, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900480 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
481 ElementsAre("-C", "FORWARD", "-i", "arc_eth0",
482 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900483 false, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900484 Datapath datapath(&runner, &firewall);
Taoyu Lica49c832019-12-06 17:56:43 +0900485 datapath.AddIPv6Forwarding("eth0", "arc_eth0");
Taoyu Lica49c832019-12-06 17:56:43 +0900486}
487
Taoyu Li90c13912019-11-26 17:56:54 +0900488TEST(DatapathTest, RemoveIPv6Forwarding) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900489 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900490 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900491 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
492 ElementsAre("-D", "FORWARD", "-i", "eth0", "-o",
493 "arc_eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900494 true, nullptr));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900495 EXPECT_CALL(runner, ip6tables(StrEq("filter"),
496 ElementsAre("-D", "FORWARD", "-i", "arc_eth0",
497 "-o", "eth0", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900498 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900499 Datapath datapath(&runner, &firewall);
Taoyu Li90c13912019-11-26 17:56:54 +0900500 datapath.RemoveIPv6Forwarding("eth0", "arc_eth0");
Taoyu Li90c13912019-11-26 17:56:54 +0900501}
502
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900503TEST(DatapathTest, AddIPv6HostRoute) {
Garrick Evans8e8e3472020-01-23 14:03:50 +0900504 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900505 MockFirewall firewall;
Garrick Evans8e8e3472020-01-23 14:03:50 +0900506 EXPECT_CALL(runner,
507 ip6(StrEq("route"), StrEq("replace"),
508 ElementsAre("2001:da8:e00::1234/128", "dev", "eth0"), true));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900509 Datapath datapath(&runner, &firewall);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900510 datapath.AddIPv6HostRoute("eth0", "2001:da8:e00::1234", 128);
Taoyu Lieb6cc8f2019-12-09 15:53:04 +0900511}
512
Hugo Benichie8758b52020-04-03 14:49:01 +0900513TEST(DatapathTest, AddIPv4Route) {
514 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900515 MockFirewall firewall;
516 Datapath datapath(&runner, &firewall, (ioctl_t)ioctl_rtentry_cap);
Hugo Benichie8758b52020-04-03 14:49:01 +0900517
518 datapath.AddIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
519 Ipv4Addr(255, 255, 255, 0));
520 datapath.DeleteIPv4Route(Ipv4Addr(192, 168, 1, 1), Ipv4Addr(100, 115, 93, 0),
521 Ipv4Addr(255, 255, 255, 0));
522 datapath.AddIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
523 Ipv4Addr(255, 255, 255, 252));
524 datapath.DeleteIPv4Route("eth0", Ipv4Addr(100, 115, 92, 8),
525 Ipv4Addr(255, 255, 255, 252));
526
527 std::vector<ioctl_req_t> expected_reqs = {SIOCADDRT, SIOCDELRT, SIOCADDRT,
528 SIOCDELRT};
529 EXPECT_EQ(expected_reqs, ioctl_reqs);
530 ioctl_reqs.clear();
531
532 std::string route1 =
533 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.93.0}, rt_genmask: "
534 "{family: AF_INET, port: 0, addr: 255.255.255.0}, rt_gateway: {family: "
535 "AF_INET, port: 0, addr: 192.168.1.1}, rt_dev: null, rt_flags: RTF_UP | "
536 "RTF_GATEWAY}";
537 std::string route2 =
538 "{rt_dst: {family: AF_INET, port: 0, addr: 100.115.92.8}, rt_genmask: "
539 "{family: AF_INET, port: 0, addr: 255.255.255.252}, rt_gateway: {unset}, "
540 "rt_dev: eth0, rt_flags: RTF_UP | RTF_GATEWAY}";
541 std::vector<std::string> captured_routes;
542 for (const auto& route : ioctl_rtentry_args) {
543 std::ostringstream stream;
544 stream << route.second;
545 captured_routes.emplace_back(stream.str());
546 }
547 ioctl_rtentry_args.clear();
548 EXPECT_EQ(route1, captured_routes[0]);
549 EXPECT_EQ(route1, captured_routes[1]);
550 EXPECT_EQ(route2, captured_routes[2]);
551 EXPECT_EQ(route2, captured_routes[3]);
552}
553
Garrick Evansd291af62020-05-25 10:39:06 +0900554TEST(DatapathTest, AddSNATMarkRules) {
555 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900556 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +0900557 EXPECT_CALL(
558 runner,
559 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +0900560 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +0900561 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900562 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +0900563 EXPECT_CALL(runner,
564 iptables(StrEq("filter"),
565 ElementsAre("-A", "FORWARD", "-m", "mark", "--mark",
566 "1/1", "-j", "ACCEPT", "-w"),
567 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +0900568 EXPECT_CALL(runner,
569 iptables(StrEq("nat"),
570 ElementsAre("-A", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +0900571 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900572 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900573 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +0900574 datapath.AddSNATMarkRules();
575}
576
577TEST(DatapathTest, RemoveSNATMarkRules) {
578 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900579 MockFirewall firewall;
Taoyu Li79871c92020-07-02 16:09:39 +0900580 EXPECT_CALL(
581 runner,
582 iptables(StrEq("filter"),
Hugo Benichi6c445322020-08-12 16:46:19 +0900583 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark", "1/1", "-m",
Taoyu Li79871c92020-07-02 16:09:39 +0900584 "state", "--state", "INVALID", "-j", "DROP", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900585 true, nullptr));
Hugo Benichi6c445322020-08-12 16:46:19 +0900586 EXPECT_CALL(runner,
587 iptables(StrEq("filter"),
588 ElementsAre("-D", "FORWARD", "-m", "mark", "--mark",
589 "1/1", "-j", "ACCEPT", "-w"),
590 true, nullptr));
Garrick Evansd291af62020-05-25 10:39:06 +0900591 EXPECT_CALL(runner,
592 iptables(StrEq("nat"),
593 ElementsAre("-D", "POSTROUTING", "-m", "mark", "--mark",
Hugo Benichi6c445322020-08-12 16:46:19 +0900594 "1/1", "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900595 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900596 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +0900597 datapath.RemoveSNATMarkRules();
598}
599
600TEST(DatapathTest, AddForwardEstablishedRule) {
601 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900602 MockFirewall firewall;
Garrick Evansd291af62020-05-25 10:39:06 +0900603 EXPECT_CALL(runner,
604 iptables(StrEq("filter"),
605 ElementsAre("-A", "FORWARD", "-m", "state", "--state",
606 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900607 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900608 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +0900609 datapath.AddForwardEstablishedRule();
610}
611
612TEST(DatapathTest, RemoveForwardEstablishedRule) {
613 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900614 MockFirewall firewall;
Garrick Evansd291af62020-05-25 10:39:06 +0900615 EXPECT_CALL(runner,
616 iptables(StrEq("filter"),
617 ElementsAre("-D", "FORWARD", "-m", "state", "--state",
618 "ESTABLISHED,RELATED", "-j", "ACCEPT", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900619 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900620 Datapath datapath(&runner, &firewall);
Garrick Evansd291af62020-05-25 10:39:06 +0900621 datapath.RemoveForwardEstablishedRule();
622}
623
Garrick Evansff6e37f2020-05-25 10:54:47 +0900624TEST(DatapathTest, AddInterfaceSNAT) {
625 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900626 MockFirewall firewall;
Garrick Evansff6e37f2020-05-25 10:54:47 +0900627 EXPECT_CALL(runner, iptables(StrEq("nat"),
628 ElementsAre("-A", "POSTROUTING", "-o", "wwan+",
629 "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900630 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900631 Datapath datapath(&runner, &firewall);
Garrick Evansff6e37f2020-05-25 10:54:47 +0900632 datapath.AddInterfaceSNAT("wwan+");
633}
634
635TEST(DatapathTest, RemoveInterfaceSNAT) {
636 MockProcessRunner runner;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900637 MockFirewall firewall;
Garrick Evansff6e37f2020-05-25 10:54:47 +0900638 EXPECT_CALL(runner, iptables(StrEq("nat"),
639 ElementsAre("-D", "POSTROUTING", "-o", "wwan+",
640 "-j", "MASQUERADE", "-w"),
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900641 true, nullptr));
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900642 Datapath datapath(&runner, &firewall);
Garrick Evansff6e37f2020-05-25 10:54:47 +0900643 datapath.RemoveInterfaceSNAT("wwan+");
644}
645
Garrick Evans2f581a02020-05-11 10:43:35 +0900646TEST(DatapathTest, ArcVethHostName) {
647 EXPECT_EQ("vetheth0", ArcVethHostName("eth0"));
648 EXPECT_EQ("vethrmnet0", ArcVethHostName("rmnet0"));
649 EXPECT_EQ("vethrmnet_data0", ArcVethHostName("rmnet_data0"));
650 EXPECT_EQ("vethifnamsiz_i0", ArcVethHostName("ifnamsiz_ifnam0"));
651 auto ifname = ArcVethHostName("exceeds_ifnamesiz_checkanyway");
652 EXPECT_EQ("vethexceeds_ify", ifname);
653 EXPECT_LT(ifname.length(), IFNAMSIZ);
654}
655
Garrick Evans8a067562020-05-11 12:47:30 +0900656TEST(DatapathTest, ArcBridgeName) {
657 EXPECT_EQ("arc_eth0", ArcBridgeName("eth0"));
658 EXPECT_EQ("arc_rmnet0", ArcBridgeName("rmnet0"));
659 EXPECT_EQ("arc_rmnet_data0", ArcBridgeName("rmnet_data0"));
660 EXPECT_EQ("arc_ifnamsiz_i0", ArcBridgeName("ifnamsiz_ifnam0"));
661 auto ifname = ArcBridgeName("exceeds_ifnamesiz_checkanyway");
662 EXPECT_EQ("arc_exceeds_ify", ifname);
663 EXPECT_LT(ifname.length(), IFNAMSIZ);
664}
665
Garrick Evans3388a032020-03-24 11:25:55 +0900666} // namespace patchpanel