blob: 6738765264f498ffed794ec0b848fc5283f70f51 [file] [log] [blame]
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07001// Copyright 2016 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#ifndef PATCHPANEL_MANAGER_H_
6#define PATCHPANEL_MANAGER_H_
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07007
Hugo Benichiadf1ec52020-01-17 16:23:58 +09008#include <iostream>
Garrick Evans49879532018-12-03 13:15:36 +09009#include <map>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070010#include <memory>
Garrick Evans49879532018-12-03 13:15:36 +090011#include <set>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070012#include <string>
Jason Jeremy Imanf4156cb2019-11-14 15:36:22 +090013#include <vector>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070014
15#include <base/memory/weak_ptr.h>
16#include <brillo/daemons/dbus_daemon.h>
Simon Glass2b1da092020-05-21 12:24:16 -060017#include <brillo/process/process_reaper.h>
Garrick Evans08843932019-09-17 14:41:08 +090018#include <chromeos/dbus/service_constants.h>
Hugo Benichi8135e562019-12-12 15:56:36 +090019#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070020
Garrick Evans3388a032020-03-24 11:25:55 +090021#include "patchpanel/address_manager.h"
22#include "patchpanel/arc_service.h"
Jie Jiang493cde42020-07-17 21:43:39 +090023#include "patchpanel/counters_service.h"
Garrick Evans3388a032020-03-24 11:25:55 +090024#include "patchpanel/crostini_service.h"
Hugo Benichifcf81022020-12-04 11:01:37 +090025#include "patchpanel/datapath.h"
Jason Jeremy Imanc28df852020-07-11 17:38:26 +090026#include "patchpanel/firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090027#include "patchpanel/helper_process.h"
Jie Jiang01c1a2e2020-04-08 20:58:30 +090028#include "patchpanel/network_monitor_service.h"
Garrick Evans3388a032020-03-24 11:25:55 +090029#include "patchpanel/routing_service.h"
30#include "patchpanel/shill_client.h"
31#include "patchpanel/socket.h"
32#include "patchpanel/subnet.h"
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070033
Garrick Evans3388a032020-03-24 11:25:55 +090034namespace patchpanel {
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070035
36// Main class that runs the mainloop and responds to LAN interface changes.
Hugo Benichib9d123e2021-02-27 23:37:16 +090037class Manager final : public brillo::DBusDaemon {
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070038 public:
Taoyu Lice7caa62019-10-01 15:43:33 +090039 Manager(std::unique_ptr<HelperProcess> adb_proxy,
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +090040 std::unique_ptr<HelperProcess> mcast_proxy,
Garrick Evans1f5a3612019-11-08 12:59:03 +090041 std::unique_ptr<HelperProcess> nd_proxy);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090042 Manager(const Manager&) = delete;
43 Manager& operator=(const Manager&) = delete;
44
Jie Jiang00592cf2020-12-17 11:23:49 +090045 ~Manager() = default;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070046
Garrick Evans4ac09852020-01-16 14:09:22 +090047 void StartForwarding(const std::string& ifname_physical,
Hugo Benichi6f118a32021-03-01 12:28:14 +090048 const std::string& ifname_virtual);
Garrick Evans4ac09852020-01-16 14:09:22 +090049
50 void StopForwarding(const std::string& ifname_physical,
Hugo Benichi6f118a32021-03-01 12:28:14 +090051 const std::string& ifname_virtual);
Garrick Evans4ac09852020-01-16 14:09:22 +090052
Jason Jeremy Imanf4156cb2019-11-14 15:36:22 +090053 // This function is used to enable specific features only on selected
54 // combination of Android version, Chrome version, and boards.
55 // Empty |supportedBoards| means that the feature should be enabled on all
56 // board.
57 static bool ShouldEnableFeature(
58 int min_android_sdk_version,
59 int min_chrome_milestone,
60 const std::vector<std::string>& supported_boards,
61 const std::string& feature_name);
62
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070063 protected:
64 int OnInit() override;
65
66 private:
Hugo Benichi2a940542020-10-26 18:50:49 +090067 void OnDefaultDeviceChanged(const ShillClient::Device& new_device,
68 const ShillClient::Device& prev_device);
Hugo Benichi76be34a2020-08-26 22:35:54 +090069 void OnDevicesChanged(const std::set<std::string>& added,
70 const std::set<std::string>& removed);
Hugo Benichi1e0656f2021-02-15 15:43:38 +090071 void OnIPConfigsChanged(const std::string& device,
72 const ShillClient::IPConfig& ipconfig);
Garrick Evans209a80a2020-11-30 14:42:40 +090073
74 void OnDeviceChanged(const Device& device,
75 Device::ChangeEvent event,
76 GuestMessage::GuestType guest_type);
77
Garrick Evans49879532018-12-03 13:15:36 +090078 void InitialSetup();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070079
Garrick Evanse94a14e2019-11-11 10:32:13 +090080 bool StartArc(pid_t pid);
Hugo Benichi4d4bb8f2020-07-07 12:16:07 +090081 void StopArc();
Garrick Evans015b0d62020-02-07 09:06:38 +090082 bool StartArcVm(uint32_t cid);
83 void StopArcVm(uint32_t cid);
Garrick Evans51d5b552020-01-30 10:42:06 +090084 bool StartCrosVm(uint64_t vm_id,
85 GuestMessage::GuestType vm_type,
Garrick Evans53a2a982020-02-05 10:53:35 +090086 uint32_t subnet_index = kAnySubnetIndex);
Garrick Evans51d5b552020-01-30 10:42:06 +090087 void StopCrosVm(uint64_t vm_id, GuestMessage::GuestType vm_type);
Garrick Evanse94a14e2019-11-11 10:32:13 +090088
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080089 // Callback from ProcessReaper to notify Manager that one of the
90 // subprocesses died.
91 void OnSubprocessExited(pid_t pid, const siginfo_t& info);
Garrick Evans4c042572019-12-17 13:42:25 +090092 void RestartSubprocess(HelperProcess* subproc);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080093
Jie Jiang00592cf2020-12-17 11:23:49 +090094 // Callback from Daemon to notify that the message loop exits and before
95 // Daemon::Run() returns.
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080096 void OnShutdown(int* exit_code) override;
97
Taoyu Lia0727dc2020-09-24 19:54:59 +090098 // Callback from NDProxy telling us to add a new IPv6 route to guest or IPv6
99 // address to guest-facing interface.
100 void OnNDProxyMessage(const NDProxyMessage& msg);
Garrick Evans4ac09852020-01-16 14:09:22 +0900101
Garrick Evans02e6e872020-11-30 11:53:13 +0900102 // Handles DBus request for managed device list.
103 std::unique_ptr<dbus::Response> OnGetDevices(dbus::MethodCall* method_call);
104
Garrick Evans08843932019-09-17 14:41:08 +0900105 // Handles DBus notification indicating ARC++ is booting up.
106 std::unique_ptr<dbus::Response> OnArcStartup(dbus::MethodCall* method_call);
107
108 // Handles DBus notification indicating ARC++ is spinning down.
109 std::unique_ptr<dbus::Response> OnArcShutdown(dbus::MethodCall* method_call);
110
111 // Handles DBus notification indicating ARCVM is booting up.
112 std::unique_ptr<dbus::Response> OnArcVmStartup(dbus::MethodCall* method_call);
113
114 // Handles DBus notification indicating ARCVM is spinning down.
115 std::unique_ptr<dbus::Response> OnArcVmShutdown(
116 dbus::MethodCall* method_call);
117
Garrick Evans47c19272019-11-21 10:58:21 +0900118 // Handles DBus notification indicating a Termina VM is booting up.
119 std::unique_ptr<dbus::Response> OnTerminaVmStartup(
120 dbus::MethodCall* method_call);
121
122 // Handles DBus notification indicating a Termina VM is spinning down.
123 std::unique_ptr<dbus::Response> OnTerminaVmShutdown(
124 dbus::MethodCall* method_call);
125
Garrick Evans51d5b552020-01-30 10:42:06 +0900126 // Handles DBus notification indicating a Plugin VM is booting up.
127 std::unique_ptr<dbus::Response> OnPluginVmStartup(
128 dbus::MethodCall* method_call);
129
130 // Handles DBus notification indicating a Plugin VM is spinning down.
131 std::unique_ptr<dbus::Response> OnPluginVmShutdown(
132 dbus::MethodCall* method_call);
133
Hugo Benichi7d9d8db2020-03-30 15:56:56 +0900134 // Handles DBus requests for setting a VPN intent fwmark on a socket.
135 std::unique_ptr<dbus::Response> OnSetVpnIntent(dbus::MethodCall* method_call);
136
Hugo Benichib56b77c2020-01-15 16:00:56 +0900137 // Handles DBus requests for connect and routing an existing network
138 // namespace created via minijail or through the rtnl
139 std::unique_ptr<dbus::Response> OnConnectNamespace(
140 dbus::MethodCall* method_call);
141
Jie Jiang493cde42020-07-17 21:43:39 +0900142 // Handles DBus requests for querying traffic counters.
143 std::unique_ptr<dbus::Response> OnGetTrafficCounters(
144 dbus::MethodCall* method_call);
145
Jason Jeremy Imanb2a421e2020-07-04 20:48:32 +0900146 // Handles DBus requests for creating iptables rules by permission_broker.
147 std::unique_ptr<dbus::Response> OnModifyPortRule(
148 dbus::MethodCall* method_call);
149
Hugo Benichi007abcc2021-05-14 10:44:45 +0900150 // Handles DBus requests for starting and stopping VPN lockdown.
151 std::unique_ptr<dbus::Response> OnSetVpnLockdown(
152 dbus::MethodCall* method_call);
153
Jie Jiang25c1b972020-11-12 15:42:53 +0900154 // Sends out DBus signal for notifying neighbor reachability event.
155 void OnNeighborReachabilityEvent(
156 int ifindex,
157 const shill::IPAddress& ip_addr,
158 NeighborLinkMonitor::NeighborRole role,
159 NeighborReachabilityEventSignal::EventType event_type);
Jie Jiang84966852020-09-18 18:49:05 +0900160
Hugo Benichi7c342672020-09-08 09:18:14 +0900161 std::unique_ptr<patchpanel::ConnectNamespaceResponse> ConnectNamespace(
162 base::ScopedFD client_fd,
163 const patchpanel::ConnectNamespaceRequest& request);
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900164 void DisconnectNamespace(int client_fd);
Hugo Benichi7352ad92020-04-07 16:11:59 +0900165 // Detects if any file descriptor committed in ConnectNamespace DBus API has
166 // been invalidated by the caller. Calls DisconnectNamespace for any invalid
167 // fd found.
168 void CheckConnectedNamespaces();
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900169
Jason Jeremy Imanc28df852020-07-11 17:38:26 +0900170 bool ModifyPortRule(const patchpanel::ModifyPortRuleRequest& request);
171
Garrick Evanse94a14e2019-11-11 10:32:13 +0900172 // Dispatch |msg| to child processes.
173 void SendGuestMessage(const GuestMessage& msg);
Garrick Evans96e03042019-05-28 14:30:52 +0900174
Hugo Benichi935eca92018-07-03 13:47:24 +0900175 friend std::ostream& operator<<(std::ostream& stream, const Manager& manager);
176
Garrick Evans69b85872020-02-04 11:40:26 +0900177 std::unique_ptr<ShillClient> shill_client_;
Hugo Benichi7d9d8db2020-03-30 15:56:56 +0900178 std::unique_ptr<RoutingService> routing_svc_;
Garrick Evans69b85872020-02-04 11:40:26 +0900179
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900180 // Guest services.
181 std::unique_ptr<ArcService> arc_svc_;
Garrick Evans47c19272019-11-21 10:58:21 +0900182 std::unique_ptr<CrostiniService> cros_svc_;
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900183
Garrick Evans08843932019-09-17 14:41:08 +0900184 // DBus service.
185 dbus::ExportedObject* dbus_svc_path_; // Owned by |bus_|.
186
Jason Jeremy Imanc28df852020-07-11 17:38:26 +0900187 // Firewall service.
188 Firewall firewall_;
189
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900190 // Other services.
Garrick Evans3915af32019-07-25 15:44:34 +0900191 brillo::ProcessReaper process_reaper_;
Garrick Evans96e03042019-05-28 14:30:52 +0900192 std::unique_ptr<HelperProcess> adb_proxy_;
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +0900193 std::unique_ptr<HelperProcess> mcast_proxy_;
Taoyu Lice7caa62019-10-01 15:43:33 +0900194 std::unique_ptr<HelperProcess> nd_proxy_;
Jie Jiang493cde42020-07-17 21:43:39 +0900195 std::unique_ptr<CountersService> counters_svc_;
Jie Jiang01c1a2e2020-04-08 20:58:30 +0900196 std::unique_ptr<NetworkMonitorService> network_monitor_svc_;
Garrick Evans96e03042019-05-28 14:30:52 +0900197
Garrick Evansf4a93292019-03-13 14:19:43 +0900198 AddressManager addr_mgr_;
Garrick Evansf4a93292019-03-13 14:19:43 +0900199
Jason Jeremy Imanf4156cb2019-11-14 15:36:22 +0900200 // |cached_feature_enabled| stores the cached result of if a feature should be
201 // enabled.
202 static std::map<const std::string, bool> cached_feature_enabled_;
203
Taoyu Li179dcc62019-10-17 11:21:08 +0900204 std::unique_ptr<MinijailedProcessRunner> runner_;
205 std::unique_ptr<Datapath> datapath_;
206
Hugo Benichi69c989d2021-03-01 00:23:39 +0900207 // TODO(b/174538233) Introduce ForwardingGroup to properly track the state of
208 // traffic forwarding (ndproxy, multicast) between upstream devices managed by
209 // shill and downstream devices managed by patchpanel.
Hugo Benichi6f118a32021-03-01 12:28:14 +0900210 // All downstream interfaces managed by patchpanel for which multicast
211 // forwarding was enabled. This information cannot always be retrieved from
212 // the IFF_MULTICAST flag of the upstream interface managed by shill if it
213 // does not exist anymore.
Hugo Benichi69c989d2021-03-01 00:23:39 +0900214 std::set<std::string> multicast_virtual_ifnames_;
Hugo Benichi6f118a32021-03-01 12:28:14 +0900215 // All downstream interfaces managed by patchpanel for which IPv6 neighbor
216 // discovery proxy was enabled. This information cannot always be retrieved
217 // from the technology type of the upstream interface managed by shill if it
218 // does not exist anymore.
219 std::set<std::string> ndproxy_virtual_ifnames_;
Hugo Benichi69c989d2021-03-01 00:23:39 +0900220
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900221 // All namespaces currently connected through patchpanel ConnectNamespace
222 // API, keyed by file descriptors committed by clients when calling
223 // ConnectNamespace.
Hugo Benichifcf81022020-12-04 11:01:37 +0900224 std::map<int, ConnectedNamespace> connected_namespaces_;
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900225 int connected_namespaces_next_id_{0};
Hugo Benichi7352ad92020-04-07 16:11:59 +0900226 // epoll file descriptor for watching client fds committed with the
227 // ConnectNamespace DBus API.
228 int connected_namespaces_epollfd_;
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900229
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700230 base::WeakPtrFactory<Manager> weak_factory_{this};
231};
232
Garrick Evans3388a032020-03-24 11:25:55 +0900233} // namespace patchpanel
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700234
Garrick Evans3388a032020-03-24 11:25:55 +0900235#endif // PATCHPANEL_MANAGER_H_