blob: 568ac58405235a6ace68d8e5b445d05a9263cb09 [file] [log] [blame]
Garrick Evans5d55f5e2019-07-17 15:28:10 +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
5#ifndef ARC_NETWORK_ARC_SERVICE_H_
6#define ARC_NETWORK_ARC_SERVICE_H_
7
Garrick Evans86c7d9c2020-03-17 09:25:48 +09008#include <deque>
Garrick Evans1b1f67c2020-02-04 16:21:25 +09009#include <map>
Garrick Evans3915af32019-07-25 15:44:34 +090010#include <memory>
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090011#include <set>
Garrick Evans3915af32019-07-25 15:44:34 +090012#include <string>
Garrick Evans54861622019-07-19 09:05:09 +090013
14#include <base/memory/weak_ptr.h>
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090015#include <gtest/gtest_prod.h> // for FRIEND_TEST
Garrick Evans54861622019-07-19 09:05:09 +090016
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090017#include "arc/network/address_manager.h"
Garrick Evans54861622019-07-19 09:05:09 +090018#include "arc/network/datapath.h"
Garrick Evansf29f5a32019-12-06 11:34:25 +090019#include "arc/network/device.h"
Garrick Evansf29f5a32019-12-06 11:34:25 +090020#include "arc/network/ipc.pb.h"
Garrick Evans69b85872020-02-04 11:40:26 +090021#include "arc/network/shill_client.h"
Garrick Evans6e4eb3b2020-03-09 07:18:31 +090022#include "arc/network/traffic_forwarder.h"
Garrick Evans5d55f5e2019-07-17 15:28:10 +090023
24namespace arc_networkd {
25
Garrick Evansf29f5a32019-12-06 11:34:25 +090026class ArcService {
Garrick Evans5d55f5e2019-07-17 15:28:10 +090027 public:
Garrick Evansb4eb3892019-11-13 12:07:07 +090028 class Impl {
29 public:
30 virtual ~Impl() = default;
31
32 virtual GuestMessage::GuestType guest() const = 0;
Garrick Evans015b0d62020-02-07 09:06:38 +090033 virtual uint32_t id() const = 0;
Garrick Evansb4eb3892019-11-13 12:07:07 +090034
Garrick Evans015b0d62020-02-07 09:06:38 +090035 virtual bool Start(uint32_t id) = 0;
36 virtual void Stop(uint32_t id) = 0;
37 virtual bool IsStarted(uint32_t* id = nullptr) const = 0;
Garrick Evansb4eb3892019-11-13 12:07:07 +090038 virtual bool OnStartDevice(Device* device) = 0;
39 virtual void OnStopDevice(Device* device) = 0;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090040 virtual void OnDefaultInterfaceChanged(const std::string& new_ifname,
41 const std::string& prev_ifname) = 0;
Garrick Evansb4eb3892019-11-13 12:07:07 +090042
Garrick Evanse94b6de2020-02-20 09:19:13 +090043 // Returns the ARC management interface.
44 Device* ArcDevice() const { return arc_device_.get(); }
45
Garrick Evansb4eb3892019-11-13 12:07:07 +090046 protected:
47 Impl() = default;
Garrick Evanse94b6de2020-02-20 09:19:13 +090048
49 // For now each implementation manages its own ARC device since ARCVM is
50 // still single-networked.
51 std::unique_ptr<Device> arc_device_;
Garrick Evans2c263102019-07-26 16:07:18 +090052 };
53
Garrick Evansd90a3822019-11-12 17:53:08 +090054 // Encapsulates all ARC++ container-specific logic.
Garrick Evansb4eb3892019-11-13 12:07:07 +090055 class ContainerImpl : public Impl {
Garrick Evansd90a3822019-11-12 17:53:08 +090056 public:
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090057 ContainerImpl(Datapath* datapath,
58 AddressManager* addr_mgr,
59 TrafficForwarder* forwarder,
Garrick Evansd90a3822019-11-12 17:53:08 +090060 GuestMessage::GuestType guest);
61 ~ContainerImpl() = default;
62
Garrick Evansb4eb3892019-11-13 12:07:07 +090063 GuestMessage::GuestType guest() const override;
Garrick Evans015b0d62020-02-07 09:06:38 +090064 uint32_t id() const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +090065
Garrick Evans015b0d62020-02-07 09:06:38 +090066 bool Start(uint32_t pid) override;
67 void Stop(uint32_t pid) override;
68 bool IsStarted(uint32_t* pid = nullptr) const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +090069 bool OnStartDevice(Device* device) override;
70 void OnStopDevice(Device* device) override;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090071 void OnDefaultInterfaceChanged(const std::string& new_ifname,
72 const std::string& prev_ifname) override;
Garrick Evansd90a3822019-11-12 17:53:08 +090073
74 private:
Garrick Evans015b0d62020-02-07 09:06:38 +090075 uint32_t pid_;
Garrick Evansd90a3822019-11-12 17:53:08 +090076 Datapath* datapath_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090077 AddressManager* addr_mgr_;
78 TrafficForwarder* forwarder_;
Garrick Evansd90a3822019-11-12 17:53:08 +090079 GuestMessage::GuestType guest_;
80
Garrick Evansd90a3822019-11-12 17:53:08 +090081 base::WeakPtrFactory<ContainerImpl> weak_factory_{this};
82 DISALLOW_COPY_AND_ASSIGN(ContainerImpl);
83 };
84
Garrick Evansb4eb3892019-11-13 12:07:07 +090085 // Encapsulates all ARC VM-specific logic.
86 class VmImpl : public Impl {
87 public:
Garrick Evansbbdf4b42020-03-05 12:59:06 +090088 VmImpl(ShillClient* shill_client,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090089 Datapath* datapath,
90 AddressManager* addr_mgr,
Garrick Evansf5862122020-03-16 09:13:45 +090091 TrafficForwarder* forwarder,
92 bool enable_multinet);
Garrick Evansb4eb3892019-11-13 12:07:07 +090093 ~VmImpl() = default;
94
95 GuestMessage::GuestType guest() const override;
Garrick Evans015b0d62020-02-07 09:06:38 +090096 uint32_t id() const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +090097
Garrick Evans015b0d62020-02-07 09:06:38 +090098 bool Start(uint32_t cid) override;
99 void Stop(uint32_t cid) override;
100 bool IsStarted(uint32_t* cid = nullptr) const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900101 bool OnStartDevice(Device* device) override;
102 void OnStopDevice(Device* device) override;
Garrick Evans1b1f67c2020-02-04 16:21:25 +0900103 void OnDefaultInterfaceChanged(const std::string& new_ifname,
104 const std::string& prev_ifname) override;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900105
106 private:
Garrick Evansf5862122020-03-16 09:13:45 +0900107 // TODO(garrick): Remove once ARCVM P is gone.
108 bool OnStartArcPDevice();
109 void OnStopArcPDevice();
110
Garrick Evans015b0d62020-02-07 09:06:38 +0900111 uint32_t cid_;
Garrick Evansbbdf4b42020-03-05 12:59:06 +0900112 const ShillClient* const shill_client_;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900113 Datapath* datapath_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900114 AddressManager* addr_mgr_;
115 TrafficForwarder* forwarder_;
Garrick Evansf5862122020-03-16 09:13:45 +0900116 bool enable_multinet_;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900117
118 DISALLOW_COPY_AND_ASSIGN(VmImpl);
119 };
120
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900121 enum class InterfaceType {
122 UNKNOWN,
123 ETHERNET,
124 WIFI,
125 CELL,
126 };
127
Garrick Evans69b85872020-02-04 11:40:26 +0900128 // All pointers are required and cannot be null, and are owned by the caller.
129 ArcService(ShillClient* shill_client,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900130 Datapath* datapath,
131 AddressManager* addr_mgr,
Garrick Evansf5862122020-03-16 09:13:45 +0900132 TrafficForwarder* forwarder,
133 bool enable_arcvm_multinet);
Garrick Evansf29f5a32019-12-06 11:34:25 +0900134 ~ArcService();
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900135
Garrick Evans015b0d62020-02-07 09:06:38 +0900136 bool Start(uint32_t id);
137 void Stop(uint32_t id);
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900138
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900139 // Returns the ARC management interface.
Garrick Evanse94b6de2020-02-20 09:19:13 +0900140 Device* ArcDevice() const;
141
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900142 private:
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900143 // Callback from ShillClient, invoked whenever the device list changes.
144 // |devices_| will contain all devices currently connected to shill
145 // (e.g. "eth0", "wlan0", etc).
146 void OnDevicesChanged(const std::set<std::string>& added,
147 const std::set<std::string>& removed);
148
149 // Callback from ShillClient, invoked whenever the default network
150 // interface changes or goes away.
151 void OnDefaultInterfaceChanged(const std::string& new_ifname,
152 const std::string& prev_ifname);
153
154 // Build and configure an ARC device for the interface |name| provided by
155 // Shill. The new device will be added to |devices_|. If an implementation is
156 // already running, the device will be started.
157 void AddDevice(const std::string& ifname);
158
159 // Deletes the ARC device; if an implementation is running, the device will be
160 // stopped first.
161 void RemoveDevice(const std::string& ifname);
162
163 // Starts a device by setting up the bridge and configuring some NAT rules,
164 // then invoking the implementation-specific start routine.
Garrick Evans54861622019-07-19 09:05:09 +0900165 void StartDevice(Device* device);
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900166
167 // Stops and cleans up any virtual interfaces and associated datapath.
Garrick Evans54861622019-07-19 09:05:09 +0900168 void StopDevice(Device* device);
169
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900170 // Creates device configurations for all available IPv4 subnets which will be
171 // assigned to devices as they are added.
172 void AllocateAddressConfigs();
173
174 // This function will temporarily remove existing devices, reallocate
175 // address configurations and re-add existing devices. This is necessary to
176 // properly handle the IPv4 addressing binding difference between ARC++ and
177 // ARCVM.
178 void ReallocateAddressConfigs();
179
180 // Reserve a configuration for an interface.
181 std::unique_ptr<Device::Config> AcquireConfig(const std::string& ifname);
182
183 // Returns a configuration to the pool.
184 void ReleaseConfig(const std::string& ifname,
185 std::unique_ptr<Device::Config> config);
186
Garrick Evans69b85872020-02-04 11:40:26 +0900187 ShillClient* shill_client_;
Taoyu Li179dcc62019-10-17 11:21:08 +0900188 Datapath* datapath_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900189 AddressManager* addr_mgr_;
190 TrafficForwarder* forwarder_;
Garrick Evansf5862122020-03-16 09:13:45 +0900191 bool enable_arcvm_multinet_;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900192 std::unique_ptr<Impl> impl_;
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900193 std::map<InterfaceType, std::deque<std::unique_ptr<Device::Config>>> configs_;
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900194 std::map<std::string, std::unique_ptr<Device>> devices_;
195
196 FRIEND_TEST(ArcServiceTest, StartDevice);
197 FRIEND_TEST(ArcServiceTest, StopDevice);
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900198 FRIEND_TEST(ArcServiceTest, VerifyAddrConfigs);
199 FRIEND_TEST(ArcServiceTest, VerifyAddrOrder);
Garrick Evans54861622019-07-19 09:05:09 +0900200
201 base::WeakPtrFactory<ArcService> weak_factory_{this};
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900202 DISALLOW_COPY_AND_ASSIGN(ArcService);
203};
204
Garrick Evansf29f5a32019-12-06 11:34:25 +0900205namespace test {
206extern GuestMessage::GuestType guest;
207} // namespace test
208
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900209} // namespace arc_networkd
210
211#endif // ARC_NETWORK_ARC_SERVICE_H_