blob: d064eb7fcea9914aa4fb03ad7cc39aa349dbbb5b [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"
21#include "patchpanel/net_util.h"
Garrick Evans54861622019-07-19 09:05:09 +090022
23using testing::_;
Garrick Evanse94b6de2020-02-20 09:19:13 +090024using testing::AnyNumber;
Garrick Evansc7071122020-04-17 12:31:57 +090025using testing::Eq;
26using testing::Pointee;
Garrick Evans54861622019-07-19 09:05:09 +090027using testing::Return;
Garrick Evansb4eb3892019-11-13 12:07:07 +090028using testing::ReturnRef;
Garrick Evans54861622019-07-19 09:05:09 +090029using testing::StrEq;
30
Garrick Evans3388a032020-03-24 11:25:55 +090031namespace patchpanel {
Garrick Evans54861622019-07-19 09:05:09 +090032namespace {
Garrick Evansb4eb3892019-11-13 12:07:07 +090033constexpr pid_t kTestPID = -2;
Garrick Evansb4eb3892019-11-13 12:07:07 +090034constexpr uint32_t kTestCID = 2;
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090035constexpr uint32_t kArcHostIP = Ipv4Addr(100, 115, 92, 1);
36constexpr uint32_t kArcGuestIP = Ipv4Addr(100, 115, 92, 2);
Hugo Benichiad1bdd92020-06-12 13:48:37 +090037constexpr uint32_t kFirstEthHostIP = Ipv4Addr(100, 115, 92, 5);
38constexpr uint32_t kFirstEthGuestIP = Ipv4Addr(100, 115, 92, 6);
Garrick Evans86c7d9c2020-03-17 09:25:48 +090039constexpr uint32_t kSecondEthHostIP = Ipv4Addr(100, 115, 92, 9);
40constexpr uint32_t kFirstWifiHostIP = Ipv4Addr(100, 115, 92, 13);
41constexpr uint32_t kSecondWifiHostIP = Ipv4Addr(100, 115, 92, 17);
42constexpr uint32_t kFirstCellHostIP = Ipv4Addr(100, 115, 92, 21);
Garrick Evansc7071122020-04-17 12:31:57 +090043constexpr MacAddress kArcVmArc0MacAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x01};
Garrick Evans54861622019-07-19 09:05:09 +090044
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090045class MockTrafficForwarder : public TrafficForwarder {
46 public:
47 MockTrafficForwarder() = default;
48 ~MockTrafficForwarder() = default;
49
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +090050 MOCK_METHOD4(StartForwarding,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090051 void(const std::string& ifname_physical,
52 const std::string& ifname_virtual,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090053 bool ipv6,
54 bool multicast));
55
56 MOCK_METHOD4(StopForwarding,
57 void(const std::string& ifname_physical,
58 const std::string& ifname_virtual,
59 bool ipv6,
60 bool multicast));
61};
62
Garrick Evans54861622019-07-19 09:05:09 +090063} // namespace
64
65class ArcServiceTest : public testing::Test {
66 public:
Garrick Evans4ee5ce22020-03-18 07:05:17 +090067 ArcServiceTest() : testing::Test() {}
Garrick Evans54861622019-07-19 09:05:09 +090068
69 protected:
70 void SetUp() override {
Taoyu Li179dcc62019-10-17 11:21:08 +090071 runner_ = std::make_unique<FakeProcessRunner>();
Garrick Evans54861622019-07-19 09:05:09 +090072 runner_->Capture(false);
Taoyu Li179dcc62019-10-17 11:21:08 +090073 datapath_ = std::make_unique<MockDatapath>(runner_.get());
Garrick Evans69b85872020-02-04 11:40:26 +090074 shill_client_ = shill_helper_.Client();
Garrick Evans4ee5ce22020-03-18 07:05:17 +090075 addr_mgr_ = std::make_unique<AddressManager>();
Garrick Evans54861622019-07-19 09:05:09 +090076 }
77
Hugo Benichiad1bdd92020-06-12 13:48:37 +090078 std::unique_ptr<ArcService> NewService(GuestMessage::GuestType guest) {
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090079 return std::make_unique<ArcService>(shill_client_.get(), datapath_.get(),
Hugo Benichiad1bdd92020-06-12 13:48:37 +090080 addr_mgr_.get(), &forwarder_, guest);
Garrick Evans54861622019-07-19 09:05:09 +090081 }
82
Garrick Evans69b85872020-02-04 11:40:26 +090083 FakeShillClientHelper shill_helper_;
84 std::unique_ptr<ShillClient> shill_client_;
Garrick Evans4ee5ce22020-03-18 07:05:17 +090085 std::unique_ptr<AddressManager> addr_mgr_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090086 MockTrafficForwarder forwarder_;
Taoyu Li179dcc62019-10-17 11:21:08 +090087 std::unique_ptr<MockDatapath> datapath_;
88 std::unique_ptr<FakeProcessRunner> runner_;
Garrick Evans54861622019-07-19 09:05:09 +090089};
90
Hugo Benichiad1bdd92020-06-12 13:48:37 +090091TEST_F(ArcServiceTest, NotStarted_AddDevice) {
92 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
93 EXPECT_CALL(*datapath_, AddInboundIPv4DNAT(StrEq("eth0"), _)).Times(0);
94 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +090095
Hugo Benichiad1bdd92020-06-12 13:48:37 +090096 auto svc = NewService(GuestMessage::ARC);
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090097 svc->AddDevice("eth0");
98 EXPECT_TRUE(svc->devices_.find("eth0") != svc->devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +090099}
100
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900101TEST_F(ArcServiceTest, NotStarted_AddRemoveDevice) {
102 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
103 EXPECT_CALL(*datapath_, AddInboundIPv4DNAT(StrEq("eth0"), _)).Times(0);
104 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0"))).Times(0);
105 EXPECT_CALL(*datapath_, RemoveOutboundIPv4(StrEq("arc_eth0"))).Times(0);
106 EXPECT_CALL(*datapath_, RemoveInboundIPv4DNAT(StrEq("eth0"), _)).Times(0);
107 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900108
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900109 auto svc = NewService(GuestMessage::ARC);
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900110 svc->AddDevice("eth0");
111 svc->RemoveDevice("eth0");
112 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900113}
114
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900115TEST_F(ArcServiceTest, VerifyAddrConfigs) {
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900116 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
117 .WillOnce(Return(true));
118 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900119 .WillOnce(Return(true));
120 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
121 .WillOnce(Return(true));
122 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
123 .WillOnce(Return(true));
124 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
125 .WillOnce(Return(true));
126 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
127 .WillOnce(Return(true));
128 EXPECT_CALL(*datapath_, AddInboundIPv4DNAT(_, _))
129 .WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900130
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900131 auto svc = NewService(GuestMessage::ARC);
132 svc->Start(kTestPID);
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900133 svc->AddDevice("eth0");
134 svc->AddDevice("eth1");
135 svc->AddDevice("wlan0");
136 svc->AddDevice("wlan1");
137 svc->AddDevice("wwan0");
138}
139
140TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900141 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
142 .WillOnce(Return(true));
143 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900144 .Times(2)
145 .WillRepeatedly(Return(true));
146 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
147 .WillOnce(Return(true));
148 EXPECT_CALL(*datapath_, AddInboundIPv4DNAT(_, _))
149 .WillRepeatedly(Return(true));
150 EXPECT_CALL(*datapath_, AddOutboundIPv4(_)).WillRepeatedly(Return(true));
151
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900152 auto svc = NewService(GuestMessage::ARC);
153 svc->Start(kTestPID);
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900154 svc->AddDevice("wlan0");
155 svc->AddDevice("eth0");
156 svc->RemoveDevice("eth0");
157 svc->AddDevice("eth0");
158}
159
Garrick Evansc7071122020-04-17 12:31:57 +0900160TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
161 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
162 .WillRepeatedly(Return("vmtap"));
163 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
164 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
165
166 auto svc = NewService(GuestMessage::ARC_VM);
167 svc->Start(kTestCID);
168 auto configs = svc->GetDeviceConfigs();
169 EXPECT_EQ(configs.size(), 6);
170 auto mac_addr = kArcVmArc0MacAddr;
171 for (const auto* config : configs) {
172 EXPECT_EQ(config->mac_addr(), mac_addr);
173 mac_addr[5]++;
174 }
175}
176
Garrick Evansb4eb3892019-11-13 12:07:07 +0900177// ContainerImpl
178
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900179TEST_F(ArcServiceTest, ContainerImpl_Start) {
180 // Expectations for arc0 setup.
Garrick Evanse94b6de2020-02-20 09:19:13 +0900181 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
182 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900183 EXPECT_CALL(*datapath_,
Garrick Evans2f581a02020-05-11 10:43:35 +0900184 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900185 .WillOnce(Return(true));
Garrick Evans2470caa2020-03-04 14:15:41 +0900186 EXPECT_CALL(*datapath_,
187 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
188 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900189 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
Garrick Evans2470caa2020-03-04 14:15:41 +0900190 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900191 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900192 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900193 EXPECT_CALL(forwarder_, StartForwarding(_, _, _, _)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900194
195 auto svc = NewService(GuestMessage::ARC);
196 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900197}
198
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900199TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
Garrick Evanse94b6de2020-02-20 09:19:13 +0900200 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
201 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900202 EXPECT_CALL(*datapath_,
Garrick Evans2f581a02020-05-11 10:43:35 +0900203 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900204 .WillOnce(Return(false));
205 EXPECT_CALL(*datapath_, ConfigureInterface(_, _, _, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900206 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900207
208 auto svc = NewService(GuestMessage::ARC);
209 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900210}
211
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900212TEST_F(ArcServiceTest, ContainerImpl_FailsToConfigureInterface) {
Garrick Evanse94b6de2020-02-20 09:19:13 +0900213 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
214 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900215 EXPECT_CALL(*datapath_,
Garrick Evans2f581a02020-05-11 10:43:35 +0900216 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
Garrick Evans63378b32020-01-14 10:36:16 +0900217 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900218 EXPECT_CALL(*datapath_,
Garrick Evans2470caa2020-03-04 14:15:41 +0900219 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
Garrick Evans63378b32020-01-14 10:36:16 +0900220 .WillOnce(Return(false));
Garrick Evans2f581a02020-05-11 10:43:35 +0900221 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900222 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
223 .Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900224 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900225
226 auto svc = NewService(GuestMessage::ARC);
227 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900228}
229
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900230TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
231 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
232 .WillOnce(Return(true));
233 EXPECT_CALL(*datapath_,
234 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
235 .WillOnce(Return(true));
236 EXPECT_CALL(*datapath_,
237 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
238 .WillOnce(Return(true));
239 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
240 .WillOnce(Return(true));
241 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
242 .WillOnce(Return(false));
243
244 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
245 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
246
247 auto svc = NewService(GuestMessage::ARC);
248 svc->Start(kTestPID);
249}
250
251TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
252 // Expectations for arc0 setup.
253 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
254 .WillOnce(Return(true));
255 EXPECT_CALL(*datapath_,
256 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
257 .WillOnce(Return(true));
258 EXPECT_CALL(*datapath_,
259 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
260 .WillOnce(Return(true));
261 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
262 .WillOnce(Return(true));
263 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
264 .WillOnce(Return(true));
265 // Expectations for eth0 setup.
266 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
267 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900268 EXPECT_CALL(*datapath_,
Garrick Evans2f581a02020-05-11 10:43:35 +0900269 AddVirtualInterfacePair(StrEq("vetheth0"), StrEq("eth0")))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900270 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900271 EXPECT_CALL(*datapath_, ConfigureInterface(StrEq("eth0"), _, kFirstEthGuestIP,
272 30, true, _))
Garrick Evans2470caa2020-03-04 14:15:41 +0900273 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900274 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetheth0"), true))
Garrick Evans2470caa2020-03-04 14:15:41 +0900275 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900276 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900277 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900278 EXPECT_CALL(forwarder_,
279 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900280 EXPECT_CALL(
281 *datapath_,
282 AddInboundIPv4DNAT(StrEq("eth0"), IPv4AddressToString(kFirstEthGuestIP)))
283 .WillOnce(Return(true));
284 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")))
285 .WillOnce(Return(true));
286
287 auto svc = NewService(GuestMessage::ARC);
288 svc->Start(kTestPID);
289 svc->AddDevice("eth0");
Garrick Evansb4eb3892019-11-13 12:07:07 +0900290}
291
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900292TEST_F(ArcServiceTest, ContainerImpl_Stop) {
293 // Expectations for arc0 setup.
294 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
295 .WillOnce(Return(true));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900296 EXPECT_CALL(*datapath_,
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900297 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
298 .WillOnce(Return(true));
299 EXPECT_CALL(*datapath_,
300 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
301 .WillOnce(Return(true));
302 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
303 .WillOnce(Return(true));
304 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
305 .WillOnce(Return(true));
306 // Expectations for arc0 teardown.
307 EXPECT_CALL(*datapath_,
308 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
309 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900310 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900311 EXPECT_CALL(forwarder_, StopForwarding(_, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900312
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900313 auto svc = NewService(GuestMessage::ARC);
314 svc->Start(kTestPID);
315 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900316}
317
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900318TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
319 // Expectations for arc0 setup.
320 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
321 .WillOnce(Return(true));
322 EXPECT_CALL(*datapath_,
323 AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
324 .WillOnce(Return(true));
325 EXPECT_CALL(*datapath_,
326 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
327 .WillOnce(Return(true));
328 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
329 .WillOnce(Return(true));
330 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
331 .WillOnce(Return(true));
332 // Expectations for eth0 setup.
333 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
334 .WillOnce(Return(true));
335 EXPECT_CALL(*datapath_,
336 AddVirtualInterfacePair(StrEq("vetheth0"), StrEq("eth0")))
337 .WillOnce(Return(true));
338 EXPECT_CALL(*datapath_, ConfigureInterface(StrEq("eth0"), _, kFirstEthGuestIP,
339 30, true, _))
340 .WillOnce(Return(true));
341 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetheth0"), true))
342 .WillOnce(Return(true));
343 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
344 .WillOnce(Return(true));
345 // Expectations for eth0 teardown.
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900346 EXPECT_CALL(forwarder_,
347 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900348 EXPECT_CALL(*datapath_, RemoveOutboundIPv4(StrEq("arc_eth0")));
349 EXPECT_CALL(*datapath_,
350 RemoveInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
351 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900352
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900353 auto svc = NewService(GuestMessage::ARC);
354 svc->Start(kTestPID);
355 svc->AddDevice("eth0");
356 svc->RemoveDevice("eth0");
Garrick Evansb4eb3892019-11-13 12:07:07 +0900357}
358
Garrick Evansb4eb3892019-11-13 12:07:07 +0900359// VM Impl
360
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900361TEST_F(ArcServiceTest, VmImpl_Start) {
362 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900363 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900364 .WillOnce(Return("vmtap0"))
365 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900366 .WillOnce(Return("vmtap2"))
367 .WillOnce(Return("vmtap3"))
368 .WillOnce(Return("vmtap4"))
369 .WillOnce(Return("vmtap5"));
370 // Expectations for "arc0" setup.
371 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900372 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900373 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900374 .WillOnce(Return(true));
375
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900376 auto svc = NewService(GuestMessage::ARC_VM);
377 svc->Start(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900378}
379
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900380TEST_F(ArcServiceTest, VmImpl_StartDevice) {
381 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900382 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900383 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900384 .WillOnce(Return("vmtap1"))
385 .WillOnce(Return("vmtap2"))
386 .WillOnce(Return("vmtap3"))
387 .WillOnce(Return("vmtap4"))
388 .WillOnce(Return("vmtap5"));
389 // Expectations for "arc0" setup.
390 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900391 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900392 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
393 .WillOnce(Return(true));
394 // Expectations for eth0 setup.
395 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900396 .WillOnce(Return(true));
397 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
398 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900399 EXPECT_CALL(*datapath_,
400 AddInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
401 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900402 EXPECT_CALL(forwarder_,
403 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
404
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900405 auto svc = NewService(GuestMessage::ARC_VM);
406 svc->Start(kTestPID);
407 svc->AddDevice("eth0");
Garrick Evans2961c7c2020-04-03 11:34:40 +0900408}
409
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900410TEST_F(ArcServiceTest, VmImpl_StartMultipleDevices) {
411 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900412 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900413 .WillOnce(Return("vmtap0"))
414 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900415 .WillOnce(Return("vmtap2"))
416 .WillOnce(Return("vmtap3"))
417 .WillOnce(Return("vmtap4"))
418 .WillOnce(Return("vmtap5"));
419 // Expectations for "arc0" setup.
420 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900421 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900422 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900423 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900424 // Expectations for eth0 setup.
425 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
426 .WillOnce(Return(true));
427 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
428 .WillOnce(Return(true));
429 EXPECT_CALL(*datapath_,
430 AddInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
431 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")));
432 EXPECT_CALL(forwarder_,
433 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
434 // Expectations for wlan0 setup.
435 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
436 .WillOnce(Return(true));
437 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_wlan0"), StrEq("vmtap3")))
438 .WillOnce(Return(true));
439 EXPECT_CALL(*datapath_,
440 AddInboundIPv4DNAT(StrEq("wlan0"), StrEq("100.115.92.14")));
441 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_wlan0")));
442 EXPECT_CALL(forwarder_,
443 StartForwarding(StrEq("wlan0"), StrEq("arc_wlan0"), _, _));
444 // Expectations for eth1 setup.
445 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
446 .WillOnce(Return(true));
447 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth1"), StrEq("vmtap2")))
448 .WillOnce(Return(true));
449 EXPECT_CALL(*datapath_,
450 AddInboundIPv4DNAT(StrEq("eth1"), StrEq("100.115.92.10")));
451 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth1")));
452 EXPECT_CALL(forwarder_,
453 StartForwarding(StrEq("eth1"), StrEq("arc_eth1"), _, _));
454
455 auto svc = NewService(GuestMessage::ARC_VM);
456 svc->Start(kTestPID);
457 svc->AddDevice("eth0");
458 svc->AddDevice("wlan0");
459 svc->AddDevice("eth1");
460}
461
462TEST_F(ArcServiceTest, VmImpl_Stop) {
463 // Expectations for tap devices pre-creation.
464 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
465 .WillOnce(Return("vmtap0"))
466 .WillOnce(Return("vmtap1"))
467 .WillOnce(Return("vmtap2"))
468 .WillOnce(Return("vmtap3"))
469 .WillOnce(Return("vmtap4"))
470 .WillOnce(Return("vmtap5"));
471 // Expectations for "arc0" setup.
472 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
473 .WillOnce(Return(true));
474 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
475 .WillOnce(Return(true));
476 // Expectations for "arc0" teardown.
477 EXPECT_CALL(*datapath_,
478 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
479 .WillOnce(Return(true));
480 // Expectations for tap devices teardown
Garrick Evans2961c7c2020-04-03 11:34:40 +0900481 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap0")));
482 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap1")));
483 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap2")));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900484 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap3")));
485 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap4")));
486 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap5")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900487
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900488 auto svc = NewService(GuestMessage::ARC_VM);
489 svc->Start(kTestPID);
490 svc->Stop(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900491}
492
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900493TEST_F(ArcServiceTest, VmImpl_StopDevice) {
494 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900495 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900496 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900497 .WillOnce(Return("vmtap1"))
498 .WillOnce(Return("vmtap2"))
499 .WillOnce(Return("vmtap3"))
500 .WillOnce(Return("vmtap4"))
501 .WillOnce(Return("vmtap5"));
502 // Expectations for "arc0" setup.
503 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900504 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900505 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900506 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900507 // Expectations for eth0 setup.
508 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
509 .WillOnce(Return(true));
510 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
511 .WillOnce(Return(true));
512 EXPECT_CALL(*datapath_,
513 AddInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
514 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")));
515 EXPECT_CALL(forwarder_,
516 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
517 // Expectations for eth0 teardown.
Garrick Evans2961c7c2020-04-03 11:34:40 +0900518 EXPECT_CALL(forwarder_,
519 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900520 EXPECT_CALL(*datapath_, RemoveOutboundIPv4(StrEq("arc_eth0")));
521 EXPECT_CALL(*datapath_,
522 RemoveInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
523 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900524
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900525 auto svc = NewService(GuestMessage::ARC_VM);
526 svc->Start(kTestPID);
527 svc->AddDevice("eth0");
528 svc->RemoveDevice("eth0");
Garrick Evans2961c7c2020-04-03 11:34:40 +0900529}
Garrick Evans3388a032020-03-24 11:25:55 +0900530
531} // namespace patchpanel