blob: 31ab576da6a6599322ae14850bd78f8c1fc7612e [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>
Garrick Evans209a80a2020-11-30 14:42:40 +090013#include <base/bind_helpers.h>
Hugo Benichi84d96c42021-02-26 14:20:13 +090014#include <dbus/mock_bus.h>
Garrick Evans54861622019-07-19 09:05:09 +090015#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
Garrick Evans3388a032020-03-24 11:25:55 +090018#include "patchpanel/address_manager.h"
19#include "patchpanel/fake_process_runner.h"
20#include "patchpanel/fake_shill_client.h"
21#include "patchpanel/mock_datapath.h"
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090022#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090023#include "patchpanel/net_util.h"
Garrick Evans54861622019-07-19 09:05:09 +090024
25using testing::_;
Garrick Evanse94b6de2020-02-20 09:19:13 +090026using testing::AnyNumber;
Garrick Evansc7071122020-04-17 12:31:57 +090027using testing::Eq;
Hugo Benichi84d96c42021-02-26 14:20:13 +090028using testing::Invoke;
Garrick Evans209a80a2020-11-30 14:42:40 +090029using testing::Pair;
Garrick Evansc7071122020-04-17 12:31:57 +090030using testing::Pointee;
Garrick Evans54861622019-07-19 09:05:09 +090031using testing::Return;
Garrick Evansb4eb3892019-11-13 12:07:07 +090032using testing::ReturnRef;
Garrick Evans54861622019-07-19 09:05:09 +090033using testing::StrEq;
Garrick Evans02e6e872020-11-30 11:53:13 +090034using testing::UnorderedElementsAre;
Garrick Evans54861622019-07-19 09:05:09 +090035
Garrick Evans3388a032020-03-24 11:25:55 +090036namespace patchpanel {
Garrick Evans54861622019-07-19 09:05:09 +090037namespace {
Garrick Evansb4eb3892019-11-13 12:07:07 +090038constexpr pid_t kTestPID = -2;
Garrick Evansb4eb3892019-11-13 12:07:07 +090039constexpr uint32_t kTestCID = 2;
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090040constexpr uint32_t kArcHostIP = Ipv4Addr(100, 115, 92, 1);
41constexpr uint32_t kArcGuestIP = Ipv4Addr(100, 115, 92, 2);
Hugo Benichiad1bdd92020-06-12 13:48:37 +090042constexpr uint32_t kFirstEthHostIP = Ipv4Addr(100, 115, 92, 5);
43constexpr uint32_t kFirstEthGuestIP = Ipv4Addr(100, 115, 92, 6);
Garrick Evans86c7d9c2020-03-17 09:25:48 +090044constexpr uint32_t kSecondEthHostIP = Ipv4Addr(100, 115, 92, 9);
45constexpr uint32_t kFirstWifiHostIP = Ipv4Addr(100, 115, 92, 13);
46constexpr uint32_t kSecondWifiHostIP = Ipv4Addr(100, 115, 92, 17);
47constexpr uint32_t kFirstCellHostIP = Ipv4Addr(100, 115, 92, 21);
Garrick Evansc7071122020-04-17 12:31:57 +090048constexpr MacAddress kArcVmArc0MacAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x01};
Garrick Evans54861622019-07-19 09:05:09 +090049
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090050class MockTrafficForwarder : public TrafficForwarder {
51 public:
52 MockTrafficForwarder() = default;
53 ~MockTrafficForwarder() = default;
54
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +090055 MOCK_METHOD4(StartForwarding,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090056 void(const std::string& ifname_physical,
57 const std::string& ifname_virtual,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090058 bool ipv6,
59 bool multicast));
60
61 MOCK_METHOD4(StopForwarding,
62 void(const std::string& ifname_physical,
63 const std::string& ifname_virtual,
64 bool ipv6,
65 bool multicast));
66};
67
Hugo Benichi84d96c42021-02-26 14:20:13 +090068class MockShillClient : public ShillClient {
69 public:
70 explicit MockShillClient(scoped_refptr<dbus::MockBus> bus)
71 : ShillClient(bus) {}
72 ~MockShillClient() = default;
73
74 MOCK_METHOD2(GetDeviceProperties,
75 bool(const std::string& ifname, ShillClient::Device* device));
76};
77
78void ExpectGetDeviceProperties(MockShillClient& shill_client,
79 const std::string& iface,
80 ShillClient::Device::Type type) {
81 EXPECT_CALL(shill_client, GetDeviceProperties(StrEq(iface), _))
82 .WillRepeatedly(
83 Invoke([type](const std::string& _, ShillClient::Device* device) {
84 device->type = type;
85 return true;
86 }));
87}
88
Garrick Evans54861622019-07-19 09:05:09 +090089} // namespace
90
91class ArcServiceTest : public testing::Test {
92 public:
Garrick Evans4ee5ce22020-03-18 07:05:17 +090093 ArcServiceTest() : testing::Test() {}
Garrick Evans54861622019-07-19 09:05:09 +090094
95 protected:
96 void SetUp() override {
Taoyu Li179dcc62019-10-17 11:21:08 +090097 runner_ = std::make_unique<FakeProcessRunner>();
Garrick Evans54861622019-07-19 09:05:09 +090098 runner_->Capture(false);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090099 datapath_ = std::make_unique<MockDatapath>(runner_.get(), &firewall_);
Hugo Benichi84d96c42021-02-26 14:20:13 +0900100 shill_client_ = std::make_unique<MockShillClient>(shill_helper_.mock_bus());
Garrick Evans4ee5ce22020-03-18 07:05:17 +0900101 addr_mgr_ = std::make_unique<AddressManager>();
Garrick Evans209a80a2020-11-30 14:42:40 +0900102 guest_devices_.clear();
Garrick Evans54861622019-07-19 09:05:09 +0900103 }
104
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900105 std::unique_ptr<ArcService> NewService(GuestMessage::GuestType guest) {
Garrick Evans209a80a2020-11-30 14:42:40 +0900106 return std::make_unique<ArcService>(
107 shill_client_.get(), datapath_.get(), addr_mgr_.get(), &forwarder_,
108 guest,
109 base::BindRepeating(&ArcServiceTest::DeviceHandler,
110 base::Unretained(this)));
111 }
112
113 void DeviceHandler(const Device& device,
114 Device::ChangeEvent event,
115 GuestMessage::GuestType guest_type) {
116 guest_devices_[device.host_ifname()] = event;
Garrick Evans54861622019-07-19 09:05:09 +0900117 }
118
Garrick Evans69b85872020-02-04 11:40:26 +0900119 FakeShillClientHelper shill_helper_;
Hugo Benichi84d96c42021-02-26 14:20:13 +0900120 std::unique_ptr<MockShillClient> shill_client_;
Garrick Evans4ee5ce22020-03-18 07:05:17 +0900121 std::unique_ptr<AddressManager> addr_mgr_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900122 MockTrafficForwarder forwarder_;
Taoyu Li179dcc62019-10-17 11:21:08 +0900123 std::unique_ptr<MockDatapath> datapath_;
124 std::unique_ptr<FakeProcessRunner> runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900125 MockFirewall firewall_;
Garrick Evans209a80a2020-11-30 14:42:40 +0900126 std::map<std::string, Device::ChangeEvent> guest_devices_;
Garrick Evans54861622019-07-19 09:05:09 +0900127};
128
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900129TEST_F(ArcServiceTest, NotStarted_AddDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900130 ExpectGetDeviceProperties(*shill_client_, "eth0",
131 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900132 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900133 EXPECT_CALL(*datapath_,
Hugo Benichi93306e52020-12-04 16:08:00 +0900134 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _, false))
Hugo Benichi8d622b52020-08-13 15:24:12 +0900135 .Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900136
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900137 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900138 svc->OnDevicesChanged({"eth0"}, {});
139 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
140 EXPECT_FALSE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900141}
142
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900143TEST_F(ArcServiceTest, NotStarted_AddRemoveDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900144 ExpectGetDeviceProperties(*shill_client_, "eth0",
145 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900146 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900147 EXPECT_CALL(*datapath_,
Hugo Benichi93306e52020-12-04 16:08:00 +0900148 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _, false))
Hugo Benichi8d622b52020-08-13 15:24:12 +0900149 .Times(0);
150 EXPECT_CALL(*datapath_,
Hugo Benichi93306e52020-12-04 16:08:00 +0900151 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _, false))
Hugo Benichi8d622b52020-08-13 15:24:12 +0900152 .Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900153 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900154
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900155 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900156 svc->OnDevicesChanged({"eth0"}, {});
157 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900158 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
Hugo Benichif0f10c72020-07-09 10:42:45 +0900159 EXPECT_TRUE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900160}
161
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900162TEST_F(ArcServiceTest, VerifyAddrConfigs) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900163 ExpectGetDeviceProperties(*shill_client_, "eth0",
164 ShillClient::Device::Type::kEthernet);
165 ExpectGetDeviceProperties(*shill_client_, "eth1",
166 ShillClient::Device::Type::kEthernet);
167 ExpectGetDeviceProperties(*shill_client_, "wlan0",
168 ShillClient::Device::Type::kWifi);
169 ExpectGetDeviceProperties(*shill_client_, "wlan1",
170 ShillClient::Device::Type::kWifi);
171 ExpectGetDeviceProperties(*shill_client_, "wwan0",
172 ShillClient::Device::Type::kCellular);
Hugo Benichi33860d72020-07-09 16:34:01 +0900173 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
174 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900175 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
176 .WillOnce(Return(true));
177 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900178 .WillOnce(Return(true));
179 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
180 .WillOnce(Return(true));
181 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
182 .WillOnce(Return(true));
183 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
184 .WillOnce(Return(true));
185 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
186 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900187 EXPECT_CALL(*datapath_,
188 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900189 .WillRepeatedly(Return(true));
190 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900191
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900192 auto svc = NewService(GuestMessage::ARC);
193 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900194 svc->OnDevicesChanged({"eth0", "eth1", "wlan0", "wlan1", "wwan0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900195}
196
197TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900198 ExpectGetDeviceProperties(*shill_client_, "wlan0",
199 ShillClient::Device::Type::kWifi);
200 ExpectGetDeviceProperties(*shill_client_, "eth0",
201 ShillClient::Device::Type::kEthernet);
Hugo Benichi33860d72020-07-09 16:34:01 +0900202 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
203 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900204 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
205 .WillOnce(Return(true));
206 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900207 .Times(2)
208 .WillRepeatedly(Return(true));
209 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
210 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900211 EXPECT_CALL(*datapath_,
212 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900213 .WillRepeatedly(Return(true));
214 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900215
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900216 auto svc = NewService(GuestMessage::ARC);
217 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900218 svc->OnDevicesChanged({"wlan0"}, {});
219 svc->OnDevicesChanged({"eth0"}, {});
220 svc->OnDevicesChanged({}, {"eth0"});
221 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900222}
223
Garrick Evansc7071122020-04-17 12:31:57 +0900224TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
225 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
226 .WillRepeatedly(Return("vmtap"));
227 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
228 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
229
230 auto svc = NewService(GuestMessage::ARC_VM);
231 svc->Start(kTestCID);
232 auto configs = svc->GetDeviceConfigs();
233 EXPECT_EQ(configs.size(), 6);
234 auto mac_addr = kArcVmArc0MacAddr;
235 for (const auto* config : configs) {
236 EXPECT_EQ(config->mac_addr(), mac_addr);
237 mac_addr[5]++;
238 }
239}
240
Garrick Evansb4eb3892019-11-13 12:07:07 +0900241// ContainerImpl
242
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900243TEST_F(ArcServiceTest, ContainerImpl_Start) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900244 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
245 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900246 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900247 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
248 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900249 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900250 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900251 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900252 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
253 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900254 EXPECT_CALL(forwarder_, StartForwarding(_, _, _, _)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900255
256 auto svc = NewService(GuestMessage::ARC);
257 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900258}
259
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900260TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900261 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
262 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900263 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900264 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
265 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900266 .WillOnce(Return(false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900267 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30)).Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900268 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900269
270 auto svc = NewService(GuestMessage::ARC);
271 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900272}
273
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900274TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900275 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
276 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900277 EXPECT_CALL(*datapath_,
278 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
279 StrEq("arc0"), _, kArcGuestIP, 30, false))
280 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900281 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
282 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900283 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
284 .WillOnce(Return(false));
285
286 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
287 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
288
289 auto svc = NewService(GuestMessage::ARC);
290 svc->Start(kTestPID);
291}
292
293TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900294 ExpectGetDeviceProperties(*shill_client_, "eth0",
295 ShillClient::Device::Type::kEthernet);
Hugo Benichi33860d72020-07-09 16:34:01 +0900296 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
297 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900298 // 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 Benichiad1bdd92020-06-12 13:48:37 +0900303 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
304 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900305 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
306 .WillOnce(Return(true));
307 // Expectations for eth0 setup.
Garrick Evansb4eb3892019-11-13 12:07:07 +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))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900311 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900312 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2470caa2020-03-04 14:15:41 +0900313 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900314 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900315 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900316 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"),
Hugo Benichi93306e52020-12-04 16:08:00 +0900320 kFirstEthGuestIP, TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900321
322 auto svc = NewService(GuestMessage::ARC);
323 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900324 svc->OnDevicesChanged({"eth0"}, {});
325}
326
Garrick Evans02e6e872020-11-30 11:53:13 +0900327TEST_F(ArcServiceTest, ContainerImpl_ScanDevices) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900328 ExpectGetDeviceProperties(*shill_client_, "eth0",
329 ShillClient::Device::Type::kEthernet);
330 ExpectGetDeviceProperties(*shill_client_, "wlan0",
331 ShillClient::Device::Type::kWifi);
Garrick Evans02e6e872020-11-30 11:53:13 +0900332 EXPECT_CALL(*datapath_, NetnsAttachName(_, _)).WillRepeatedly(Return(true));
333 EXPECT_CALL(*datapath_, ConnectVethPair(_, _, _, _, _, _, _, _))
334 .WillRepeatedly(Return(true));
335 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
336 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
337
338 auto svc = NewService(GuestMessage::ARC);
339 svc->Start(kTestPID);
340 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
341
342 std::vector<std::string> devs;
343 svc->ScanDevices(base::BindRepeating(
344 [](std::vector<std::string>* list, const Device& device) {
345 list->push_back(device.host_ifname());
346 },
347 &devs));
348
349 EXPECT_EQ(devs.size(), 2);
350 EXPECT_THAT(devs,
351 UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0")));
352}
353
Garrick Evans209a80a2020-11-30 14:42:40 +0900354TEST_F(ArcServiceTest, ContainerImpl_DeviceHandler) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900355 ExpectGetDeviceProperties(*shill_client_, "eth0",
356 ShillClient::Device::Type::kEthernet);
357 ExpectGetDeviceProperties(*shill_client_, "wlan0",
358 ShillClient::Device::Type::kWifi);
Garrick Evans209a80a2020-11-30 14:42:40 +0900359 EXPECT_CALL(*datapath_, NetnsAttachName(_, _)).WillRepeatedly(Return(true));
360 EXPECT_CALL(*datapath_, ConnectVethPair(_, _, _, _, _, _, _, _))
361 .WillRepeatedly(Return(true));
362 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
363 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
364
365 auto svc = NewService(GuestMessage::ARC);
366 svc->Start(kTestPID);
367
368 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
369 EXPECT_EQ(guest_devices_.size(), 2);
370 EXPECT_THAT(guest_devices_,
371 UnorderedElementsAre(
372 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
373 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
374
375 svc->OnDevicesChanged({}, {"wlan0"});
376 EXPECT_THAT(guest_devices_,
377 UnorderedElementsAre(
378 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
379 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::REMOVED)));
380
381 guest_devices_.clear();
382 svc->OnDevicesChanged({"wlan0"}, {});
383 EXPECT_THAT(guest_devices_,
384 UnorderedElementsAre(
385 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
386}
387
Hugo Benichif0f10c72020-07-09 10:42:45 +0900388TEST_F(ArcServiceTest, ContainerImpl_StartAfterDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900389 ExpectGetDeviceProperties(*shill_client_, "eth0",
390 ShillClient::Device::Type::kEthernet);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900391 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
392 .WillOnce(Return(true));
393 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900394 EXPECT_CALL(*datapath_,
395 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
396 StrEq("arc0"), _, kArcGuestIP, 30, false))
397 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900398 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
399 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900400 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
401 .WillOnce(Return(true));
402 // Expectations for eth0 setup.
Hugo Benichif0f10c72020-07-09 10:42:45 +0900403 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900404 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
405 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900406 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900407 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900408 .WillOnce(Return(true));
409 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
410 .WillOnce(Return(true));
411 EXPECT_CALL(forwarder_,
412 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900413 EXPECT_CALL(*datapath_,
414 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
Hugo Benichi93306e52020-12-04 16:08:00 +0900415 kFirstEthGuestIP, TrafficSource::ARC, false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900416
417 auto svc = NewService(GuestMessage::ARC);
418 svc->OnDevicesChanged({"eth0"}, {});
419 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900420}
421
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900422TEST_F(ArcServiceTest, ContainerImpl_Stop) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900423 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
424 .WillOnce(Return(true));
425 EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
426 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900427 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900428 EXPECT_CALL(*datapath_,
429 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
430 StrEq("arc0"), _, kArcGuestIP, 30, false))
431 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900432 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
433 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900434 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
435 .WillOnce(Return(true));
436 // Expectations for arc0 teardown.
437 EXPECT_CALL(*datapath_,
438 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
439 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900440 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900441 EXPECT_CALL(forwarder_, StopForwarding(_, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900442
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900443 auto svc = NewService(GuestMessage::ARC);
444 svc->Start(kTestPID);
445 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900446}
447
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900448TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900449 ExpectGetDeviceProperties(*shill_client_, "eth0",
450 ShillClient::Device::Type::kEthernet);
Hugo Benichi33860d72020-07-09 16:34:01 +0900451 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
452 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900453 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900454 EXPECT_CALL(*datapath_,
455 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
456 StrEq("arc0"), _, kArcGuestIP, 30, false))
457 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900458 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
459 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900460 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
461 .WillOnce(Return(true));
462 // Expectations for eth0 setup.
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900463 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900464 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
465 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900466 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900467 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900468 .WillOnce(Return(true));
469 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
470 .WillOnce(Return(true));
471 // Expectations for eth0 teardown.
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900472 EXPECT_CALL(forwarder_,
473 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi93306e52020-12-04 16:08:00 +0900474 EXPECT_CALL(*datapath_, StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
475 Ipv4Addr(100, 115, 92, 6),
476 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900477 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900478
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900479 auto svc = NewService(GuestMessage::ARC);
480 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900481 svc->OnDevicesChanged({"eth0"}, {});
482 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evansb4eb3892019-11-13 12:07:07 +0900483}
484
Garrick Evansb4eb3892019-11-13 12:07:07 +0900485// VM Impl
486
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900487TEST_F(ArcServiceTest, VmImpl_Start) {
488 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900489 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900490 .WillOnce(Return("vmtap0"))
491 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900492 .WillOnce(Return("vmtap2"))
493 .WillOnce(Return("vmtap3"))
494 .WillOnce(Return("vmtap4"))
495 .WillOnce(Return("vmtap5"));
496 // Expectations for "arc0" setup.
497 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900498 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900499 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900500 .WillOnce(Return(true));
501
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900502 auto svc = NewService(GuestMessage::ARC_VM);
503 svc->Start(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900504}
505
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900506TEST_F(ArcServiceTest, VmImpl_StartDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900507 ExpectGetDeviceProperties(*shill_client_, "eth0",
508 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900509 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900510 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900511 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900512 .WillOnce(Return("vmtap1"))
513 .WillOnce(Return("vmtap2"))
514 .WillOnce(Return("vmtap3"))
515 .WillOnce(Return("vmtap4"))
516 .WillOnce(Return("vmtap5"));
517 // Expectations for "arc0" setup.
518 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900519 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900520 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
521 .WillOnce(Return(true));
522 // Expectations for eth0 setup.
523 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900524 .WillOnce(Return(true));
525 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
526 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900527 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
528 Ipv4Addr(100, 115, 92, 6),
Hugo Benichi93306e52020-12-04 16:08:00 +0900529 TrafficSource::ARC, false));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900530 EXPECT_CALL(forwarder_,
531 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
532
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900533 auto svc = NewService(GuestMessage::ARC_VM);
534 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900535 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900536}
537
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900538TEST_F(ArcServiceTest, VmImpl_StartMultipleDevices) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900539 ExpectGetDeviceProperties(*shill_client_, "eth0",
540 ShillClient::Device::Type::kEthernet);
541 ExpectGetDeviceProperties(*shill_client_, "eth1",
542 ShillClient::Device::Type::kEthernet);
543 ExpectGetDeviceProperties(*shill_client_, "wlan0",
544 ShillClient::Device::Type::kWifi);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900545 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900546 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900547 .WillOnce(Return("vmtap0"))
548 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900549 .WillOnce(Return("vmtap2"))
550 .WillOnce(Return("vmtap3"))
551 .WillOnce(Return("vmtap4"))
552 .WillOnce(Return("vmtap5"));
553 // Expectations for "arc0" setup.
554 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900555 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900556 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900557 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900558 // Expectations for eth0 setup.
559 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
560 .WillOnce(Return(true));
561 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
562 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900563 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
564 Ipv4Addr(100, 115, 92, 6),
Hugo Benichi93306e52020-12-04 16:08:00 +0900565 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900566 EXPECT_CALL(forwarder_,
567 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
568 // Expectations for wlan0 setup.
569 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
570 .WillOnce(Return(true));
571 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_wlan0"), StrEq("vmtap3")))
572 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900573 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("wlan0"), StrEq("arc_wlan0"),
574 Ipv4Addr(100, 115, 92, 14),
Hugo Benichi93306e52020-12-04 16:08:00 +0900575 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900576 EXPECT_CALL(forwarder_,
577 StartForwarding(StrEq("wlan0"), StrEq("arc_wlan0"), _, _));
578 // Expectations for eth1 setup.
579 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
580 .WillOnce(Return(true));
581 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth1"), StrEq("vmtap2")))
582 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900583 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth1"), StrEq("arc_eth1"),
584 Ipv4Addr(100, 115, 92, 10),
Hugo Benichi93306e52020-12-04 16:08:00 +0900585 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900586 EXPECT_CALL(forwarder_,
587 StartForwarding(StrEq("eth1"), StrEq("arc_eth1"), _, _));
588
589 auto svc = NewService(GuestMessage::ARC_VM);
590 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900591 svc->OnDevicesChanged({"eth0"}, {});
592 svc->OnDevicesChanged({"wlan0"}, {});
593 svc->OnDevicesChanged({"eth1"}, {});
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900594}
595
596TEST_F(ArcServiceTest, VmImpl_Stop) {
597 // Expectations for tap devices pre-creation.
598 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
599 .WillOnce(Return("vmtap0"))
600 .WillOnce(Return("vmtap1"))
601 .WillOnce(Return("vmtap2"))
602 .WillOnce(Return("vmtap3"))
603 .WillOnce(Return("vmtap4"))
604 .WillOnce(Return("vmtap5"));
605 // Expectations for "arc0" setup.
606 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
607 .WillOnce(Return(true));
608 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
609 .WillOnce(Return(true));
610 // Expectations for "arc0" teardown.
611 EXPECT_CALL(*datapath_,
612 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
613 .WillOnce(Return(true));
614 // Expectations for tap devices teardown
Garrick Evans2961c7c2020-04-03 11:34:40 +0900615 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap0")));
616 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap1")));
617 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap2")));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900618 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap3")));
619 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap4")));
620 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap5")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900621
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900622 auto svc = NewService(GuestMessage::ARC_VM);
623 svc->Start(kTestPID);
624 svc->Stop(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900625}
626
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900627TEST_F(ArcServiceTest, VmImpl_StopDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900628 ExpectGetDeviceProperties(*shill_client_, "eth0",
629 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900630 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900631 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900632 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900633 .WillOnce(Return("vmtap1"))
634 .WillOnce(Return("vmtap2"))
635 .WillOnce(Return("vmtap3"))
636 .WillOnce(Return("vmtap4"))
637 .WillOnce(Return("vmtap5"));
638 // Expectations for "arc0" setup.
639 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900640 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900641 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900642 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900643 // Expectations for eth0 setup.
644 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
645 .WillOnce(Return(true));
646 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
647 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900648 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
649 Ipv4Addr(100, 115, 92, 6),
Hugo Benichi93306e52020-12-04 16:08:00 +0900650 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900651 EXPECT_CALL(forwarder_,
652 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
653 // Expectations for eth0 teardown.
Garrick Evans2961c7c2020-04-03 11:34:40 +0900654 EXPECT_CALL(forwarder_,
655 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi93306e52020-12-04 16:08:00 +0900656 EXPECT_CALL(*datapath_, StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
657 Ipv4Addr(100, 115, 92, 6),
658 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900659 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900660
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900661 auto svc = NewService(GuestMessage::ARC_VM);
662 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900663 svc->OnDevicesChanged({"eth0"}, {});
664 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900665}
Garrick Evans3388a032020-03-24 11:25:55 +0900666
Garrick Evans02e6e872020-11-30 11:53:13 +0900667TEST_F(ArcServiceTest, VmImpl_ScanDevices) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900668 ExpectGetDeviceProperties(*shill_client_, "eth0",
669 ShillClient::Device::Type::kEthernet);
670 ExpectGetDeviceProperties(*shill_client_, "eth1",
671 ShillClient::Device::Type::kEthernet);
672 ExpectGetDeviceProperties(*shill_client_, "wlan0",
673 ShillClient::Device::Type::kWifi);
Garrick Evans02e6e872020-11-30 11:53:13 +0900674 // Expectations for tap devices pre-creation.
675 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
676 .WillOnce(Return("vmtap0"))
677 .WillOnce(Return("vmtap1"))
678 .WillOnce(Return("vmtap2"))
679 .WillOnce(Return("vmtap3"))
680 .WillOnce(Return("vmtap4"))
681 .WillOnce(Return("vmtap5"));
682 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
683 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
684
685 auto svc = NewService(GuestMessage::ARC_VM);
686 svc->Start(kTestPID);
687 svc->OnDevicesChanged({"eth0", "wlan0", "eth1"}, {});
688
689 std::vector<std::string> devs;
690 svc->ScanDevices(base::BindRepeating(
691 [](std::vector<std::string>* list, const Device& device) {
692 list->push_back(device.host_ifname());
693 },
694 &devs));
695
696 EXPECT_EQ(devs.size(), 3);
697 EXPECT_THAT(devs, UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0"),
698 StrEq("arc_eth1")));
699}
700
Garrick Evans209a80a2020-11-30 14:42:40 +0900701TEST_F(ArcServiceTest, VmImpl_DeviceHandler) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900702 ExpectGetDeviceProperties(*shill_client_, "eth0",
703 ShillClient::Device::Type::kEthernet);
704 ExpectGetDeviceProperties(*shill_client_, "wlan0",
705 ShillClient::Device::Type::kWifi);
Garrick Evans209a80a2020-11-30 14:42:40 +0900706 // Expectations for tap devices pre-creation.
707 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
708 .WillOnce(Return("vmtap0"))
709 .WillOnce(Return("vmtap1"))
710 .WillOnce(Return("vmtap2"))
711 .WillOnce(Return("vmtap3"))
712 .WillOnce(Return("vmtap4"))
713 .WillOnce(Return("vmtap5"));
714 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
715 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
716
717 auto svc = NewService(GuestMessage::ARC_VM);
718 svc->Start(kTestPID);
719
720 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
721 EXPECT_EQ(guest_devices_.size(), 2);
722 EXPECT_THAT(guest_devices_,
723 UnorderedElementsAre(
724 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
725 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
726
727 svc->OnDevicesChanged({}, {"wlan0"});
728 EXPECT_THAT(guest_devices_,
729 UnorderedElementsAre(
730 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
731 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::REMOVED)));
732
733 guest_devices_.clear();
734 svc->OnDevicesChanged({"wlan0"}, {});
735 EXPECT_THAT(guest_devices_,
736 UnorderedElementsAre(
737 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
738}
739
Garrick Evans3388a032020-03-24 11:25:55 +0900740} // namespace patchpanel