arc: Move platform2/arc/network/ to platform2/patchpanel

Next step in the arc-networkd -> patchpanel rename, this patch moves the
location of the code.

BUG=b:151879931
TEST=units,flashed image to atlas
TEST=tasts arc.PlayStore, crostini.LaunchTerminal.download

Change-Id: I1b5cf8d670e1631d46f6449b725395157bf88dde
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2115863
Tested-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/arc_service.h b/patchpanel/arc_service.h
new file mode 100644
index 0000000..ab1c781
--- /dev/null
+++ b/patchpanel/arc_service.h
@@ -0,0 +1,226 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PATCHPANEL_ARC_SERVICE_H_
+#define PATCHPANEL_ARC_SERVICE_H_
+
+#include <deque>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/memory/weak_ptr.h>
+#include <gtest/gtest_prod.h>  // for FRIEND_TEST
+
+#include "patchpanel/address_manager.h"
+#include "patchpanel/datapath.h"
+#include "patchpanel/device.h"
+#include "patchpanel/ipc.pb.h"
+#include "patchpanel/shill_client.h"
+#include "patchpanel/traffic_forwarder.h"
+
+namespace patchpanel {
+
+class ArcService {
+ public:
+  class Impl {
+   public:
+    virtual ~Impl() = default;
+
+    virtual GuestMessage::GuestType guest() const = 0;
+    virtual uint32_t id() const = 0;
+
+    // Returns the list of device configurations that were provided to the
+    // implementation at creation time plus the one for the ARC device, if
+    // applicable. Currently only ARCVM supports this method.
+    virtual std::vector<const Device::Config*> GetDeviceConfigs() const = 0;
+
+    virtual bool Start(uint32_t id) = 0;
+    virtual void Stop(uint32_t id) = 0;
+    virtual bool IsStarted(uint32_t* id = nullptr) const = 0;
+    virtual bool OnStartDevice(Device* device) = 0;
+    virtual void OnStopDevice(Device* device) = 0;
+    virtual void OnDefaultInterfaceChanged(const std::string& new_ifname,
+                                           const std::string& prev_ifname) = 0;
+
+   protected:
+    Impl() = default;
+
+    // For now each implementation manages its own ARC device since ARCVM is
+    // still single-networked.
+    std::unique_ptr<Device> arc_device_;
+  };
+
+  // Encapsulates all ARC++ container-specific logic.
+  class ContainerImpl : public Impl {
+   public:
+    ContainerImpl(Datapath* datapath,
+                  AddressManager* addr_mgr,
+                  TrafficForwarder* forwarder,
+                  GuestMessage::GuestType guest);
+    ~ContainerImpl() = default;
+
+    GuestMessage::GuestType guest() const override;
+    uint32_t id() const override;
+    std::vector<const Device::Config*> GetDeviceConfigs() const override {
+      return {};
+    }
+
+    bool Start(uint32_t pid) override;
+    void Stop(uint32_t pid) override;
+    bool IsStarted(uint32_t* pid = nullptr) const override;
+    bool OnStartDevice(Device* device) override;
+    void OnStopDevice(Device* device) override;
+    void OnDefaultInterfaceChanged(const std::string& new_ifname,
+                                   const std::string& prev_ifname) override;
+
+   private:
+    uint32_t pid_;
+    Datapath* datapath_;
+    AddressManager* addr_mgr_;
+    TrafficForwarder* forwarder_;
+    GuestMessage::GuestType guest_;
+
+    base::WeakPtrFactory<ContainerImpl> weak_factory_{this};
+    DISALLOW_COPY_AND_ASSIGN(ContainerImpl);
+  };
+
+  // Encapsulates all ARC VM-specific logic.
+  class VmImpl : public Impl {
+   public:
+    // |configs| is an optional list of device configurations that, if provided,
+    // will be used to pre-allocated and associate them, when necessary, to
+    // devices as they are added. The caller retains ownership of the pointers.
+    VmImpl(ShillClient* shill_client,
+           Datapath* datapath,
+           AddressManager* addr_mgr,
+           TrafficForwarder* forwarder,
+           const std::vector<Device::Config*>& configs);
+    ~VmImpl() = default;
+
+    GuestMessage::GuestType guest() const override;
+    uint32_t id() const override;
+    std::vector<const Device::Config*> GetDeviceConfigs() const override;
+
+    bool Start(uint32_t cid) override;
+    void Stop(uint32_t cid) override;
+    bool IsStarted(uint32_t* cid = nullptr) const override;
+    bool OnStartDevice(Device* device) override;
+    void OnStopDevice(Device* device) override;
+    void OnDefaultInterfaceChanged(const std::string& new_ifname,
+                                   const std::string& prev_ifname) override;
+
+   private:
+    // TODO(garrick): Remove once ARCVM P is gone.
+    bool OnStartArcPDevice();
+    void OnStopArcPDevice();
+
+    bool IsMultinetEnabled() const;
+
+    uint32_t cid_;
+    const ShillClient* const shill_client_;
+    Datapath* datapath_;
+    AddressManager* addr_mgr_;
+    TrafficForwarder* forwarder_;
+    std::vector<Device::Config*> configs_;
+
+    DISALLOW_COPY_AND_ASSIGN(VmImpl);
+  };
+
+  enum class InterfaceType {
+    UNKNOWN,
+    ETHERNET,
+    WIFI,
+    CELL,
+  };
+
+  // All pointers are required and cannot be null, and are owned by the caller.
+  ArcService(ShillClient* shill_client,
+             Datapath* datapath,
+             AddressManager* addr_mgr,
+             TrafficForwarder* forwarder,
+             bool enable_arcvm_multinet);
+  ~ArcService();
+
+  bool Start(uint32_t id);
+  void Stop(uint32_t id);
+
+  // Returns a list of device configurations. This method only really is useful
+  // when ARCVM is running as it enables the caller to discover which
+  // configurations, if any, are currently associated to TAP devices.
+  std::vector<const Device::Config*> GetDeviceConfigs() const;
+
+ private:
+  // Callback from ShillClient, invoked whenever the device list changes.
+  // |devices_| will contain all devices currently connected to shill
+  // (e.g. "eth0", "wlan0", etc).
+  void OnDevicesChanged(const std::set<std::string>& added,
+                        const std::set<std::string>& removed);
+
+  // Callback from ShillClient, invoked whenever the default network
+  // interface changes or goes away.
+  void OnDefaultInterfaceChanged(const std::string& new_ifname,
+                                 const std::string& prev_ifname);
+
+  // Build and configure an ARC device for the interface |name| provided by
+  // Shill. The new device will be added to |devices_|. If an implementation is
+  // already running, the device will be started.
+  void AddDevice(const std::string& ifname);
+
+  // Deletes the ARC device; if an implementation is running, the device will be
+  // stopped first.
+  void RemoveDevice(const std::string& ifname);
+
+  // Starts a device by setting up the bridge and configuring some NAT rules,
+  // then invoking the implementation-specific start routine.
+  void StartDevice(Device* device);
+
+  // Stops and cleans up any virtual interfaces and associated datapath.
+  void StopDevice(Device* device);
+
+  // Creates device configurations for all available IPv4 subnets which will be
+  // assigned to devices as they are added.
+  void AllocateAddressConfigs();
+
+  // This function will temporarily remove existing devices, reallocate
+  // address configurations and re-add existing devices. This is necessary to
+  // properly handle the IPv4 addressing binding difference between ARC++ and
+  // ARCVM.
+  // Returns the list of all configurations ordered by type.
+  std::vector<Device::Config*> ReallocateAddressConfigs();
+
+  // Reserve a configuration for an interface.
+  std::unique_ptr<Device::Config> AcquireConfig(const std::string& ifname);
+
+  // Returns a configuration to the pool.
+  void ReleaseConfig(const std::string& ifname,
+                     std::unique_ptr<Device::Config> config);
+
+  ShillClient* shill_client_;
+  Datapath* datapath_;
+  AddressManager* addr_mgr_;
+  TrafficForwarder* forwarder_;
+  bool enable_arcvm_multinet_;
+  std::unique_ptr<Impl> impl_;
+  std::map<InterfaceType, std::deque<std::unique_ptr<Device::Config>>> configs_;
+  std::map<std::string, std::unique_ptr<Device>> devices_;
+
+  FRIEND_TEST(ArcServiceTest, StartDevice);
+  FRIEND_TEST(ArcServiceTest, StopDevice);
+  FRIEND_TEST(ArcServiceTest, VerifyAddrConfigs);
+  FRIEND_TEST(ArcServiceTest, VerifyAddrOrder);
+
+  base::WeakPtrFactory<ArcService> weak_factory_{this};
+  DISALLOW_COPY_AND_ASSIGN(ArcService);
+};
+
+namespace test {
+extern GuestMessage::GuestType guest;
+}  // namespace test
+
+}  // namespace patchpanel
+
+#endif  // PATCHPANEL_ARC_SERVICE_H_