blob: b75f8a82a13e41bd7acb7a5749377eff628cbe89 [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 Evans3915af32019-07-25 15:44:34 +09008#include <memory>
Garrick Evans3915af32019-07-25 15:44:34 +09009#include <string>
Garrick Evans54861622019-07-19 09:05:09 +090010
11#include <base/memory/weak_ptr.h>
12#include <shill/net/rtnl_handler.h>
13#include <shill/net/rtnl_listener.h>
14
15#include "arc/network/datapath.h"
Garrick Evansf29f5a32019-12-06 11:34:25 +090016#include "arc/network/device.h"
17#include "arc/network/device_manager.h"
18#include "arc/network/ipc.pb.h"
Garrick Evans69b85872020-02-04 11:40:26 +090019#include "arc/network/shill_client.h"
Garrick Evans5d55f5e2019-07-17 15:28:10 +090020
21namespace arc_networkd {
22
Garrick Evansf29f5a32019-12-06 11:34:25 +090023class ArcService {
Garrick Evans5d55f5e2019-07-17 15:28:10 +090024 public:
Garrick Evans2c263102019-07-26 16:07:18 +090025 class Context : public Device::Context {
26 public:
27 Context();
28 ~Context() = default;
29
30 // Tracks the lifetime of the ARC++ container.
31 void Start();
32 void Stop();
33 bool IsStarted() const;
34
35 bool IsLinkUp() const override;
36 // Returns true if the internal state changed.
37 bool SetLinkUp(bool link_up);
38
39 bool HasIPv6() const;
40 // Returns false if |routing_tid| is invalid.
41 bool SetHasIPv6(int routing_tid);
Garrick Evansdc3fc452019-09-06 14:15:04 +090042 // Resets the IPv6 attributes.
43 void ClearIPv6();
44
Garrick Evans2c263102019-07-26 16:07:18 +090045 int RoutingTableID() const;
46 // Returns the current value and increments the counter.
47 int RoutingTableAttempts();
48
Garrick Evansb4eb3892019-11-13 12:07:07 +090049 // For ARCVM only.
50 const std::string& TAP() const;
51 void SetTAP(const std::string& tap);
52
Garrick Evans2c263102019-07-26 16:07:18 +090053 private:
54 // Indicates the device was started.
55 bool started_;
56 // Indicates Android has brought up the interface.
57 bool link_up_;
58 // The routing table ID found for the interface.
59 int routing_table_id_;
60 // The number of times table ID lookup was attempted.
61 int routing_table_attempts_;
Garrick Evansb4eb3892019-11-13 12:07:07 +090062 // For ARCVM, the name of the bound TAP device.
63 std::string tap_;
64 };
65
66 class Impl {
67 public:
68 virtual ~Impl() = default;
69
70 virtual GuestMessage::GuestType guest() const = 0;
Garrick Evans015b0d62020-02-07 09:06:38 +090071 virtual uint32_t id() const = 0;
Garrick Evansb4eb3892019-11-13 12:07:07 +090072
Garrick Evans015b0d62020-02-07 09:06:38 +090073 virtual bool Start(uint32_t id) = 0;
74 virtual void Stop(uint32_t id) = 0;
75 virtual bool IsStarted(uint32_t* id = nullptr) const = 0;
Garrick Evansb4eb3892019-11-13 12:07:07 +090076 virtual bool OnStartDevice(Device* device) = 0;
77 virtual void OnStopDevice(Device* device) = 0;
78 virtual void OnDefaultInterfaceChanged(const std::string& ifname) = 0;
79
80 protected:
81 Impl() = default;
Garrick Evans2c263102019-07-26 16:07:18 +090082 };
83
Garrick Evansd90a3822019-11-12 17:53:08 +090084 // Encapsulates all ARC++ container-specific logic.
Garrick Evansb4eb3892019-11-13 12:07:07 +090085 class ContainerImpl : public Impl {
Garrick Evansd90a3822019-11-12 17:53:08 +090086 public:
87 ContainerImpl(DeviceManagerBase* dev_mgr,
88 Datapath* datapath,
89 GuestMessage::GuestType guest);
90 ~ContainerImpl() = default;
91
Garrick Evansb4eb3892019-11-13 12:07:07 +090092 GuestMessage::GuestType guest() const override;
Garrick Evans015b0d62020-02-07 09:06:38 +090093 uint32_t id() const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +090094
Garrick Evans015b0d62020-02-07 09:06:38 +090095 bool Start(uint32_t pid) override;
96 void Stop(uint32_t pid) override;
97 bool IsStarted(uint32_t* pid = nullptr) const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +090098 bool OnStartDevice(Device* device) override;
99 void OnStopDevice(Device* device) override;
100 void OnDefaultInterfaceChanged(const std::string& ifname) override;
Garrick Evansd90a3822019-11-12 17:53:08 +0900101
102 private:
103 // Handles RT netlink messages in the container net namespace and if it
104 // determines the link status has changed, toggles the device services
105 // accordingly.
106 void LinkMsgHandler(const shill::RTNLMessage& msg);
107
Garrick Evansbc91a352020-01-16 16:43:26 +0900108 // Handles RT netlink messages in the host namespace in order to toggle
109 // legacy IPv6 configuration.
110 void HostLinkMsgHandler(const shill::RTNLMessage& msg);
111
Garrick Evansd90a3822019-11-12 17:53:08 +0900112 void SetupIPv6(Device* device);
113 void TeardownIPv6(Device* device);
114
Garrick Evans015b0d62020-02-07 09:06:38 +0900115 uint32_t pid_;
Garrick Evansd90a3822019-11-12 17:53:08 +0900116 DeviceManagerBase* dev_mgr_;
117 Datapath* datapath_;
118 GuestMessage::GuestType guest_;
119
Garrick Evansbc91a352020-01-16 16:43:26 +0900120 // These are installed in the ARC net namespace.
Garrick Evansd90a3822019-11-12 17:53:08 +0900121 std::unique_ptr<shill::RTNLHandler> rtnl_handler_;
122 std::unique_ptr<shill::RTNLListener> link_listener_;
Garrick Evansbc91a352020-01-16 16:43:26 +0900123 // This is installed in the default namespace are are used only to start
124 // and stop legacy IPv6 configuration. Once all boards have been upgraded to
125 // P and are using NDProxy, it should be removed.
126 std::unique_ptr<shill::RTNLListener> host_link_listener_;
Garrick Evansd90a3822019-11-12 17:53:08 +0900127
Garrick Evansd90a3822019-11-12 17:53:08 +0900128 base::WeakPtrFactory<ContainerImpl> weak_factory_{this};
129 DISALLOW_COPY_AND_ASSIGN(ContainerImpl);
130 };
131
Garrick Evansb4eb3892019-11-13 12:07:07 +0900132 // Encapsulates all ARC VM-specific logic.
133 class VmImpl : public Impl {
134 public:
135 VmImpl(DeviceManagerBase* dev_mgr, Datapath* datapath);
136 ~VmImpl() = default;
137
138 GuestMessage::GuestType guest() const override;
Garrick Evans015b0d62020-02-07 09:06:38 +0900139 uint32_t id() const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900140
Garrick Evans015b0d62020-02-07 09:06:38 +0900141 bool Start(uint32_t cid) override;
142 void Stop(uint32_t cid) override;
143 bool IsStarted(uint32_t* cid = nullptr) const override;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900144 bool OnStartDevice(Device* device) override;
145 void OnStopDevice(Device* device) override;
146 void OnDefaultInterfaceChanged(const std::string& ifname) override;
147
148 private:
Garrick Evans015b0d62020-02-07 09:06:38 +0900149 uint32_t cid_;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900150 DeviceManagerBase* dev_mgr_;
151 Datapath* datapath_;
152
153 DISALLOW_COPY_AND_ASSIGN(VmImpl);
154 };
155
Garrick Evans69b85872020-02-04 11:40:26 +0900156 // All pointers are required and cannot be null, and are owned by the caller.
157 ArcService(ShillClient* shill_client,
158 DeviceManagerBase* dev_mgr,
159 Datapath* datapath);
Garrick Evansf29f5a32019-12-06 11:34:25 +0900160 ~ArcService();
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900161
Garrick Evans015b0d62020-02-07 09:06:38 +0900162 bool Start(uint32_t id);
163 void Stop(uint32_t id);
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900164
Garrick Evansf29f5a32019-12-06 11:34:25 +0900165 void OnDeviceAdded(Device* device);
166 void OnDeviceRemoved(Device* device);
167 void OnDefaultInterfaceChanged(const std::string& ifname);
Garrick Evans54861622019-07-19 09:05:09 +0900168
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900169 private:
Garrick Evans54861622019-07-19 09:05:09 +0900170 void StartDevice(Device* device);
171 void StopDevice(Device* device);
172
Garrick Evans8ff08452019-11-25 09:24:26 +0900173 // Returns true if the device should be processed by the service.
174 bool AllowDevice(Device* device) const;
175
Garrick Evans69b85872020-02-04 11:40:26 +0900176 ShillClient* shill_client_;
Garrick Evansf29f5a32019-12-06 11:34:25 +0900177 DeviceManagerBase* dev_mgr_;
Taoyu Li179dcc62019-10-17 11:21:08 +0900178 Datapath* datapath_;
Garrick Evansb4eb3892019-11-13 12:07:07 +0900179 std::unique_ptr<Impl> impl_;
Garrick Evans54861622019-07-19 09:05:09 +0900180
181 base::WeakPtrFactory<ArcService> weak_factory_{this};
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900182 DISALLOW_COPY_AND_ASSIGN(ArcService);
183};
184
Garrick Evansf29f5a32019-12-06 11:34:25 +0900185namespace test {
186extern GuestMessage::GuestType guest;
187} // namespace test
188
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900189} // namespace arc_networkd
190
191#endif // ARC_NETWORK_ARC_SERVICE_H_