blob: e8a267d2e68310b59b2cb99bacc90a1699d7b510 [file] [log] [blame]
Garrick Evans54861622019-07-19 09:05:09 +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/arc_service.h"
Garrick Evans54861622019-07-19 09:05:09 +09006
Garrick Evanse94b6de2020-02-20 09:19:13 +09007#include <net/if.h>
8
Garrick Evans54861622019-07-19 09:05:09 +09009#include <utility>
10#include <vector>
11
12#include <base/bind.h>
13
14#include <gmock/gmock.h>
15#include <gtest/gtest.h>
16
Garrick Evans3388a032020-03-24 11:25:55 +090017#include "patchpanel/address_manager.h"
18#include "patchpanel/fake_process_runner.h"
19#include "patchpanel/fake_shill_client.h"
20#include "patchpanel/mock_datapath.h"
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090021#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090022#include "patchpanel/net_util.h"
Garrick Evans54861622019-07-19 09:05:09 +090023
24using testing::_;
Garrick Evanse94b6de2020-02-20 09:19:13 +090025using testing::AnyNumber;
Garrick Evansc7071122020-04-17 12:31:57 +090026using testing::Eq;
27using testing::Pointee;
Garrick Evans54861622019-07-19 09:05:09 +090028using testing::Return;
Garrick Evansb4eb3892019-11-13 12:07:07 +090029using testing::ReturnRef;
Garrick Evans54861622019-07-19 09:05:09 +090030using testing::StrEq;
Garrick Evans02e6e872020-11-30 11:53:13 +090031using testing::UnorderedElementsAre;
Garrick Evans54861622019-07-19 09:05:09 +090032
Garrick Evans3388a032020-03-24 11:25:55 +090033namespace patchpanel {
Garrick Evans54861622019-07-19 09:05:09 +090034namespace {
Garrick Evansb4eb3892019-11-13 12:07:07 +090035constexpr pid_t kTestPID = -2;
Garrick Evansb4eb3892019-11-13 12:07:07 +090036constexpr uint32_t kTestCID = 2;
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090037constexpr uint32_t kArcHostIP = Ipv4Addr(100, 115, 92, 1);
38constexpr uint32_t kArcGuestIP = Ipv4Addr(100, 115, 92, 2);
Hugo Benichiad1bdd92020-06-12 13:48:37 +090039constexpr uint32_t kFirstEthHostIP = Ipv4Addr(100, 115, 92, 5);
40constexpr uint32_t kFirstEthGuestIP = Ipv4Addr(100, 115, 92, 6);
Garrick Evans86c7d9c2020-03-17 09:25:48 +090041constexpr uint32_t kSecondEthHostIP = Ipv4Addr(100, 115, 92, 9);
42constexpr uint32_t kFirstWifiHostIP = Ipv4Addr(100, 115, 92, 13);
43constexpr uint32_t kSecondWifiHostIP = Ipv4Addr(100, 115, 92, 17);
44constexpr uint32_t kFirstCellHostIP = Ipv4Addr(100, 115, 92, 21);
Garrick Evansc7071122020-04-17 12:31:57 +090045constexpr MacAddress kArcVmArc0MacAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x01};
Garrick Evans54861622019-07-19 09:05:09 +090046
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090047class MockTrafficForwarder : public TrafficForwarder {
48 public:
49 MockTrafficForwarder() = default;
50 ~MockTrafficForwarder() = default;
51
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +090052 MOCK_METHOD4(StartForwarding,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090053 void(const std::string& ifname_physical,
54 const std::string& ifname_virtual,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090055 bool ipv6,
56 bool multicast));
57
58 MOCK_METHOD4(StopForwarding,
59 void(const std::string& ifname_physical,
60 const std::string& ifname_virtual,
61 bool ipv6,
62 bool multicast));
63};
64
Garrick Evans54861622019-07-19 09:05:09 +090065} // namespace
66
67class ArcServiceTest : public testing::Test {
68 public:
Garrick Evans4ee5ce22020-03-18 07:05:17 +090069 ArcServiceTest() : testing::Test() {}
Garrick Evans54861622019-07-19 09:05:09 +090070
71 protected:
72 void SetUp() override {
Taoyu Li179dcc62019-10-17 11:21:08 +090073 runner_ = std::make_unique<FakeProcessRunner>();
Garrick Evans54861622019-07-19 09:05:09 +090074 runner_->Capture(false);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090075 datapath_ = std::make_unique<MockDatapath>(runner_.get(), &firewall_);
Garrick Evans69b85872020-02-04 11:40:26 +090076 shill_client_ = shill_helper_.Client();
Garrick Evans4ee5ce22020-03-18 07:05:17 +090077 addr_mgr_ = std::make_unique<AddressManager>();
Garrick Evans54861622019-07-19 09:05:09 +090078 }
79
Hugo Benichiad1bdd92020-06-12 13:48:37 +090080 std::unique_ptr<ArcService> NewService(GuestMessage::GuestType guest) {
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090081 return std::make_unique<ArcService>(shill_client_.get(), datapath_.get(),
Hugo Benichiad1bdd92020-06-12 13:48:37 +090082 addr_mgr_.get(), &forwarder_, guest);
Garrick Evans54861622019-07-19 09:05:09 +090083 }
84
Garrick Evans69b85872020-02-04 11:40:26 +090085 FakeShillClientHelper shill_helper_;
86 std::unique_ptr<ShillClient> shill_client_;
Garrick Evans4ee5ce22020-03-18 07:05:17 +090087 std::unique_ptr<AddressManager> addr_mgr_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090088 MockTrafficForwarder forwarder_;
Taoyu Li179dcc62019-10-17 11:21:08 +090089 std::unique_ptr<MockDatapath> datapath_;
90 std::unique_ptr<FakeProcessRunner> runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090091 MockFirewall firewall_;
Garrick Evans54861622019-07-19 09:05:09 +090092};
93
Hugo Benichiad1bdd92020-06-12 13:48:37 +090094TEST_F(ArcServiceTest, NotStarted_AddDevice) {
95 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +090096 EXPECT_CALL(*datapath_,
97 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
98 .Times(0);
Garrick Evans54861622019-07-19 09:05:09 +090099
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900100 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900101 svc->OnDevicesChanged({"eth0"}, {});
102 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
103 EXPECT_FALSE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900104}
105
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900106TEST_F(ArcServiceTest, NotStarted_AddRemoveDevice) {
107 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900108 EXPECT_CALL(*datapath_,
109 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
110 .Times(0);
111 EXPECT_CALL(*datapath_,
112 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
113 .Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900114 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900115
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900116 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900117 svc->OnDevicesChanged({"eth0"}, {});
118 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900119 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
Hugo Benichif0f10c72020-07-09 10:42:45 +0900120 EXPECT_TRUE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900121}
122
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900123TEST_F(ArcServiceTest, VerifyAddrConfigs) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900124 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
125 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900126 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
127 .WillOnce(Return(true));
128 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900129 .WillOnce(Return(true));
130 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
131 .WillOnce(Return(true));
132 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
133 .WillOnce(Return(true));
134 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
135 .WillOnce(Return(true));
136 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
137 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900138 EXPECT_CALL(*datapath_,
139 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900140 .WillRepeatedly(Return(true));
141 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900142
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900143 auto svc = NewService(GuestMessage::ARC);
144 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900145 svc->OnDevicesChanged({"eth0", "eth1", "wlan0", "wlan1", "wwan0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900146}
147
148TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900149 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
150 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900151 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
152 .WillOnce(Return(true));
153 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900154 .Times(2)
155 .WillRepeatedly(Return(true));
156 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
157 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900158 EXPECT_CALL(*datapath_,
159 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900160 .WillRepeatedly(Return(true));
161 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900162
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900163 auto svc = NewService(GuestMessage::ARC);
164 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900165 svc->OnDevicesChanged({"wlan0"}, {});
166 svc->OnDevicesChanged({"eth0"}, {});
167 svc->OnDevicesChanged({}, {"eth0"});
168 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900169}
170
Garrick Evansc7071122020-04-17 12:31:57 +0900171TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
172 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
173 .WillRepeatedly(Return("vmtap"));
174 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
175 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
176
177 auto svc = NewService(GuestMessage::ARC_VM);
178 svc->Start(kTestCID);
179 auto configs = svc->GetDeviceConfigs();
180 EXPECT_EQ(configs.size(), 6);
181 auto mac_addr = kArcVmArc0MacAddr;
182 for (const auto* config : configs) {
183 EXPECT_EQ(config->mac_addr(), mac_addr);
184 mac_addr[5]++;
185 }
186}
187
Garrick Evansb4eb3892019-11-13 12:07:07 +0900188// ContainerImpl
189
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900190TEST_F(ArcServiceTest, ContainerImpl_Start) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900191 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
192 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900193 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900194 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
195 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900196 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900197 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900198 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900199 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
200 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900201 EXPECT_CALL(forwarder_, StartForwarding(_, _, _, _)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900202
203 auto svc = NewService(GuestMessage::ARC);
204 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900205}
206
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900207TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900208 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
209 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900210 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900211 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
212 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900213 .WillOnce(Return(false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900214 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30)).Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900215 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900216
217 auto svc = NewService(GuestMessage::ARC);
218 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900219}
220
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900221TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900222 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
223 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900224 EXPECT_CALL(*datapath_,
225 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
226 StrEq("arc0"), _, kArcGuestIP, 30, false))
227 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900228 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
229 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900230 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
231 .WillOnce(Return(false));
232
233 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
234 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
235
236 auto svc = NewService(GuestMessage::ARC);
237 svc->Start(kTestPID);
238}
239
240TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900241 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
242 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900243 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900244 EXPECT_CALL(*datapath_,
245 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
246 StrEq("arc0"), _, kArcGuestIP, 30, false))
247 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900248 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
249 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900250 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
251 .WillOnce(Return(true));
252 // Expectations for eth0 setup.
Garrick Evansb4eb3892019-11-13 12:07:07 +0900253 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900254 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
255 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900256 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900257 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2470caa2020-03-04 14:15:41 +0900258 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900259 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900260 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900261 EXPECT_CALL(forwarder_,
262 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900263 EXPECT_CALL(*datapath_,
264 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
265 kFirstEthGuestIP, TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900266
267 auto svc = NewService(GuestMessage::ARC);
268 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900269 svc->OnDevicesChanged({"eth0"}, {});
270}
271
Garrick Evans02e6e872020-11-30 11:53:13 +0900272TEST_F(ArcServiceTest, ContainerImpl_ScanDevices) {
273 EXPECT_CALL(*datapath_, NetnsAttachName(_, _)).WillRepeatedly(Return(true));
274 EXPECT_CALL(*datapath_, ConnectVethPair(_, _, _, _, _, _, _, _))
275 .WillRepeatedly(Return(true));
276 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
277 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
278
279 auto svc = NewService(GuestMessage::ARC);
280 svc->Start(kTestPID);
281 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
282
283 std::vector<std::string> devs;
284 svc->ScanDevices(base::BindRepeating(
285 [](std::vector<std::string>* list, const Device& device) {
286 list->push_back(device.host_ifname());
287 },
288 &devs));
289
290 EXPECT_EQ(devs.size(), 2);
291 EXPECT_THAT(devs,
292 UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0")));
293}
294
Hugo Benichif0f10c72020-07-09 10:42:45 +0900295TEST_F(ArcServiceTest, ContainerImpl_StartAfterDevice) {
296 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
297 .WillOnce(Return(true));
298 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900299 EXPECT_CALL(*datapath_,
300 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
301 StrEq("arc0"), _, kArcGuestIP, 30, false))
302 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900303 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
304 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900305 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
306 .WillOnce(Return(true));
307 // Expectations for eth0 setup.
Hugo Benichif0f10c72020-07-09 10:42:45 +0900308 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900309 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
310 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900311 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900312 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900313 .WillOnce(Return(true));
314 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
315 .WillOnce(Return(true));
316 EXPECT_CALL(forwarder_,
317 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900318 EXPECT_CALL(*datapath_,
319 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
320 kFirstEthGuestIP, TrafficSource::ARC));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900321
322 auto svc = NewService(GuestMessage::ARC);
323 svc->OnDevicesChanged({"eth0"}, {});
324 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900325}
326
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900327TEST_F(ArcServiceTest, ContainerImpl_Stop) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900328 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
329 .WillOnce(Return(true));
330 EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
331 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900332 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900333 EXPECT_CALL(*datapath_,
334 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
335 StrEq("arc0"), _, kArcGuestIP, 30, false))
336 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900337 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
338 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900339 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
340 .WillOnce(Return(true));
341 // Expectations for arc0 teardown.
342 EXPECT_CALL(*datapath_,
343 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
344 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900345 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900346 EXPECT_CALL(forwarder_, StopForwarding(_, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900347
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900348 auto svc = NewService(GuestMessage::ARC);
349 svc->Start(kTestPID);
350 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900351}
352
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900353TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900354 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
355 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900356 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900357 EXPECT_CALL(*datapath_,
358 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
359 StrEq("arc0"), _, kArcGuestIP, 30, false))
360 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900361 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
362 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900363 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
364 .WillOnce(Return(true));
365 // Expectations for eth0 setup.
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900366 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900367 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
368 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900369 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900370 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900371 .WillOnce(Return(true));
372 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
373 .WillOnce(Return(true));
374 // Expectations for eth0 teardown.
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900375 EXPECT_CALL(forwarder_,
376 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900377 EXPECT_CALL(*datapath_,
Hugo Benichi8d622b52020-08-13 15:24:12 +0900378 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
379 Ipv4Addr(100, 115, 92, 6), TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900380 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900381
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900382 auto svc = NewService(GuestMessage::ARC);
383 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900384 svc->OnDevicesChanged({"eth0"}, {});
385 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evansb4eb3892019-11-13 12:07:07 +0900386}
387
Garrick Evansb4eb3892019-11-13 12:07:07 +0900388// VM Impl
389
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900390TEST_F(ArcServiceTest, VmImpl_Start) {
391 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900392 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900393 .WillOnce(Return("vmtap0"))
394 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900395 .WillOnce(Return("vmtap2"))
396 .WillOnce(Return("vmtap3"))
397 .WillOnce(Return("vmtap4"))
398 .WillOnce(Return("vmtap5"));
399 // Expectations for "arc0" setup.
400 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900401 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900402 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900403 .WillOnce(Return(true));
404
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900405 auto svc = NewService(GuestMessage::ARC_VM);
406 svc->Start(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900407}
408
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900409TEST_F(ArcServiceTest, VmImpl_StartDevice) {
410 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900411 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900412 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900413 .WillOnce(Return("vmtap1"))
414 .WillOnce(Return("vmtap2"))
415 .WillOnce(Return("vmtap3"))
416 .WillOnce(Return("vmtap4"))
417 .WillOnce(Return("vmtap5"));
418 // Expectations for "arc0" setup.
419 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900420 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900421 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
422 .WillOnce(Return(true));
423 // Expectations for eth0 setup.
424 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900425 .WillOnce(Return(true));
426 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
427 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900428 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
429 Ipv4Addr(100, 115, 92, 6),
430 TrafficSource::ARC));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900431 EXPECT_CALL(forwarder_,
432 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
433
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900434 auto svc = NewService(GuestMessage::ARC_VM);
435 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900436 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900437}
438
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900439TEST_F(ArcServiceTest, VmImpl_StartMultipleDevices) {
440 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900441 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900442 .WillOnce(Return("vmtap0"))
443 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900444 .WillOnce(Return("vmtap2"))
445 .WillOnce(Return("vmtap3"))
446 .WillOnce(Return("vmtap4"))
447 .WillOnce(Return("vmtap5"));
448 // Expectations for "arc0" setup.
449 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900450 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900451 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900452 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900453 // Expectations for eth0 setup.
454 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
455 .WillOnce(Return(true));
456 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
457 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900458 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
459 Ipv4Addr(100, 115, 92, 6),
460 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900461 EXPECT_CALL(forwarder_,
462 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
463 // Expectations for wlan0 setup.
464 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
465 .WillOnce(Return(true));
466 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_wlan0"), StrEq("vmtap3")))
467 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900468 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("wlan0"), StrEq("arc_wlan0"),
469 Ipv4Addr(100, 115, 92, 14),
470 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900471 EXPECT_CALL(forwarder_,
472 StartForwarding(StrEq("wlan0"), StrEq("arc_wlan0"), _, _));
473 // Expectations for eth1 setup.
474 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
475 .WillOnce(Return(true));
476 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth1"), StrEq("vmtap2")))
477 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900478 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth1"), StrEq("arc_eth1"),
479 Ipv4Addr(100, 115, 92, 10),
480 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900481 EXPECT_CALL(forwarder_,
482 StartForwarding(StrEq("eth1"), StrEq("arc_eth1"), _, _));
483
484 auto svc = NewService(GuestMessage::ARC_VM);
485 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900486 svc->OnDevicesChanged({"eth0"}, {});
487 svc->OnDevicesChanged({"wlan0"}, {});
488 svc->OnDevicesChanged({"eth1"}, {});
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900489}
490
491TEST_F(ArcServiceTest, VmImpl_Stop) {
492 // Expectations for tap devices pre-creation.
493 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
494 .WillOnce(Return("vmtap0"))
495 .WillOnce(Return("vmtap1"))
496 .WillOnce(Return("vmtap2"))
497 .WillOnce(Return("vmtap3"))
498 .WillOnce(Return("vmtap4"))
499 .WillOnce(Return("vmtap5"));
500 // Expectations for "arc0" setup.
501 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
502 .WillOnce(Return(true));
503 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
504 .WillOnce(Return(true));
505 // Expectations for "arc0" teardown.
506 EXPECT_CALL(*datapath_,
507 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
508 .WillOnce(Return(true));
509 // Expectations for tap devices teardown
Garrick Evans2961c7c2020-04-03 11:34:40 +0900510 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap0")));
511 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap1")));
512 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap2")));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900513 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap3")));
514 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap4")));
515 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap5")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900516
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900517 auto svc = NewService(GuestMessage::ARC_VM);
518 svc->Start(kTestPID);
519 svc->Stop(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900520}
521
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900522TEST_F(ArcServiceTest, VmImpl_StopDevice) {
523 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900524 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900525 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900526 .WillOnce(Return("vmtap1"))
527 .WillOnce(Return("vmtap2"))
528 .WillOnce(Return("vmtap3"))
529 .WillOnce(Return("vmtap4"))
530 .WillOnce(Return("vmtap5"));
531 // Expectations for "arc0" setup.
532 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900533 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900534 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900535 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900536 // Expectations for eth0 setup.
537 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
538 .WillOnce(Return(true));
539 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
540 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900541 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
542 Ipv4Addr(100, 115, 92, 6),
543 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900544 EXPECT_CALL(forwarder_,
545 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
546 // Expectations for eth0 teardown.
Garrick Evans2961c7c2020-04-03 11:34:40 +0900547 EXPECT_CALL(forwarder_,
548 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900549 EXPECT_CALL(*datapath_,
Hugo Benichi8d622b52020-08-13 15:24:12 +0900550 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
551 Ipv4Addr(100, 115, 92, 6), TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900552 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900553
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900554 auto svc = NewService(GuestMessage::ARC_VM);
555 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900556 svc->OnDevicesChanged({"eth0"}, {});
557 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900558}
Garrick Evans3388a032020-03-24 11:25:55 +0900559
Garrick Evans02e6e872020-11-30 11:53:13 +0900560TEST_F(ArcServiceTest, VmImpl_ScanDevices) {
561 // Expectations for tap devices pre-creation.
562 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
563 .WillOnce(Return("vmtap0"))
564 .WillOnce(Return("vmtap1"))
565 .WillOnce(Return("vmtap2"))
566 .WillOnce(Return("vmtap3"))
567 .WillOnce(Return("vmtap4"))
568 .WillOnce(Return("vmtap5"));
569 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
570 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
571
572 auto svc = NewService(GuestMessage::ARC_VM);
573 svc->Start(kTestPID);
574 svc->OnDevicesChanged({"eth0", "wlan0", "eth1"}, {});
575
576 std::vector<std::string> devs;
577 svc->ScanDevices(base::BindRepeating(
578 [](std::vector<std::string>* list, const Device& device) {
579 list->push_back(device.host_ifname());
580 },
581 &devs));
582
583 EXPECT_EQ(devs.size(), 3);
584 EXPECT_THAT(devs, UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0"),
585 StrEq("arc_eth1")));
586}
587
Garrick Evans3388a032020-03-24 11:25:55 +0900588} // namespace patchpanel