blob: 63d8ad1df5414f399d5fd963ca89c63b13f0ff2b [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
Hidehiko Abe3a7e5132018-02-15 13:07:50 +09005#include "arc/network/manager.h"
Kevin Cernekee4e62cc12016-12-03 11:50:53 -08006
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07007#include <arpa/inet.h>
Hugo Benichi935eca92018-07-03 13:47:24 +09008#include <netinet/in.h>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07009#include <stdint.h>
10
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080011#include <utility>
12
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070013#include <base/bind.h>
14#include <base/logging.h>
15#include <base/message_loop/message_loop.h>
Garrick Evans49879532018-12-03 13:15:36 +090016#include <base/strings/stringprintf.h>
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080017#include <brillo/minijail/minijail.h>
18
Garrick Evans428e4762018-12-11 15:18:42 +090019#include "arc/network/ipc.pb.h"
20
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070021namespace {
22
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080023const uint64_t kManagerCapMask = CAP_TO_MASK(CAP_NET_RAW);
Garrick Evansd2bb8502019-02-20 15:59:35 +090024const char kUnprivilegedUser[] = "arc-networkd";
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070025
26} // namespace
27
28namespace arc_networkd {
29
Garrick Evansd2bb8502019-02-20 15:59:35 +090030Manager::Manager(std::unique_ptr<HelperProcess> ip_helper, bool enable_multinet)
Garrick Evansf4a93292019-03-13 14:19:43 +090031 : addr_mgr_({
32 AddressManager::Guest::ARC,
33 AddressManager::Guest::ARC_NET,
34 }),
35 enable_multinet_(enable_multinet) {
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080036 ip_helper_ = std::move(ip_helper);
37}
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070038
39int Manager::OnInit() {
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080040 // Run with minimal privileges.
41 brillo::Minijail* m = brillo::Minijail::GetInstance();
42 struct minijail* jail = m->New();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070043
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080044 // Most of these return void, but DropRoot() can fail if the user/group
45 // does not exist.
Hugo Benichi935eca92018-07-03 13:47:24 +090046 CHECK(m->DropRoot(jail, kUnprivilegedUser, kUnprivilegedUser))
47 << "Could not drop root privileges";
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080048 m->UseCapabilities(jail, kManagerCapMask);
49 m->Enter(jail);
50 m->Destroy(jail);
51
52 // Handle subprocess lifecycle.
Hugo Benichi935eca92018-07-03 13:47:24 +090053
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080054 process_reaper_.Register(this);
Hugo Benichi935eca92018-07-03 13:47:24 +090055
56 CHECK(process_reaper_.WatchForChild(
Hidehiko Abe3a7e5132018-02-15 13:07:50 +090057 FROM_HERE, ip_helper_->pid(),
58 base::Bind(&Manager::OnSubprocessExited, weak_factory_.GetWeakPtr(),
Hugo Benichi935eca92018-07-03 13:47:24 +090059 ip_helper_->pid())))
60 << "Failed to watch child IpHelper process";
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080061
Garrick Evans49879532018-12-03 13:15:36 +090062 // Handle container lifecycle.
63 RegisterHandler(
64 SIGUSR1, base::Bind(&Manager::OnContainerStart, base::Unretained(this)));
65 RegisterHandler(
66 SIGUSR2, base::Bind(&Manager::OnContainerStop, base::Unretained(this)));
67
68 // Run after Daemon::OnInit().
Eric Caruso9ce54182018-01-04 11:19:47 -080069 base::MessageLoopForIO::current()->task_runner()->PostTask(
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070070 FROM_HERE,
71 base::Bind(&Manager::InitialSetup, weak_factory_.GetWeakPtr()));
72
73 return DBusDaemon::OnInit();
74}
75
76void Manager::InitialSetup() {
Garrick Evans428e4762018-12-11 15:18:42 +090077 shill_client_ = std::make_unique<ShillClient>(std::move(bus_));
Garrick Evans428e4762018-12-11 15:18:42 +090078 device_mgr_ = std::make_unique<DeviceManager>(
Garrick Evansf4a93292019-03-13 14:19:43 +090079 &addr_mgr_, base::Bind(&Manager::SendMessage, weak_factory_.GetWeakPtr()),
Garrick Evansd2bb8502019-02-20 15:59:35 +090080 enable_multinet_ ? kAndroidDevice : kAndroidLegacyDevice);
81
82 if (enable_multinet_) {
83 shill_client_->RegisterDevicesChangedHandler(
84 base::Bind(&Manager::OnDevicesChanged, weak_factory_.GetWeakPtr()));
85 shill_client_->ScanDevices(
86 base::Bind(&Manager::OnDevicesChanged, weak_factory_.GetWeakPtr()));
87 }
Garrick Evans49879532018-12-03 13:15:36 +090088}
89
Garrick Evans49879532018-12-03 13:15:36 +090090bool Manager::OnContainerStart(const struct signalfd_siginfo& info) {
91 if (info.ssi_code == SI_USER) {
92 shill_client_->RegisterDefaultInterfaceChangedHandler(base::Bind(
93 &Manager::OnDefaultInterfaceChanged, weak_factory_.GetWeakPtr()));
94 }
95
Hugo Benichiee787ff2019-05-20 16:42:42 +090096 if (enable_multinet_ && device_mgr_) {
97 device_mgr_->EnableAllDevices();
98 }
99
Garrick Evans49879532018-12-03 13:15:36 +0900100 // Stay registered.
101 return false;
102}
103
104bool Manager::OnContainerStop(const struct signalfd_siginfo& info) {
105 if (info.ssi_code == SI_USER) {
106 shill_client_->UnregisterDefaultInterfaceChangedHandler();
Hugo Benichiee787ff2019-05-20 16:42:42 +0900107 if (device_mgr_) {
108 if (enable_multinet_) {
109 device_mgr_->DisableAllDevices();
110 } else {
111 device_mgr_->DisableLegacyDevice();
112 }
113 }
Garrick Evans49879532018-12-03 13:15:36 +0900114 }
115
116 // Stay registered.
117 return false;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700118}
119
120void Manager::OnDefaultInterfaceChanged(const std::string& ifname) {
Garrick Evans49879532018-12-03 13:15:36 +0900121 LOG(INFO) << "Default interface changed to " << ifname;
Hugo Benichiee787ff2019-05-20 16:42:42 +0900122 if (!enable_multinet_ && device_mgr_)
123 device_mgr_->EnableLegacyDevice(ifname);
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700124}
125
Garrick Evans49879532018-12-03 13:15:36 +0900126void Manager::OnDevicesChanged(const std::set<std::string>& devices) {
Garrick Evans428e4762018-12-11 15:18:42 +0900127 if (device_mgr_)
128 device_mgr_->Reset(devices);
Kevin Cernekee31a3d902017-07-11 16:46:39 -0700129}
130
Kevin Cernekee27bcaa62016-12-03 11:16:26 -0800131void Manager::OnShutdown(int* exit_code) {
Garrick Evans428e4762018-12-11 15:18:42 +0900132 device_mgr_.reset();
Kevin Cernekee27bcaa62016-12-03 11:16:26 -0800133}
134
135void Manager::OnSubprocessExited(pid_t pid, const siginfo_t& info) {
Hugo Benichi10a2af42018-08-27 10:09:42 +0900136 LOG(ERROR) << "Subprocess " << pid << " exited unexpectedly";
137 Quit();
Kevin Cernekee27bcaa62016-12-03 11:16:26 -0800138}
139
Garrick Evans49879532018-12-03 13:15:36 +0900140void Manager::SendMessage(const IpHelperMessage& msg) {
141 ip_helper_->SendMessage(msg);
Hugo Benichi935eca92018-07-03 13:47:24 +0900142}
143
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700144} // namespace arc_networkd