blob: 01aad325dfcf738ae9da22e65a66362189e73904 [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 Benichi33860d72020-07-09 16:34:01 +0900116 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
117 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900118 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
119 .WillOnce(Return(true));
120 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900121 .WillOnce(Return(true));
122 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
123 .WillOnce(Return(true));
124 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
125 .WillOnce(Return(true));
126 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
127 .WillOnce(Return(true));
128 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
129 .WillOnce(Return(true));
130 EXPECT_CALL(*datapath_, AddInboundIPv4DNAT(_, _))
131 .WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900132
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900133 auto svc = NewService(GuestMessage::ARC);
134 svc->Start(kTestPID);
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900135 svc->AddDevice("eth0");
136 svc->AddDevice("eth1");
137 svc->AddDevice("wlan0");
138 svc->AddDevice("wlan1");
139 svc->AddDevice("wwan0");
140}
141
142TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900143 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
144 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900145 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
146 .WillOnce(Return(true));
147 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900148 .Times(2)
149 .WillRepeatedly(Return(true));
150 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
151 .WillOnce(Return(true));
152 EXPECT_CALL(*datapath_, AddInboundIPv4DNAT(_, _))
153 .WillRepeatedly(Return(true));
154 EXPECT_CALL(*datapath_, AddOutboundIPv4(_)).WillRepeatedly(Return(true));
155
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900156 auto svc = NewService(GuestMessage::ARC);
157 svc->Start(kTestPID);
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900158 svc->AddDevice("wlan0");
159 svc->AddDevice("eth0");
160 svc->RemoveDevice("eth0");
161 svc->AddDevice("eth0");
162}
163
Garrick Evansc7071122020-04-17 12:31:57 +0900164TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
165 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
166 .WillRepeatedly(Return("vmtap"));
167 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
168 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
169
170 auto svc = NewService(GuestMessage::ARC_VM);
171 svc->Start(kTestCID);
172 auto configs = svc->GetDeviceConfigs();
173 EXPECT_EQ(configs.size(), 6);
174 auto mac_addr = kArcVmArc0MacAddr;
175 for (const auto* config : configs) {
176 EXPECT_EQ(config->mac_addr(), mac_addr);
177 mac_addr[5]++;
178 }
179}
180
Garrick Evansb4eb3892019-11-13 12:07:07 +0900181// ContainerImpl
182
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900183TEST_F(ArcServiceTest, ContainerImpl_Start) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900184 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
185 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900186 // Expectations for arc0 setup.
Garrick Evanse94b6de2020-02-20 09:19:13 +0900187 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
188 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900189 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900190 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
191 StrEq("arc0")))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900192 .WillOnce(Return(true));
Garrick Evans2470caa2020-03-04 14:15:41 +0900193 EXPECT_CALL(*datapath_,
194 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
195 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900196 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
Garrick Evans2470caa2020-03-04 14:15:41 +0900197 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900198 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900199 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900200 EXPECT_CALL(forwarder_, StartForwarding(_, _, _, _)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900201
202 auto svc = NewService(GuestMessage::ARC);
203 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900204}
205
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900206TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900207 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
208 .WillOnce(Return(true));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900209 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
210 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900211 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900212 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
213 StrEq("arc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900214 .WillOnce(Return(false));
215 EXPECT_CALL(*datapath_, ConfigureInterface(_, _, _, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900216 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900217
218 auto svc = NewService(GuestMessage::ARC);
219 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900220}
221
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900222TEST_F(ArcServiceTest, ContainerImpl_FailsToConfigureInterface) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900223 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
224 .WillOnce(Return(true));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900225 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
226 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900227 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900228 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
229 StrEq("arc0")))
Garrick Evans63378b32020-01-14 10:36:16 +0900230 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900231 EXPECT_CALL(*datapath_,
Garrick Evans2470caa2020-03-04 14:15:41 +0900232 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
Garrick Evans63378b32020-01-14 10:36:16 +0900233 .WillOnce(Return(false));
Garrick Evans2f581a02020-05-11 10:43:35 +0900234 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900235 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
236 .Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900237 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900238
239 auto svc = NewService(GuestMessage::ARC);
240 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900241}
242
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900243TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900244 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
245 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900246 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
247 .WillOnce(Return(true));
248 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900249 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
250 StrEq("arc0")))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900251 .WillOnce(Return(true));
252 EXPECT_CALL(*datapath_,
253 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
254 .WillOnce(Return(true));
255 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
256 .WillOnce(Return(true));
257 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
258 .WillOnce(Return(false));
259
260 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
261 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
262
263 auto svc = NewService(GuestMessage::ARC);
264 svc->Start(kTestPID);
265}
266
267TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900268 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
269 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900270 // Expectations for arc0 setup.
271 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
272 .WillOnce(Return(true));
273 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900274 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
275 StrEq("arc0")))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900276 .WillOnce(Return(true));
277 EXPECT_CALL(*datapath_,
278 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
279 .WillOnce(Return(true));
280 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
281 .WillOnce(Return(true));
282 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
283 .WillOnce(Return(true));
284 // Expectations for eth0 setup.
285 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
286 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900287 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900288 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetheth0"),
289 StrEq("eth0")))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900290 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900291 EXPECT_CALL(*datapath_, ConfigureInterface(StrEq("eth0"), _, kFirstEthGuestIP,
292 30, true, _))
Garrick Evans2470caa2020-03-04 14:15:41 +0900293 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900294 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetheth0"), true))
Garrick Evans2470caa2020-03-04 14:15:41 +0900295 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900296 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900297 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900298 EXPECT_CALL(forwarder_,
299 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900300 EXPECT_CALL(
301 *datapath_,
302 AddInboundIPv4DNAT(StrEq("eth0"), IPv4AddressToString(kFirstEthGuestIP)))
303 .WillOnce(Return(true));
304 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")))
305 .WillOnce(Return(true));
306
307 auto svc = NewService(GuestMessage::ARC);
308 svc->Start(kTestPID);
309 svc->AddDevice("eth0");
Garrick Evansb4eb3892019-11-13 12:07:07 +0900310}
311
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900312TEST_F(ArcServiceTest, ContainerImpl_Stop) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900313 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
314 .WillOnce(Return(true));
315 EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
316 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900317 // Expectations for arc0 setup.
318 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
319 .WillOnce(Return(true));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900320 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900321 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
322 StrEq("arc0")))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900323 .WillOnce(Return(true));
324 EXPECT_CALL(*datapath_,
325 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
326 .WillOnce(Return(true));
327 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
328 .WillOnce(Return(true));
329 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
330 .WillOnce(Return(true));
331 // Expectations for arc0 teardown.
332 EXPECT_CALL(*datapath_,
333 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
334 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900335 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900336 EXPECT_CALL(forwarder_, StopForwarding(_, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900337
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900338 auto svc = NewService(GuestMessage::ARC);
339 svc->Start(kTestPID);
340 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900341}
342
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900343TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900344 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
345 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900346 // Expectations for arc0 setup.
347 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
348 .WillOnce(Return(true));
349 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900350 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
351 StrEq("arc0")))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900352 .WillOnce(Return(true));
353 EXPECT_CALL(*datapath_,
354 ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
355 .WillOnce(Return(true));
356 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetharc0"), true))
357 .WillOnce(Return(true));
358 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
359 .WillOnce(Return(true));
360 // Expectations for eth0 setup.
361 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
362 .WillOnce(Return(true));
363 EXPECT_CALL(*datapath_,
Hugo Benichi33860d72020-07-09 16:34:01 +0900364 AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetheth0"),
365 StrEq("eth0")))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900366 .WillOnce(Return(true));
367 EXPECT_CALL(*datapath_, ConfigureInterface(StrEq("eth0"), _, kFirstEthGuestIP,
368 30, true, _))
369 .WillOnce(Return(true));
370 EXPECT_CALL(*datapath_, ToggleInterface(StrEq("vetheth0"), true))
371 .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_, RemoveOutboundIPv4(StrEq("arc_eth0")));
378 EXPECT_CALL(*datapath_,
379 RemoveInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
380 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);
384 svc->AddDevice("eth0");
385 svc->RemoveDevice("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 Benichiad1bdd92020-06-12 13:48:37 +0900428 EXPECT_CALL(*datapath_,
429 AddInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
430 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")));
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);
436 svc->AddDevice("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));
458 EXPECT_CALL(*datapath_,
459 AddInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
460 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")));
461 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));
468 EXPECT_CALL(*datapath_,
469 AddInboundIPv4DNAT(StrEq("wlan0"), StrEq("100.115.92.14")));
470 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_wlan0")));
471 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));
478 EXPECT_CALL(*datapath_,
479 AddInboundIPv4DNAT(StrEq("eth1"), StrEq("100.115.92.10")));
480 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth1")));
481 EXPECT_CALL(forwarder_,
482 StartForwarding(StrEq("eth1"), StrEq("arc_eth1"), _, _));
483
484 auto svc = NewService(GuestMessage::ARC_VM);
485 svc->Start(kTestPID);
486 svc->AddDevice("eth0");
487 svc->AddDevice("wlan0");
488 svc->AddDevice("eth1");
489}
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));
541 EXPECT_CALL(*datapath_,
542 AddInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
543 EXPECT_CALL(*datapath_, AddOutboundIPv4(StrEq("arc_eth0")));
544 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_, RemoveOutboundIPv4(StrEq("arc_eth0")));
550 EXPECT_CALL(*datapath_,
551 RemoveInboundIPv4DNAT(StrEq("eth0"), StrEq("100.115.92.6")));
552 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);
556 svc->AddDevice("eth0");
557 svc->RemoveDevice("eth0");
Garrick Evans2961c7c2020-04-03 11:34:40 +0900558}
Garrick Evans3388a032020-03-24 11:25:55 +0900559
560} // namespace patchpanel