blob: fed2adfaae8e0a4c0a3f481619a74f2414b839e7 [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"
23#include "patchpanel/crostini_service.h"
24#include "patchpanel/helper_process.h"
Jie Jiang01c1a2e2020-04-08 20:58:30 +090025#include "patchpanel/network_monitor_service.h"
Garrick Evans3388a032020-03-24 11:25:55 +090026#include "patchpanel/routing_service.h"
27#include "patchpanel/shill_client.h"
28#include "patchpanel/socket.h"
29#include "patchpanel/subnet.h"
30#include "patchpanel/traffic_forwarder.h"
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070031
Garrick Evans3388a032020-03-24 11:25:55 +090032namespace patchpanel {
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070033
34// Main class that runs the mainloop and responds to LAN interface changes.
Garrick Evans4ac09852020-01-16 14:09:22 +090035class Manager final : public brillo::DBusDaemon, private TrafficForwarder {
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070036 public:
Hugo Benichiadf1ec52020-01-17 16:23:58 +090037 // Metadata for tracking state associated with a connected namespace.
38 struct ConnectNamespaceInfo {
39 // The pid of the client network namespace.
40 pid_t pid;
41 // Name of the shill device for routing outbound traffic from the client
42 // namespace. Empty if outbound traffic should be forwarded to the highest
43 // priority network (physical or virtual).
44 std::string outbound_ifname;
45 // Name of the "local" veth device visible on the host namespace.
46 std::string host_ifname;
47 // Name of the "remote" veth device moved into the client namespace.
48 std::string client_ifname;
49 // IPv4 subnet assigned to the client namespace.
50 std::unique_ptr<Subnet> client_subnet;
51 };
52
Taoyu Lice7caa62019-10-01 15:43:33 +090053 Manager(std::unique_ptr<HelperProcess> adb_proxy,
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +090054 std::unique_ptr<HelperProcess> mcast_proxy,
Garrick Evans1f5a3612019-11-08 12:59:03 +090055 std::unique_ptr<HelperProcess> nd_proxy);
Garrick Evans207e7482019-12-16 11:54:36 +090056 ~Manager();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070057
Garrick Evans4ac09852020-01-16 14:09:22 +090058 // TrafficForwarder methods.
59
60 void StartForwarding(const std::string& ifname_physical,
61 const std::string& ifname_virtual,
Garrick Evans4ac09852020-01-16 14:09:22 +090062 bool ipv6,
63 bool multicast) override;
64
65 void StopForwarding(const std::string& ifname_physical,
66 const std::string& ifname_virtual,
67 bool ipv6,
68 bool multicast) override;
69
Jason Jeremy Imanf4156cb2019-11-14 15:36:22 +090070 // This function is used to enable specific features only on selected
71 // combination of Android version, Chrome version, and boards.
72 // Empty |supportedBoards| means that the feature should be enabled on all
73 // board.
74 static bool ShouldEnableFeature(
75 int min_android_sdk_version,
76 int min_chrome_milestone,
77 const std::vector<std::string>& supported_boards,
78 const std::string& feature_name);
79
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070080 protected:
81 int OnInit() override;
82
83 private:
Garrick Evans49879532018-12-03 13:15:36 +090084 void InitialSetup();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070085
Garrick Evanse94a14e2019-11-11 10:32:13 +090086 bool StartArc(pid_t pid);
Garrick Evans21173b12019-11-20 15:23:16 +090087 void StopArc(pid_t pid);
Garrick Evans015b0d62020-02-07 09:06:38 +090088 bool StartArcVm(uint32_t cid);
89 void StopArcVm(uint32_t cid);
Garrick Evans51d5b552020-01-30 10:42:06 +090090 bool StartCrosVm(uint64_t vm_id,
91 GuestMessage::GuestType vm_type,
Garrick Evans53a2a982020-02-05 10:53:35 +090092 uint32_t subnet_index = kAnySubnetIndex);
Garrick Evans51d5b552020-01-30 10:42:06 +090093 void StopCrosVm(uint64_t vm_id, GuestMessage::GuestType vm_type);
Garrick Evanse94a14e2019-11-11 10:32:13 +090094
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080095 // Callback from ProcessReaper to notify Manager that one of the
96 // subprocesses died.
97 void OnSubprocessExited(pid_t pid, const siginfo_t& info);
Garrick Evans4c042572019-12-17 13:42:25 +090098 void RestartSubprocess(HelperProcess* subproc);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080099
Garrick Evans664a82f2019-12-17 12:18:05 +0900100 // Callback from Daemon to notify that SIGTERM or SIGINT was received and
Kevin Cernekee27bcaa62016-12-03 11:16:26 -0800101 // the daemon should clean up in preparation to exit.
102 void OnShutdown(int* exit_code) override;
103
Garrick Evans4ac09852020-01-16 14:09:22 +0900104 // Callback from NDProxy telling us to add a new IPv6 route.
105 void OnDeviceMessageFromNDProxy(const DeviceMessage& msg);
106
Garrick Evans08843932019-09-17 14:41:08 +0900107 // Handles DBus notification indicating ARC++ is booting up.
108 std::unique_ptr<dbus::Response> OnArcStartup(dbus::MethodCall* method_call);
109
110 // Handles DBus notification indicating ARC++ is spinning down.
111 std::unique_ptr<dbus::Response> OnArcShutdown(dbus::MethodCall* method_call);
112
113 // Handles DBus notification indicating ARCVM is booting up.
114 std::unique_ptr<dbus::Response> OnArcVmStartup(dbus::MethodCall* method_call);
115
116 // Handles DBus notification indicating ARCVM is spinning down.
117 std::unique_ptr<dbus::Response> OnArcVmShutdown(
118 dbus::MethodCall* method_call);
119
Garrick Evans47c19272019-11-21 10:58:21 +0900120 // Handles DBus notification indicating a Termina VM is booting up.
121 std::unique_ptr<dbus::Response> OnTerminaVmStartup(
122 dbus::MethodCall* method_call);
123
124 // Handles DBus notification indicating a Termina VM is spinning down.
125 std::unique_ptr<dbus::Response> OnTerminaVmShutdown(
126 dbus::MethodCall* method_call);
127
Garrick Evans51d5b552020-01-30 10:42:06 +0900128 // Handles DBus notification indicating a Plugin VM is booting up.
129 std::unique_ptr<dbus::Response> OnPluginVmStartup(
130 dbus::MethodCall* method_call);
131
132 // Handles DBus notification indicating a Plugin VM is spinning down.
133 std::unique_ptr<dbus::Response> OnPluginVmShutdown(
134 dbus::MethodCall* method_call);
135
Hugo Benichi7d9d8db2020-03-30 15:56:56 +0900136 // Handles DBus requests for setting a VPN intent fwmark on a socket.
137 std::unique_ptr<dbus::Response> OnSetVpnIntent(dbus::MethodCall* method_call);
138
Hugo Benichib56b77c2020-01-15 16:00:56 +0900139 // Handles DBus requests for connect and routing an existing network
140 // namespace created via minijail or through the rtnl
141 std::unique_ptr<dbus::Response> OnConnectNamespace(
142 dbus::MethodCall* method_call);
143
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900144 void ConnectNamespace(base::ScopedFD client_fd,
145 const patchpanel::ConnectNamespaceRequest& request,
146 patchpanel::ConnectNamespaceResponse& response);
147 void DisconnectNamespace(int client_fd);
Hugo Benichi7352ad92020-04-07 16:11:59 +0900148 // Detects if any file descriptor committed in ConnectNamespace DBus API has
149 // been invalidated by the caller. Calls DisconnectNamespace for any invalid
150 // fd found.
151 void CheckConnectedNamespaces();
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900152
Garrick Evanse94a14e2019-11-11 10:32:13 +0900153 // Dispatch |msg| to child processes.
154 void SendGuestMessage(const GuestMessage& msg);
Garrick Evans96e03042019-05-28 14:30:52 +0900155
Hugo Benichi935eca92018-07-03 13:47:24 +0900156 friend std::ostream& operator<<(std::ostream& stream, const Manager& manager);
157
Garrick Evans69b85872020-02-04 11:40:26 +0900158 std::unique_ptr<ShillClient> shill_client_;
Hugo Benichi7d9d8db2020-03-30 15:56:56 +0900159 std::unique_ptr<RoutingService> routing_svc_;
Garrick Evans69b85872020-02-04 11:40:26 +0900160
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900161 // Guest services.
162 std::unique_ptr<ArcService> arc_svc_;
Garrick Evans47c19272019-11-21 10:58:21 +0900163 std::unique_ptr<CrostiniService> cros_svc_;
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900164
Garrick Evans08843932019-09-17 14:41:08 +0900165 // DBus service.
166 dbus::ExportedObject* dbus_svc_path_; // Owned by |bus_|.
167
Garrick Evans5d55f5e2019-07-17 15:28:10 +0900168 // Other services.
Garrick Evans3915af32019-07-25 15:44:34 +0900169 brillo::ProcessReaper process_reaper_;
Garrick Evans96e03042019-05-28 14:30:52 +0900170 std::unique_ptr<HelperProcess> adb_proxy_;
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +0900171 std::unique_ptr<HelperProcess> mcast_proxy_;
Taoyu Lice7caa62019-10-01 15:43:33 +0900172 std::unique_ptr<HelperProcess> nd_proxy_;
Jie Jiang01c1a2e2020-04-08 20:58:30 +0900173 std::unique_ptr<NetworkMonitorService> network_monitor_svc_;
Garrick Evans96e03042019-05-28 14:30:52 +0900174
Garrick Evansf4a93292019-03-13 14:19:43 +0900175 AddressManager addr_mgr_;
Garrick Evansf4a93292019-03-13 14:19:43 +0900176
Jason Jeremy Imanf4156cb2019-11-14 15:36:22 +0900177 // |cached_feature_enabled| stores the cached result of if a feature should be
178 // enabled.
179 static std::map<const std::string, bool> cached_feature_enabled_;
180
Taoyu Li179dcc62019-10-17 11:21:08 +0900181 std::unique_ptr<MinijailedProcessRunner> runner_;
182 std::unique_ptr<Datapath> datapath_;
183
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900184 // All namespaces currently connected through patchpanel ConnectNamespace
185 // API, keyed by file descriptors committed by clients when calling
186 // ConnectNamespace.
187 std::map<int, ConnectNamespaceInfo> connected_namespaces_;
188 int connected_namespaces_next_id_{0};
Hugo Benichi7352ad92020-04-07 16:11:59 +0900189 // epoll file descriptor for watching client fds committed with the
190 // ConnectNamespace DBus API.
191 int connected_namespaces_epollfd_;
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900192
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700193 base::WeakPtrFactory<Manager> weak_factory_{this};
Garrick Evansf4a93292019-03-13 14:19:43 +0900194 DISALLOW_COPY_AND_ASSIGN(Manager);
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700195};
196
Hugo Benichiadf1ec52020-01-17 16:23:58 +0900197std::ostream& operator<<(std::ostream& stream,
198 const Manager::ConnectNamespaceInfo& ns_info);
199
Garrick Evans3388a032020-03-24 11:25:55 +0900200} // namespace patchpanel
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700201
Garrick Evans3388a032020-03-24 11:25:55 +0900202#endif // PATCHPANEL_MANAGER_H_