blob: 676233ea7f7b689bda2255f10a6a45a95c53a8f7 [file] [log] [blame]
Garrick Evans54861622019-07-19 09:05:09 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/arc_service.h"
Garrick Evans54861622019-07-19 09:05:09 +09006
Garrick Evanse94b6de2020-02-20 09:19:13 +09007#include <net/if.h>
8
Garrick Evans54861622019-07-19 09:05:09 +09009#include <utility>
10#include <vector>
11
12#include <base/bind.h>
13
14#include <gmock/gmock.h>
15#include <gtest/gtest.h>
16
Garrick Evans3388a032020-03-24 11:25:55 +090017#include "patchpanel/address_manager.h"
18#include "patchpanel/fake_process_runner.h"
19#include "patchpanel/fake_shill_client.h"
20#include "patchpanel/mock_datapath.h"
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090021#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090022#include "patchpanel/net_util.h"
Garrick Evans54861622019-07-19 09:05:09 +090023
24using testing::_;
Garrick Evanse94b6de2020-02-20 09:19:13 +090025using testing::AnyNumber;
Garrick Evansc7071122020-04-17 12:31:57 +090026using testing::Eq;
27using testing::Pointee;
Garrick Evans54861622019-07-19 09:05:09 +090028using testing::Return;
Garrick Evansb4eb3892019-11-13 12:07:07 +090029using testing::ReturnRef;
Garrick Evans54861622019-07-19 09:05:09 +090030using testing::StrEq;
31
Garrick Evans3388a032020-03-24 11:25:55 +090032namespace patchpanel {
Garrick Evans54861622019-07-19 09:05:09 +090033namespace {
Garrick Evansb4eb3892019-11-13 12:07:07 +090034constexpr pid_t kTestPID = -2;
Garrick Evansb4eb3892019-11-13 12:07:07 +090035constexpr uint32_t kTestCID = 2;
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090036constexpr uint32_t kArcHostIP = Ipv4Addr(100, 115, 92, 1);
37constexpr uint32_t kArcGuestIP = Ipv4Addr(100, 115, 92, 2);
Hugo Benichiad1bdd92020-06-12 13:48:37 +090038constexpr uint32_t kFirstEthHostIP = Ipv4Addr(100, 115, 92, 5);
39constexpr uint32_t kFirstEthGuestIP = Ipv4Addr(100, 115, 92, 6);
Garrick Evans86c7d9c2020-03-17 09:25:48 +090040constexpr uint32_t kSecondEthHostIP = Ipv4Addr(100, 115, 92, 9);
41constexpr uint32_t kFirstWifiHostIP = Ipv4Addr(100, 115, 92, 13);
42constexpr uint32_t kSecondWifiHostIP = Ipv4Addr(100, 115, 92, 17);
43constexpr uint32_t kFirstCellHostIP = Ipv4Addr(100, 115, 92, 21);
Garrick Evansc7071122020-04-17 12:31:57 +090044constexpr MacAddress kArcVmArc0MacAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x01};
Garrick Evans54861622019-07-19 09:05:09 +090045
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090046class MockTrafficForwarder : public TrafficForwarder {
47 public:
48 MockTrafficForwarder() = default;
49 ~MockTrafficForwarder() = default;
50
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +090051 MOCK_METHOD4(StartForwarding,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090052 void(const std::string& ifname_physical,
53 const std::string& ifname_virtual,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090054 bool ipv6,
55 bool multicast));
56
57 MOCK_METHOD4(StopForwarding,
58 void(const std::string& ifname_physical,
59 const std::string& ifname_virtual,
60 bool ipv6,
61 bool multicast));
62};
63
Garrick Evans54861622019-07-19 09:05:09 +090064} // namespace
65
66class ArcServiceTest : public testing::Test {
67 public:
Garrick Evans4ee5ce22020-03-18 07:05:17 +090068 ArcServiceTest() : testing::Test() {}
Garrick Evans54861622019-07-19 09:05:09 +090069
70 protected:
71 void SetUp() override {
Taoyu Li179dcc62019-10-17 11:21:08 +090072 runner_ = std::make_unique<FakeProcessRunner>();
Garrick Evans54861622019-07-19 09:05:09 +090073 runner_->Capture(false);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090074 datapath_ = std::make_unique<MockDatapath>(runner_.get(), &firewall_);
Garrick Evans69b85872020-02-04 11:40:26 +090075 shill_client_ = shill_helper_.Client();
Garrick Evans4ee5ce22020-03-18 07:05:17 +090076 addr_mgr_ = std::make_unique<AddressManager>();
Garrick Evans54861622019-07-19 09:05:09 +090077 }
78
Hugo Benichiad1bdd92020-06-12 13:48:37 +090079 std::unique_ptr<ArcService> NewService(GuestMessage::GuestType guest) {
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090080 return std::make_unique<ArcService>(shill_client_.get(), datapath_.get(),
Hugo Benichiad1bdd92020-06-12 13:48:37 +090081 addr_mgr_.get(), &forwarder_, guest);
Garrick Evans54861622019-07-19 09:05:09 +090082 }
83
Garrick Evans69b85872020-02-04 11:40:26 +090084 FakeShillClientHelper shill_helper_;
85 std::unique_ptr<ShillClient> shill_client_;
Garrick Evans4ee5ce22020-03-18 07:05:17 +090086 std::unique_ptr<AddressManager> addr_mgr_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090087 MockTrafficForwarder forwarder_;
Taoyu Li179dcc62019-10-17 11:21:08 +090088 std::unique_ptr<MockDatapath> datapath_;
89 std::unique_ptr<FakeProcessRunner> runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090090 MockFirewall firewall_;
Garrick Evans54861622019-07-19 09:05:09 +090091};
92
Hugo Benichiad1bdd92020-06-12 13:48:37 +090093TEST_F(ArcServiceTest, NotStarted_AddDevice) {
94 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +090095 EXPECT_CALL(*datapath_,
96 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
97 .Times(0);
Garrick Evans54861622019-07-19 09:05:09 +090098
Hugo Benichiad1bdd92020-06-12 13:48:37 +090099 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900100 svc->OnDevicesChanged({"eth0"}, {});
101 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
102 EXPECT_FALSE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900103}
104
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900105TEST_F(ArcServiceTest, NotStarted_AddRemoveDevice) {
106 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900107 EXPECT_CALL(*datapath_,
108 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
109 .Times(0);
110 EXPECT_CALL(*datapath_,
111 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
112 .Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900113 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900114
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900115 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900116 svc->OnDevicesChanged({"eth0"}, {});
117 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900118 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
Hugo Benichif0f10c72020-07-09 10:42:45 +0900119 EXPECT_TRUE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900120}
121
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900122TEST_F(ArcServiceTest, VerifyAddrConfigs) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900123 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
124 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900125 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
126 .WillOnce(Return(true));
127 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900128 .WillOnce(Return(true));
129 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
130 .WillOnce(Return(true));
131 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
132 .WillOnce(Return(true));
133 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
134 .WillOnce(Return(true));
135 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
136 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900137 EXPECT_CALL(*datapath_,
138 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900139 .WillRepeatedly(Return(true));
140 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900141
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900142 auto svc = NewService(GuestMessage::ARC);
143 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900144 svc->OnDevicesChanged({"eth0", "eth1", "wlan0", "wlan1", "wwan0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900145}
146
147TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900148 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
149 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900150 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
151 .WillOnce(Return(true));
152 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900153 .Times(2)
154 .WillRepeatedly(Return(true));
155 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
156 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900157 EXPECT_CALL(*datapath_,
158 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900159 .WillRepeatedly(Return(true));
160 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900161
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900162 auto svc = NewService(GuestMessage::ARC);
163 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900164 svc->OnDevicesChanged({"wlan0"}, {});
165 svc->OnDevicesChanged({"eth0"}, {});
166 svc->OnDevicesChanged({}, {"eth0"});
167 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900168}
169
Garrick Evansc7071122020-04-17 12:31:57 +0900170TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
171 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
172 .WillRepeatedly(Return("vmtap"));
173 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
174 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
175
176 auto svc = NewService(GuestMessage::ARC_VM);
177 svc->Start(kTestCID);
178 auto configs = svc->GetDeviceConfigs();
179 EXPECT_EQ(configs.size(), 6);
180 auto mac_addr = kArcVmArc0MacAddr;
181 for (const auto* config : configs) {
182 EXPECT_EQ(config->mac_addr(), mac_addr);
183 mac_addr[5]++;
184 }
185}
186
Garrick Evansb4eb3892019-11-13 12:07:07 +0900187// ContainerImpl
188
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900189TEST_F(ArcServiceTest, ContainerImpl_Start) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900190 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
191 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900192 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900193 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
194 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900195 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900196 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900197 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900198 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
199 .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 Evans63378b32020-01-14 10:36:16 +0900209 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900210 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
211 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900212 .WillOnce(Return(false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900213 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30)).Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900214 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900215
216 auto svc = NewService(GuestMessage::ARC);
217 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900218}
219
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900220TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900221 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
222 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900223 EXPECT_CALL(*datapath_,
224 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
225 StrEq("arc0"), _, kArcGuestIP, 30, false))
226 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900227 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
228 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900229 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
230 .WillOnce(Return(false));
231
232 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
233 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
234
235 auto svc = NewService(GuestMessage::ARC);
236 svc->Start(kTestPID);
237}
238
239TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900240 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
241 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900242 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900243 EXPECT_CALL(*datapath_,
244 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
245 StrEq("arc0"), _, kArcGuestIP, 30, false))
246 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900247 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
248 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900249 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
250 .WillOnce(Return(true));
251 // Expectations for eth0 setup.
Garrick Evansb4eb3892019-11-13 12:07:07 +0900252 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900253 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
254 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900255 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900256 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2470caa2020-03-04 14:15:41 +0900257 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900258 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900259 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900260 EXPECT_CALL(forwarder_,
261 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900262 EXPECT_CALL(*datapath_,
263 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
264 kFirstEthGuestIP, TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900265
266 auto svc = NewService(GuestMessage::ARC);
267 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900268 svc->OnDevicesChanged({"eth0"}, {});
269}
270
271TEST_F(ArcServiceTest, ContainerImpl_StartAfterDevice) {
272 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
273 .WillOnce(Return(true));
274 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900275 EXPECT_CALL(*datapath_,
276 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
277 StrEq("arc0"), _, kArcGuestIP, 30, false))
278 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900279 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
280 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900281 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
282 .WillOnce(Return(true));
283 // Expectations for eth0 setup.
Hugo Benichif0f10c72020-07-09 10:42:45 +0900284 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900285 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
286 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900287 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900288 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900289 .WillOnce(Return(true));
290 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
291 .WillOnce(Return(true));
292 EXPECT_CALL(forwarder_,
293 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900294 EXPECT_CALL(*datapath_,
295 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
296 kFirstEthGuestIP, TrafficSource::ARC));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900297
298 auto svc = NewService(GuestMessage::ARC);
299 svc->OnDevicesChanged({"eth0"}, {});
300 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900301}
302
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900303TEST_F(ArcServiceTest, ContainerImpl_Stop) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900304 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
305 .WillOnce(Return(true));
306 EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
307 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900308 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900309 EXPECT_CALL(*datapath_,
310 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
311 StrEq("arc0"), _, kArcGuestIP, 30, false))
312 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900313 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
314 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900315 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
316 .WillOnce(Return(true));
317 // Expectations for arc0 teardown.
318 EXPECT_CALL(*datapath_,
319 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
320 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900321 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900322 EXPECT_CALL(forwarder_, StopForwarding(_, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900323
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900324 auto svc = NewService(GuestMessage::ARC);
325 svc->Start(kTestPID);
326 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900327}
328
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900329TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900330 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
331 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900332 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900333 EXPECT_CALL(*datapath_,
334 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
335 StrEq("arc0"), _, kArcGuestIP, 30, false))
336 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900337 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
338 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900339 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
340 .WillOnce(Return(true));
341 // Expectations for eth0 setup.
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900342 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900343 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
344 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900345 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900346 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900347 .WillOnce(Return(true));
348 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
349 .WillOnce(Return(true));
350 // Expectations for eth0 teardown.
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900351 EXPECT_CALL(forwarder_,
352 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900353 EXPECT_CALL(*datapath_,
Hugo Benichi8d622b52020-08-13 15:24:12 +0900354 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
355 Ipv4Addr(100, 115, 92, 6), TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900356 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900357
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900358 auto svc = NewService(GuestMessage::ARC);
359 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900360 svc->OnDevicesChanged({"eth0"}, {});
361 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evansb4eb3892019-11-13 12:07:07 +0900362}
363
Garrick Evansb4eb3892019-11-13 12:07:07 +0900364// VM Impl
365
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900366TEST_F(ArcServiceTest, VmImpl_Start) {
367 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900368 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900369 .WillOnce(Return("vmtap0"))
370 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900371 .WillOnce(Return("vmtap2"))
372 .WillOnce(Return("vmtap3"))
373 .WillOnce(Return("vmtap4"))
374 .WillOnce(Return("vmtap5"));
375 // Expectations for "arc0" setup.
376 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900377 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900378 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900379 .WillOnce(Return(true));
380
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900381 auto svc = NewService(GuestMessage::ARC_VM);
382 svc->Start(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900383}
384
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900385TEST_F(ArcServiceTest, VmImpl_StartDevice) {
386 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900387 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900388 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900389 .WillOnce(Return("vmtap1"))
390 .WillOnce(Return("vmtap2"))
391 .WillOnce(Return("vmtap3"))
392 .WillOnce(Return("vmtap4"))
393 .WillOnce(Return("vmtap5"));
394 // Expectations for "arc0" setup.
395 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900396 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900397 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
398 .WillOnce(Return(true));
399 // Expectations for eth0 setup.
400 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900401 .WillOnce(Return(true));
402 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
403 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900404 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
405 Ipv4Addr(100, 115, 92, 6),
406 TrafficSource::ARC));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900407 EXPECT_CALL(forwarder_,
408 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
409
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900410 auto svc = NewService(GuestMessage::ARC_VM);
411 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900412 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900413}
414
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900415TEST_F(ArcServiceTest, VmImpl_StartMultipleDevices) {
416 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900417 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900418 .WillOnce(Return("vmtap0"))
419 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900420 .WillOnce(Return("vmtap2"))
421 .WillOnce(Return("vmtap3"))
422 .WillOnce(Return("vmtap4"))
423 .WillOnce(Return("vmtap5"));
424 // Expectations for "arc0" setup.
425 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900426 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900427 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900428 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900429 // Expectations for eth0 setup.
430 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
431 .WillOnce(Return(true));
432 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
433 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900434 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
435 Ipv4Addr(100, 115, 92, 6),
436 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900437 EXPECT_CALL(forwarder_,
438 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
439 // Expectations for wlan0 setup.
440 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
441 .WillOnce(Return(true));
442 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_wlan0"), StrEq("vmtap3")))
443 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900444 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("wlan0"), StrEq("arc_wlan0"),
445 Ipv4Addr(100, 115, 92, 14),
446 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900447 EXPECT_CALL(forwarder_,
448 StartForwarding(StrEq("wlan0"), StrEq("arc_wlan0"), _, _));
449 // Expectations for eth1 setup.
450 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
451 .WillOnce(Return(true));
452 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth1"), StrEq("vmtap2")))
453 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900454 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth1"), StrEq("arc_eth1"),
455 Ipv4Addr(100, 115, 92, 10),
456 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900457 EXPECT_CALL(forwarder_,
458 StartForwarding(StrEq("eth1"), StrEq("arc_eth1"), _, _));
459
460 auto svc = NewService(GuestMessage::ARC_VM);
461 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900462 svc->OnDevicesChanged({"eth0"}, {});
463 svc->OnDevicesChanged({"wlan0"}, {});
464 svc->OnDevicesChanged({"eth1"}, {});
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900465}
466
467TEST_F(ArcServiceTest, VmImpl_Stop) {
468 // Expectations for tap devices pre-creation.
469 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
470 .WillOnce(Return("vmtap0"))
471 .WillOnce(Return("vmtap1"))
472 .WillOnce(Return("vmtap2"))
473 .WillOnce(Return("vmtap3"))
474 .WillOnce(Return("vmtap4"))
475 .WillOnce(Return("vmtap5"));
476 // Expectations for "arc0" setup.
477 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
478 .WillOnce(Return(true));
479 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
480 .WillOnce(Return(true));
481 // Expectations for "arc0" teardown.
482 EXPECT_CALL(*datapath_,
483 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
484 .WillOnce(Return(true));
485 // Expectations for tap devices teardown
Garrick Evans2961c7c2020-04-03 11:34:40 +0900486 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap0")));
487 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap1")));
488 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap2")));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900489 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap3")));
490 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap4")));
491 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap5")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900492
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900493 auto svc = NewService(GuestMessage::ARC_VM);
494 svc->Start(kTestPID);
495 svc->Stop(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900496}
497
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900498TEST_F(ArcServiceTest, VmImpl_StopDevice) {
499 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900500 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900501 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900502 .WillOnce(Return("vmtap1"))
503 .WillOnce(Return("vmtap2"))
504 .WillOnce(Return("vmtap3"))
505 .WillOnce(Return("vmtap4"))
506 .WillOnce(Return("vmtap5"));
507 // Expectations for "arc0" setup.
508 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900509 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900510 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900511 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900512 // Expectations for eth0 setup.
513 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
514 .WillOnce(Return(true));
515 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
516 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900517 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
518 Ipv4Addr(100, 115, 92, 6),
519 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900520 EXPECT_CALL(forwarder_,
521 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
522 // Expectations for eth0 teardown.
Garrick Evans2961c7c2020-04-03 11:34:40 +0900523 EXPECT_CALL(forwarder_,
524 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900525 EXPECT_CALL(*datapath_,
Hugo Benichi8d622b52020-08-13 15:24:12 +0900526 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
527 Ipv4Addr(100, 115, 92, 6), TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900528 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900529
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900530 auto svc = NewService(GuestMessage::ARC_VM);
531 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900532 svc->OnDevicesChanged({"eth0"}, {});
533 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900534}
Garrick Evans3388a032020-03-24 11:25:55 +0900535
536} // namespace patchpanel