blob: cb974ea4dafe59c80f4f4f95392649ecfb001817 [file] [log] [blame]
Lorenzo Colittie4d626e2016-02-02 17:19:04 +09001/**
2 * Copyright (c) 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Netd"
18
Ben Schwartz4204ecf2017-10-02 12:35:48 -040019#include <set>
Erik Kline38e51f12018-09-06 20:14:44 +090020#include <tuple>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090021#include <vector>
22
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090023#include <android-base/stringprintf.h>
Ben Schwartz4204ecf2017-10-02 12:35:48 -040024#include <android-base/strings.h>
Robin Lee2cf56172016-09-13 18:55:42 +090025#include <cutils/properties.h>
Logan Chien3f461482018-04-23 14:31:32 +080026#include <log/log.h>
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090027#include <utils/Errors.h>
Pierre Imaibeedec32016-04-13 06:44:51 +090028#include <utils/String16.h>
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090029
30#include <binder/IPCThreadState.h>
31#include <binder/IServiceManager.h>
32#include "android/net/BnNetd.h"
33
Ben Schwartze7601812017-04-28 16:38:29 -040034#include <openssl/base64.h>
35
Lorenzo Colitti89faa342016-02-26 11:38:47 +090036#include "Controllers.h"
Erik Kline2d3a1632016-03-15 16:33:48 +090037#include "DumpWriter.h"
Michal Karpinskid5440112016-10-06 16:56:04 +010038#include "EventReporter.h"
Erik Kline55b06f82016-07-04 09:57:18 +090039#include "InterfaceController.h"
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090040#include "NetdConstants.h"
41#include "NetdNativeService.h"
Erik Kline85890042018-05-25 19:19:11 +090042#include "Process.h"
Robin Leeb8087362016-03-30 18:43:08 +010043#include "RouteController.h"
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090044#include "SockDiag.h"
Robin Leeb8087362016-03-30 18:43:08 +010045#include "UidRanges.h"
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090046
47using android::base::StringPrintf;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090048using android::os::PersistableBundle;
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090049
50namespace android {
51namespace net {
52
53namespace {
54
55const char CONNECTIVITY_INTERNAL[] = "android.permission.CONNECTIVITY_INTERNAL";
Joel Scherpelz08b84cd2017-05-22 13:11:54 +090056const char NETWORK_STACK[] = "android.permission.NETWORK_STACK";
Erik Kline2d3a1632016-03-15 16:33:48 +090057const char DUMP[] = "android.permission.DUMP";
Erik Klineb31fd692018-06-06 20:50:11 +090058const char OPT_SHORT[] = "--short";
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090059
60binder::Status checkPermission(const char *permission) {
61 pid_t pid;
62 uid_t uid;
63
64 if (checkCallingPermission(String16(permission), (int32_t *) &pid, (int32_t *) &uid)) {
65 return binder::Status::ok();
66 } else {
67 auto err = StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission);
68 return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str()));
69 }
70}
71
Robin Lee2cf56172016-09-13 18:55:42 +090072#define ENFORCE_DEBUGGABLE() { \
73 char value[PROPERTY_VALUE_MAX + 1]; \
Yi Kongbdfd57e2018-07-25 13:26:10 -070074 if (property_get("ro.debuggable", value, nullptr) != 1 \
Robin Lee2cf56172016-09-13 18:55:42 +090075 || value[0] != '1') { \
76 return binder::Status::fromExceptionCode( \
77 binder::Status::EX_SECURITY, \
78 String8("Not available in production builds.") \
79 ); \
80 } \
81}
82
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090083#define ENFORCE_PERMISSION(permission) { \
84 binder::Status status = checkPermission((permission)); \
85 if (!status.isOk()) { \
86 return status; \
87 } \
88}
89
Lorenzo Colitti89faa342016-02-26 11:38:47 +090090#define NETD_LOCKING_RPC(permission, lock) \
91 ENFORCE_PERMISSION(permission); \
Bernie Innocentiabf8a342018-08-10 15:17:16 +090092 std::lock_guard _lock(lock);
Lorenzo Colitti89faa342016-02-26 11:38:47 +090093
94#define NETD_BIG_LOCK_RPC(permission) NETD_LOCKING_RPC((permission), gBigNetdLock)
Lorenzo Colittid33e96d2016-12-15 23:59:01 +090095
96inline binder::Status statusFromErrcode(int ret) {
97 if (ret) {
98 return binder::Status::fromServiceSpecificError(-ret, strerror(-ret));
99 }
100 return binder::Status::ok();
101}
102
Erik Klineb31fd692018-06-06 20:50:11 +0900103bool contains(const Vector<String16>& words, const String16& word) {
104 for (const auto& w : words) {
105 if (w == word) return true;
106 }
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900107
Erik Klineb31fd692018-06-06 20:50:11 +0900108 return false;
109}
110
111} // namespace
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900112
Lorenzo Colittie4851de2016-03-17 13:23:28 +0900113status_t NetdNativeService::start() {
114 IPCThreadState::self()->disableBackgroundScheduling(true);
Erik Klineb31fd692018-06-06 20:50:11 +0900115 const status_t ret = BinderService<NetdNativeService>::publish();
Lorenzo Colittie4851de2016-03-17 13:23:28 +0900116 if (ret != android::OK) {
117 return ret;
118 }
119 sp<ProcessState> ps(ProcessState::self());
120 ps->startThreadPool();
121 ps->giveThreadPoolName();
122 return android::OK;
123}
124
Hugo Benichi7b314e12018-01-15 21:54:00 +0900125status_t NetdNativeService::dump(int fd, const Vector<String16> &args) {
Erik Kline2d3a1632016-03-15 16:33:48 +0900126 const binder::Status dump_permission = checkPermission(DUMP);
127 if (!dump_permission.isOk()) {
128 const String8 msg(dump_permission.toString8());
129 write(fd, msg.string(), msg.size());
130 return PERMISSION_DENIED;
131 }
132
133 // This method does not grab any locks. If individual classes need locking
134 // their dump() methods MUST handle locking appropriately.
Hugo Benichi7b314e12018-01-15 21:54:00 +0900135
Erik Kline2d3a1632016-03-15 16:33:48 +0900136 DumpWriter dw(fd);
Hugo Benichi7b314e12018-01-15 21:54:00 +0900137
138 if (!args.isEmpty() && args[0] == TcpSocketMonitor::DUMP_KEYWORD) {
139 dw.blankline();
140 gCtls->tcpSocketMonitor.dump(dw);
141 dw.blankline();
142 return NO_ERROR;
143 }
144
Chenbo Fengef297172018-03-26 10:53:33 -0700145 if (!args.isEmpty() && args[0] == TrafficController::DUMP_KEYWORD) {
146 dw.blankline();
147 gCtls->trafficCtrl.dump(dw, true);
148 dw.blankline();
149 return NO_ERROR;
150 }
151
Erik Kline85890042018-05-25 19:19:11 +0900152 process::dump(dw);
Erik Kline2d3a1632016-03-15 16:33:48 +0900153 dw.blankline();
154 gCtls->netCtrl.dump(dw);
155 dw.blankline();
156
Chenbo Fengef297172018-03-26 10:53:33 -0700157 gCtls->trafficCtrl.dump(dw, false);
158 dw.blankline();
159
Erik Klineb31fd692018-06-06 20:50:11 +0900160 {
161 ScopedIndent indentLog(dw);
162 if (contains(args, String16(OPT_SHORT))) {
163 dw.println("Log: <omitted>");
164 } else {
165 dw.println("Log:");
166 ScopedIndent indentLogEntries(dw);
167 gLog.forEachEntry([&dw](const std::string& entry) mutable { dw.println(entry); });
168 }
169 dw.blankline();
170 }
171
Erik Kline2d3a1632016-03-15 16:33:48 +0900172 return NO_ERROR;
173}
174
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900175binder::Status NetdNativeService::isAlive(bool *alive) {
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900176 NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900177 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900178
179 *alive = true;
Erik Klineb31fd692018-06-06 20:50:11 +0900180
181 gLog.log(entry.returns(*alive));
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900182 return binder::Status::ok();
183}
184
Erik Klinef52d4522018-03-14 15:01:46 +0900185binder::Status NetdNativeService::firewallReplaceUidChain(const std::string& chainName,
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900186 bool isWhitelist, const std::vector<int32_t>& uids, bool *ret) {
187 NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->firewallCtrl.lock);
Erik Klineb31fd692018-06-06 20:50:11 +0900188 auto entry = gLog.newEntry()
189 .prettyFunction(__PRETTY_FUNCTION__)
190 .arg(chainName)
191 .arg(isWhitelist)
192 .arg(uids);
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900193
Erik Klinef52d4522018-03-14 15:01:46 +0900194 int err = gCtls->firewallCtrl.replaceUidChain(chainName, isWhitelist, uids);
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900195 *ret = (err == 0);
Erik Klineb31fd692018-06-06 20:50:11 +0900196
197 gLog.log(entry.returns(*ret).withAutomaticDuration());
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900198 return binder::Status::ok();
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900199}
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900200
201binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
202 NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->bandwidthCtrl.lock);
Erik Klineb31fd692018-06-06 20:50:11 +0900203 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(enable);
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900204
205 int err = gCtls->bandwidthCtrl.enableDataSaver(enable);
206 *ret = (err == 0);
Erik Klineb31fd692018-06-06 20:50:11 +0900207 gLog.log(entry.returns(*ret).withAutomaticDuration());
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900208 return binder::Status::ok();
209}
210
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900211binder::Status NetdNativeService::networkCreatePhysical(int32_t netId,
212 const std::string& permission) {
213 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900214 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId).arg(permission);
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900215 int ret = gCtls->netCtrl.createPhysicalNetwork(netId, stringToPermission(permission.c_str()));
Erik Klineb31fd692018-06-06 20:50:11 +0900216 gLog.log(entry.returns(ret).withAutomaticDuration());
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900217 return statusFromErrcode(ret);
218}
219
220binder::Status NetdNativeService::networkCreateVpn(int32_t netId, bool hasDns, bool secure) {
221 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
222 int ret = gCtls->netCtrl.createVirtualNetwork(netId, hasDns, secure);
223 return statusFromErrcode(ret);
224}
225
226binder::Status NetdNativeService::networkDestroy(int32_t netId) {
Erik Klinec8b6a9c2018-01-15 17:06:48 +0900227 ENFORCE_PERMISSION(NETWORK_STACK);
228 // Both of these functions manage their own locking internally.
229 const int ret = gCtls->netCtrl.destroyNetwork(netId);
230 gCtls->resolverCtrl.clearDnsServers(netId);
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900231 return statusFromErrcode(ret);
232}
233
234binder::Status NetdNativeService::networkAddInterface(int32_t netId, const std::string& iface) {
235 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
236 int ret = gCtls->netCtrl.addInterfaceToNetwork(netId, iface.c_str());
237 return statusFromErrcode(ret);
238}
239
240binder::Status NetdNativeService::networkRemoveInterface(int32_t netId, const std::string& iface) {
241 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
242 int ret = gCtls->netCtrl.removeInterfaceFromNetwork(netId, iface.c_str());
243 return statusFromErrcode(ret);
244}
245
246binder::Status NetdNativeService::networkAddUidRanges(int32_t netId,
247 const std::vector<UidRange>& uidRangeArray) {
248 // NetworkController::addUsersToNetwork is thread-safe.
249 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
250 int ret = gCtls->netCtrl.addUsersToNetwork(netId, UidRanges(uidRangeArray));
251 return statusFromErrcode(ret);
252}
253
254binder::Status NetdNativeService::networkRemoveUidRanges(int32_t netId,
255 const std::vector<UidRange>& uidRangeArray) {
256 // NetworkController::removeUsersFromNetwork is thread-safe.
257 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
258 int ret = gCtls->netCtrl.removeUsersFromNetwork(netId, UidRanges(uidRangeArray));
259 return statusFromErrcode(ret);
260}
261
Robin Leeb8087362016-03-30 18:43:08 +0100262binder::Status NetdNativeService::networkRejectNonSecureVpn(bool add,
263 const std::vector<UidRange>& uidRangeArray) {
264 // TODO: elsewhere RouteController is only used from the tethering and network controllers, so
265 // it should be possible to use the same lock as NetworkController. However, every call through
266 // the CommandListener "network" command will need to hold this lock too, not just the ones that
267 // read/modify network internal state (that is sufficient for ::dump() because it doesn't
268 // look at routes, but it's not enough here).
269 NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
270
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900271 UidRanges uidRanges(uidRangeArray);
Robin Leeb8087362016-03-30 18:43:08 +0100272
273 int err;
274 if (add) {
275 err = RouteController::addUsersToRejectNonSecureNetworkRule(uidRanges);
276 } else {
277 err = RouteController::removeUsersFromRejectNonSecureNetworkRule(uidRanges);
278 }
279
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900280 return statusFromErrcode(err);
Robin Leeb8087362016-03-30 18:43:08 +0100281}
282
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900283binder::Status NetdNativeService::socketDestroy(const std::vector<UidRange>& uids,
284 const std::vector<int32_t>& skipUids) {
285
286 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
287
288 SockDiag sd;
289 if (!sd.open()) {
290 return binder::Status::fromServiceSpecificError(EIO,
291 String8("Could not open SOCK_DIAG socket"));
292 }
293
294 UidRanges uidRanges(uids);
Lorenzo Colittie5c3c992016-07-26 17:53:50 +0900295 int err = sd.destroySockets(uidRanges, std::set<uid_t>(skipUids.begin(), skipUids.end()),
296 true /* excludeLoopback */);
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900297
298 if (err) {
299 return binder::Status::fromServiceSpecificError(-err,
300 String8::format("destroySockets: %s", strerror(-err)));
301 }
Pierre Imaibeedec32016-04-13 06:44:51 +0900302 return binder::Status::ok();
303}
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900304
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400305// Parse a base64 encoded string into a vector of bytes.
306// On failure, return an empty vector.
307static std::vector<uint8_t> parseBase64(const std::string& input) {
308 std::vector<uint8_t> decoded;
309 size_t out_len;
310 if (EVP_DecodedLength(&out_len, input.size()) != 1) {
311 return decoded;
312 }
313 // out_len is now an upper bound on the output length.
314 decoded.resize(out_len);
315 if (EVP_DecodeBase64(decoded.data(), &out_len, decoded.size(),
316 reinterpret_cast<const uint8_t*>(input.data()), input.size()) == 1) {
317 // Possibly shrink the vector if the actual output was smaller than the bound.
318 decoded.resize(out_len);
319 } else {
320 decoded.clear();
321 }
322 if (out_len != SHA256_SIZE) {
323 decoded.clear();
324 }
325 return decoded;
326}
327
Pierre Imaibeedec32016-04-13 06:44:51 +0900328binder::Status NetdNativeService::setResolverConfiguration(int32_t netId,
329 const std::vector<std::string>& servers, const std::vector<std::string>& domains,
Erik Klinea1476fb2018-03-04 21:01:56 +0900330 const std::vector<int32_t>& params, const std::string& tlsName,
331 const std::vector<std::string>& tlsServers,
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400332 const std::vector<std::string>& tlsFingerprints) {
Pierre Imaibeedec32016-04-13 06:44:51 +0900333 // This function intentionally does not lock within Netd, as Bionic is thread-safe.
334 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900335 auto entry = gLog.newEntry()
336 .prettyFunction(__PRETTY_FUNCTION__)
337 .arg(netId)
338 .arg(servers)
339 .arg(domains)
340 .arg(params)
341 .arg(tlsName)
342 .arg(tlsServers)
343 .arg(tlsFingerprints);
Pierre Imaibeedec32016-04-13 06:44:51 +0900344
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400345 std::set<std::vector<uint8_t>> decoded_fingerprints;
346 for (const std::string& fingerprint : tlsFingerprints) {
347 std::vector<uint8_t> decoded = parseBase64(fingerprint);
348 if (decoded.empty()) {
349 return binder::Status::fromServiceSpecificError(EINVAL,
350 String8::format("ResolverController error: bad fingerprint"));
351 }
352 decoded_fingerprints.emplace(decoded);
353 }
354
355 int err = gCtls->resolverCtrl.setResolverConfiguration(netId, servers, domains, params,
Erik Klinea1476fb2018-03-04 21:01:56 +0900356 tlsName, tlsServers, decoded_fingerprints);
Erik Klineb31fd692018-06-06 20:50:11 +0900357 gLog.log(entry.returns(err).withAutomaticDuration());
Pierre Imaibeedec32016-04-13 06:44:51 +0900358 if (err != 0) {
359 return binder::Status::fromServiceSpecificError(-err,
360 String8::format("ResolverController error: %s", strerror(-err)));
361 }
362 return binder::Status::ok();
363}
364
365binder::Status NetdNativeService::getResolverInfo(int32_t netId,
366 std::vector<std::string>* servers, std::vector<std::string>* domains,
367 std::vector<int32_t>* params, std::vector<int32_t>* stats) {
368 // This function intentionally does not lock within Netd, as Bionic is thread-safe.
369 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
370
371 int err = gCtls->resolverCtrl.getResolverInfo(netId, servers, domains, params, stats);
372 if (err != 0) {
373 return binder::Status::fromServiceSpecificError(-err,
374 String8::format("ResolverController error: %s", strerror(-err)));
375 }
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900376 return binder::Status::ok();
377}
378
Erik Klinef48e4dd2016-07-18 04:02:07 +0900379binder::Status NetdNativeService::tetherApplyDnsInterfaces(bool *ret) {
Luke Huangd1ee4622018-06-29 13:49:58 +0800380 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
Erik Klinef48e4dd2016-07-18 04:02:07 +0900381
382 *ret = gCtls->tetherCtrl.applyDnsInterfaces();
383 return binder::Status::ok();
384}
385
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900386namespace {
387
388void tetherAddStats(PersistableBundle *bundle, const TetherController::TetherStats& stats) {
389 String16 iface = String16(stats.extIface.c_str());
390 std::vector<int64_t> statsVector(INetd::TETHER_STATS_ARRAY_SIZE);
391
392 bundle->getLongVector(iface, &statsVector);
393 if (statsVector.size() == 0) {
394 for (int i = 0; i < INetd::TETHER_STATS_ARRAY_SIZE; i++) statsVector.push_back(0);
395 }
396
Lorenzo Colitti9a65ac62017-09-04 18:07:56 +0900397 statsVector[INetd::TETHER_STATS_RX_BYTES] += stats.rxBytes;
398 statsVector[INetd::TETHER_STATS_RX_PACKETS] += stats.rxPackets;
399 statsVector[INetd::TETHER_STATS_TX_BYTES] += stats.txBytes;
400 statsVector[INetd::TETHER_STATS_TX_PACKETS] += stats.txPackets;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900401
402 bundle->putLongVector(iface, statsVector);
403}
404
405} // namespace
406
407binder::Status NetdNativeService::tetherGetStats(PersistableBundle *bundle) {
Luke Huangd1ee4622018-06-29 13:49:58 +0800408 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900409
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900410 const auto& statsList = gCtls->tetherCtrl.getTetherStats();
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900411 if (!isOk(statsList)) {
Nathan Harold28ccfef2018-03-16 19:02:47 -0700412 return asBinderStatus(statsList);
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900413 }
414
415 for (const auto& stats : statsList.value()) {
416 tetherAddStats(bundle, stats);
417 }
418
419 return binder::Status::ok();
420}
421
Erik Kline53c20882016-08-02 15:22:53 +0900422binder::Status NetdNativeService::interfaceAddAddress(const std::string &ifName,
423 const std::string &addrString, int prefixLength) {
424 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
425
426 const int err = InterfaceController::addAddress(
427 ifName.c_str(), addrString.c_str(), prefixLength);
428 if (err != 0) {
429 return binder::Status::fromServiceSpecificError(-err,
430 String8::format("InterfaceController error: %s", strerror(-err)));
431 }
432 return binder::Status::ok();
433}
434
435binder::Status NetdNativeService::interfaceDelAddress(const std::string &ifName,
436 const std::string &addrString, int prefixLength) {
437 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
438
439 const int err = InterfaceController::delAddress(
440 ifName.c_str(), addrString.c_str(), prefixLength);
441 if (err != 0) {
442 return binder::Status::fromServiceSpecificError(-err,
443 String8::format("InterfaceController error: %s", strerror(-err)));
444 }
445 return binder::Status::ok();
446}
447
Erik Kline38e51f12018-09-06 20:14:44 +0900448namespace {
Erik Kline55b06f82016-07-04 09:57:18 +0900449
Erik Kline38e51f12018-09-06 20:14:44 +0900450std::tuple<binder::Status, const char*, const char*> getPathComponents(int32_t ipversion,
451 int32_t category) {
452 const char* ipversionStr = nullptr;
453 switch (ipversion) {
Erik Kline55b06f82016-07-04 09:57:18 +0900454 case INetd::IPV4:
Erik Kline38e51f12018-09-06 20:14:44 +0900455 ipversionStr = "ipv4";
Erik Kline55b06f82016-07-04 09:57:18 +0900456 break;
457 case INetd::IPV6:
Erik Kline38e51f12018-09-06 20:14:44 +0900458 ipversionStr = "ipv6";
Erik Kline55b06f82016-07-04 09:57:18 +0900459 break;
460 default:
Erik Kline38e51f12018-09-06 20:14:44 +0900461 return {binder::Status::fromServiceSpecificError(EAFNOSUPPORT, "Bad IP version"),
462 nullptr, nullptr};
Erik Kline55b06f82016-07-04 09:57:18 +0900463 }
464
Erik Kline38e51f12018-09-06 20:14:44 +0900465 const char* whichStr = nullptr;
466 switch (category) {
Erik Kline55b06f82016-07-04 09:57:18 +0900467 case INetd::CONF:
468 whichStr = "conf";
469 break;
470 case INetd::NEIGH:
471 whichStr = "neigh";
472 break;
473 default:
Erik Kline38e51f12018-09-06 20:14:44 +0900474 return {binder::Status::fromServiceSpecificError(EINVAL, "Bad category"), nullptr,
475 nullptr};
Erik Kline55b06f82016-07-04 09:57:18 +0900476 }
477
Erik Kline38e51f12018-09-06 20:14:44 +0900478 return {binder::Status::ok(), ipversionStr, whichStr};
479}
480
481} // namespace
482
483binder::Status NetdNativeService::getProcSysNet(int32_t ipversion, int32_t which,
484 const std::string& ifname,
485 const std::string& parameter, std::string* value) {
486 ENFORCE_PERMISSION(NETWORK_STACK);
487 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__)
488 .args(ipversion, which, ifname, parameter);
489
490 const auto pathParts = getPathComponents(ipversion, which);
491 const auto& pathStatus = std::get<0>(pathParts);
492 if (!pathStatus.isOk()) {
493 gLog.log(entry.returns(pathStatus.exceptionCode()).withAutomaticDuration());
494 return pathStatus;
Erik Kline55b06f82016-07-04 09:57:18 +0900495 }
Erik Kline38e51f12018-09-06 20:14:44 +0900496
497 const int err = InterfaceController::getParameter(std::get<1>(pathParts),
498 std::get<2>(pathParts), ifname.c_str(),
499 parameter.c_str(), value);
500 entry.returns(err);
501 if (err == 0) entry.returns(*value);
502 gLog.log(entry.withAutomaticDuration());
503 return statusFromErrcode(err);
504}
505
506binder::Status NetdNativeService::setProcSysNet(int32_t ipversion, int32_t which,
507 const std::string& ifname,
508 const std::string& parameter,
509 const std::string& value) {
510 ENFORCE_PERMISSION(NETWORK_STACK);
511 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__)
512 .args(ipversion, which, ifname, parameter, value);
513
514 const auto pathParts = getPathComponents(ipversion, which);
515 const auto& pathStatus = std::get<0>(pathParts);
516 if (!pathStatus.isOk()) {
517 gLog.log(entry.returns(pathStatus.exceptionCode()).withAutomaticDuration());
518 return pathStatus;
519 }
520
521 const int err = InterfaceController::setParameter(std::get<1>(pathParts),
522 std::get<2>(pathParts), ifname.c_str(),
523 parameter.c_str(), value.c_str());
524 gLog.log(entry.returns(err).withAutomaticDuration());
525 return statusFromErrcode(err);
Erik Kline55b06f82016-07-04 09:57:18 +0900526}
527
Robin Lee2cf56172016-09-13 18:55:42 +0900528binder::Status NetdNativeService::getMetricsReportingLevel(int *reportingLevel) {
529 // This function intentionally does not lock, since the only thing it does is one read from an
530 // atomic_int.
531 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
532 ENFORCE_DEBUGGABLE();
533
Michal Karpinskid5440112016-10-06 16:56:04 +0100534 *reportingLevel = gCtls->eventReporter.getMetricsReportingLevel();
Robin Lee2cf56172016-09-13 18:55:42 +0900535 return binder::Status::ok();
536}
537
538binder::Status NetdNativeService::setMetricsReportingLevel(const int reportingLevel) {
539 // This function intentionally does not lock, since the only thing it does is one write to an
540 // atomic_int.
541 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
542 ENFORCE_DEBUGGABLE();
543
Michal Karpinskid5440112016-10-06 16:56:04 +0100544 return (gCtls->eventReporter.setMetricsReportingLevel(reportingLevel) == 0)
545 ? binder::Status::ok()
546 : binder::Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT);
Robin Lee2cf56172016-09-13 18:55:42 +0900547}
548
Benedict Wongb2daefb2017-12-06 22:05:46 -0800549binder::Status NetdNativeService::ipSecSetEncapSocketOwner(const android::base::unique_fd& socket,
550 int newUid) {
551 ENFORCE_PERMISSION(NETWORK_STACK)
Erik Klineb31fd692018-06-06 20:50:11 +0900552 gLog.log("ipSecSetEncapSocketOwner()");
Benedict Wongb2daefb2017-12-06 22:05:46 -0800553
554 uid_t callerUid = IPCThreadState::self()->getCallingUid();
555 return asBinderStatus(gCtls->xfrmCtrl.ipSecSetEncapSocketOwner(socket, newUid, callerUid));
556}
557
Nathan Harold1a371532017-01-30 12:30:48 -0800558binder::Status NetdNativeService::ipSecAllocateSpi(
559 int32_t transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800560 const std::string& sourceAddress,
561 const std::string& destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800562 int32_t inSpi,
563 int32_t* outSpi) {
564 // Necessary locking done in IpSecService and kernel
565 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900566 gLog.log("ipSecAllocateSpi()");
ludi6e8eccd2017-08-14 14:40:37 -0700567 return asBinderStatus(gCtls->xfrmCtrl.ipSecAllocateSpi(
Nathan Harold1a371532017-01-30 12:30:48 -0800568 transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800569 sourceAddress,
570 destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800571 inSpi,
572 outSpi));
573}
574
575binder::Status NetdNativeService::ipSecAddSecurityAssociation(
576 int32_t transformId,
577 int32_t mode,
Nathan Haroldda54f122018-01-09 16:42:57 -0800578 const std::string& sourceAddress,
579 const std::string& destinationAddress,
Benedict Wong96abf482018-01-22 13:56:41 -0800580 int32_t underlyingNetId,
Nathan Harold1a371532017-01-30 12:30:48 -0800581 int32_t spi,
Di Lu2ccb3e52018-01-03 16:19:20 -0800582 int32_t markValue,
583 int32_t markMask,
Nathan Harold1a371532017-01-30 12:30:48 -0800584 const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
585 const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
Benedict Wongbe65b432017-08-22 21:43:14 -0700586 const std::string& aeadAlgo, const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits,
Nathan Harold1a371532017-01-30 12:30:48 -0800587 int32_t encapType,
588 int32_t encapLocalPort,
ludiec836052017-05-20 14:17:05 -0700589 int32_t encapRemotePort) {
Nathan Harold1a371532017-01-30 12:30:48 -0800590 // Necessary locking done in IpSecService and kernel
591 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900592 gLog.log("ipSecAddSecurityAssociation()");
ludi6e8eccd2017-08-14 14:40:37 -0700593 return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityAssociation(
Benedict Wongad600cb2018-05-14 17:22:35 -0700594 transformId, mode, sourceAddress, destinationAddress, underlyingNetId, spi, markValue,
595 markMask, authAlgo, authKey, authTruncBits, cryptAlgo, cryptKey, cryptTruncBits,
596 aeadAlgo, aeadKey, aeadIcvBits, encapType, encapLocalPort, encapRemotePort));
Nathan Harold1a371532017-01-30 12:30:48 -0800597}
598
599binder::Status NetdNativeService::ipSecDeleteSecurityAssociation(
600 int32_t transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800601 const std::string& sourceAddress,
602 const std::string& destinationAddress,
Di Lu2ccb3e52018-01-03 16:19:20 -0800603 int32_t spi,
604 int32_t markValue,
605 int32_t markMask) {
Nathan Harold1a371532017-01-30 12:30:48 -0800606 // Necessary locking done in IpSecService and kernel
607 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900608 gLog.log("ipSecDeleteSecurityAssociation()");
ludi6e8eccd2017-08-14 14:40:37 -0700609 return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityAssociation(
Nathan Harold1a371532017-01-30 12:30:48 -0800610 transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800611 sourceAddress,
612 destinationAddress,
Di Lu2ccb3e52018-01-03 16:19:20 -0800613 spi,
614 markValue,
615 markMask));
Nathan Harold1a371532017-01-30 12:30:48 -0800616}
617
618binder::Status NetdNativeService::ipSecApplyTransportModeTransform(
619 const android::base::unique_fd& socket,
620 int32_t transformId,
621 int32_t direction,
Nathan Haroldda54f122018-01-09 16:42:57 -0800622 const std::string& sourceAddress,
623 const std::string& destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800624 int32_t spi) {
625 // Necessary locking done in IpSecService and kernel
626 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900627 gLog.log("ipSecApplyTransportModeTransform()");
ludi6e8eccd2017-08-14 14:40:37 -0700628 return asBinderStatus(gCtls->xfrmCtrl.ipSecApplyTransportModeTransform(
Nathan Harold1a371532017-01-30 12:30:48 -0800629 socket,
630 transformId,
631 direction,
Nathan Haroldda54f122018-01-09 16:42:57 -0800632 sourceAddress,
633 destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800634 spi));
635}
636
637binder::Status NetdNativeService::ipSecRemoveTransportModeTransform(
638 const android::base::unique_fd& socket) {
639 // Necessary locking done in IpSecService and kernel
640 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900641 gLog.log("ipSecRemoveTransportModeTransform()");
ludi6e8eccd2017-08-14 14:40:37 -0700642 return asBinderStatus(gCtls->xfrmCtrl.ipSecRemoveTransportModeTransform(
Nathan Harold1a371532017-01-30 12:30:48 -0800643 socket));
644}
645
Benedict Wonga04ffa72018-05-09 21:42:42 -0700646binder::Status NetdNativeService::ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
647 int32_t direction,
Benedict Wongad600cb2018-05-14 17:22:35 -0700648 const std::string& tmplSrcAddress,
649 const std::string& tmplDstAddress,
650 int32_t spi, int32_t markValue,
651 int32_t markMask) {
Benedict Wong84a8dca2018-01-19 12:12:17 -0800652 // Necessary locking done in IpSecService and kernel
653 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900654 gLog.log("ipSecAddSecurityPolicy()");
Benedict Wong84a8dca2018-01-19 12:12:17 -0800655 return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityPolicy(
Benedict Wonga04ffa72018-05-09 21:42:42 -0700656 transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
657 markMask));
Benedict Wong84a8dca2018-01-19 12:12:17 -0800658}
659
Benedict Wonga04ffa72018-05-09 21:42:42 -0700660binder::Status NetdNativeService::ipSecUpdateSecurityPolicy(int32_t transformId,
661 int32_t selAddrFamily,
662 int32_t direction,
Benedict Wongad600cb2018-05-14 17:22:35 -0700663 const std::string& tmplSrcAddress,
664 const std::string& tmplDstAddress,
665 int32_t spi, int32_t markValue,
666 int32_t markMask) {
Benedict Wong84a8dca2018-01-19 12:12:17 -0800667 // Necessary locking done in IpSecService and kernel
668 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900669 gLog.log("ipSecAddSecurityPolicy()");
Benedict Wong84a8dca2018-01-19 12:12:17 -0800670 return asBinderStatus(gCtls->xfrmCtrl.ipSecUpdateSecurityPolicy(
Benedict Wonga04ffa72018-05-09 21:42:42 -0700671 transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
672 markMask));
Benedict Wong84a8dca2018-01-19 12:12:17 -0800673}
674
Benedict Wonga04ffa72018-05-09 21:42:42 -0700675binder::Status NetdNativeService::ipSecDeleteSecurityPolicy(int32_t transformId,
676 int32_t selAddrFamily,
677 int32_t direction, int32_t markValue,
678 int32_t markMask) {
Benedict Wong84a8dca2018-01-19 12:12:17 -0800679 // Necessary locking done in IpSecService and kernel
680 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900681 gLog.log("ipSecAddSecurityPolicy()");
Benedict Wong84a8dca2018-01-19 12:12:17 -0800682 return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityPolicy(
Benedict Wonga04ffa72018-05-09 21:42:42 -0700683 transformId, selAddrFamily, direction, markValue, markMask));
Benedict Wong84a8dca2018-01-19 12:12:17 -0800684}
685
manojboopathi8707f232018-01-02 14:45:47 -0800686binder::Status NetdNativeService::addVirtualTunnelInterface(
687 const std::string& deviceName,
688 const std::string& localAddress,
689 const std::string& remoteAddress,
690 int32_t iKey,
691 int32_t oKey) {
692 // Necessary locking done in IpSecService and kernel
693 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900694 gLog.log("addVirtualTunnelInterface()");
manojboopathi8707f232018-01-02 14:45:47 -0800695 int ret = gCtls->xfrmCtrl.addVirtualTunnelInterface(
696 deviceName,
697 localAddress,
698 remoteAddress,
699 iKey,
700 oKey,
701 false);
702
703 return (ret == 0) ? binder::Status::ok() :
704 asBinderStatus(netdutils::statusFromErrno(
705 ret, "Error in creating virtual tunnel interface."));
706}
707
708binder::Status NetdNativeService::updateVirtualTunnelInterface(
709 const std::string& deviceName,
710 const std::string& localAddress,
711 const std::string& remoteAddress,
712 int32_t iKey,
713 int32_t oKey) {
714 // Necessary locking done in IpSecService and kernel
715 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900716 gLog.log("updateVirtualTunnelInterface()");
manojboopathi8707f232018-01-02 14:45:47 -0800717 int ret = gCtls->xfrmCtrl.addVirtualTunnelInterface(
718 deviceName,
719 localAddress,
720 remoteAddress,
721 iKey,
722 oKey,
723 true);
724
725 return (ret == 0) ? binder::Status::ok() :
726 asBinderStatus(netdutils::statusFromErrno(
727 ret, "Error in updating virtual tunnel interface."));
728}
729
730binder::Status NetdNativeService::removeVirtualTunnelInterface(const std::string& deviceName) {
731 // Necessary locking done in IpSecService and kernel
732 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900733 gLog.log("removeVirtualTunnelInterface()");
manojboopathi8707f232018-01-02 14:45:47 -0800734 int ret = gCtls->xfrmCtrl.removeVirtualTunnelInterface(deviceName);
735
736 return (ret == 0) ? binder::Status::ok() :
737 asBinderStatus(netdutils::statusFromErrno(
738 ret, "Error in removing virtual tunnel interface."));
739}
740
Joel Scherpelzde937962017-06-01 13:20:21 +0900741binder::Status NetdNativeService::setIPv6AddrGenMode(const std::string& ifName,
742 int32_t mode) {
743 ENFORCE_PERMISSION(NETWORK_STACK);
Nathan Harold28ccfef2018-03-16 19:02:47 -0700744 return asBinderStatus(InterfaceController::setIPv6AddrGenMode(ifName, mode));
Joel Scherpelzde937962017-06-01 13:20:21 +0900745}
746
Joel Scherpelz08b84cd2017-05-22 13:11:54 +0900747binder::Status NetdNativeService::wakeupAddInterface(const std::string& ifName,
748 const std::string& prefix, int32_t mark,
749 int32_t mask) {
750 ENFORCE_PERMISSION(NETWORK_STACK);
Nathan Harold28ccfef2018-03-16 19:02:47 -0700751 return asBinderStatus(gCtls->wakeupCtrl.addInterface(ifName, prefix, mark, mask));
Joel Scherpelz08b84cd2017-05-22 13:11:54 +0900752}
753
754binder::Status NetdNativeService::wakeupDelInterface(const std::string& ifName,
755 const std::string& prefix, int32_t mark,
756 int32_t mask) {
757 ENFORCE_PERMISSION(NETWORK_STACK);
Nathan Harold28ccfef2018-03-16 19:02:47 -0700758 return asBinderStatus(gCtls->wakeupCtrl.delInterface(ifName, prefix, mark, mask));
Joel Scherpelz08b84cd2017-05-22 13:11:54 +0900759}
760
Chenbo Feng07d43fe2017-12-21 14:38:51 -0800761binder::Status NetdNativeService::trafficCheckBpfStatsEnable(bool* ret) {
762 ENFORCE_PERMISSION(NETWORK_STACK);
763 *ret = gCtls->trafficCtrl.checkBpfStatsEnable();
764 return binder::Status::ok();
765}
766
Luke Huang0051a622018-07-23 20:30:16 +0800767binder::Status NetdNativeService::idletimerAddInterface(const std::string& ifName, int32_t timeout,
768 const std::string& classLabel) {
769 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->idletimerCtrl.lock);
770 auto entry = gLog.newEntry()
771 .prettyFunction(__PRETTY_FUNCTION__)
772 .arg(ifName)
773 .arg(timeout)
774 .arg(classLabel);
775 int res =
776 gCtls->idletimerCtrl.addInterfaceIdletimer(ifName.c_str(), timeout, classLabel.c_str());
777 gLog.log(entry.returns(res).withAutomaticDuration());
778 return statusFromErrcode(res);
779}
780
781binder::Status NetdNativeService::idletimerRemoveInterface(const std::string& ifName,
782 int32_t timeout,
783 const std::string& classLabel) {
784 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->idletimerCtrl.lock);
785 auto entry = gLog.newEntry()
786 .prettyFunction(__PRETTY_FUNCTION__)
787 .arg(ifName)
788 .arg(timeout)
789 .arg(classLabel);
790 int res = gCtls->idletimerCtrl.removeInterfaceIdletimer(ifName.c_str(), timeout,
791 classLabel.c_str());
792 gLog.log(entry.returns(res).withAutomaticDuration());
793 return statusFromErrcode(res);
794}
Luke Huanga67dd562018-07-17 19:58:25 +0800795
796binder::Status NetdNativeService::strictUidCleartextPenalty(int32_t uid, int32_t policyPenalty) {
797 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->strictCtrl.lock);
798 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid).arg(policyPenalty);
799 StrictPenalty penalty;
800 switch (policyPenalty) {
801 case INetd::PENALTY_POLICY_REJECT:
802 penalty = REJECT;
803 break;
804 case INetd::PENALTY_POLICY_LOG:
805 penalty = LOG;
806 break;
807 case INetd::PENALTY_POLICY_ACCEPT:
808 penalty = ACCEPT;
809 break;
810 default:
811 return statusFromErrcode(-EINVAL);
812 break;
813 }
814 int res = gCtls->strictCtrl.setUidCleartextPenalty((uid_t) uid, penalty);
815 gLog.log(entry.returns(res).withAutomaticDuration());
816 return statusFromErrcode(res);
817}
Luke Huang6d301232018-08-01 14:05:18 +0800818binder::Status NetdNativeService::clatdStart(const std::string& ifName) {
819 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->clatdCtrl.mutex);
820 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
821 int res = gCtls->clatdCtrl.startClatd(ifName.c_str());
822 gLog.log(entry.returns(res).withAutomaticDuration());
823 return statusFromErrcode(res);
824}
825
826binder::Status NetdNativeService::clatdStop(const std::string& ifName) {
827 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->clatdCtrl.mutex);
828 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
829 int res = gCtls->clatdCtrl.stopClatd(ifName.c_str());
830 gLog.log(entry.returns(res).withAutomaticDuration());
831 return statusFromErrcode(res);
832}
Luke Huanga67dd562018-07-17 19:58:25 +0800833
Luke Huang457d4702018-08-16 15:39:15 +0800834binder::Status NetdNativeService::ipfwdEnabled(bool* status) {
835 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
836 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
837 *status = (gCtls->tetherCtrl.forwardingRequestCount() > 0) ? true : false;
838 gLog.log(entry.returns(*status).withAutomaticDuration());
839 return binder::Status::ok();
840}
841
842binder::Status NetdNativeService::ipfwdEnableForwarding(const std::string& requester) {
843 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
844 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(requester);
845 int res = (gCtls->tetherCtrl.enableForwarding(requester.c_str())) ? 0 : -EREMOTEIO;
846 gLog.log(entry.returns(res).withAutomaticDuration());
847 return statusFromErrcode(res);
848}
849
850binder::Status NetdNativeService::ipfwdDisableForwarding(const std::string& requester) {
851 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
852 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(requester);
853 int res = (gCtls->tetherCtrl.disableForwarding(requester.c_str())) ? 0 : -EREMOTEIO;
854 gLog.log(entry.returns(res).withAutomaticDuration());
855 return statusFromErrcode(res);
856}
857
858binder::Status NetdNativeService::ipfwdAddInterfaceForward(const std::string& fromIface,
859 const std::string& toIface) {
860 ENFORCE_PERMISSION(NETWORK_STACK);
861 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(fromIface).arg(toIface);
862 int res = RouteController::enableTethering(fromIface.c_str(), toIface.c_str());
863 gLog.log(entry.returns(res).withAutomaticDuration());
864 return statusFromErrcode(res);
865}
866
867binder::Status NetdNativeService::ipfwdRemoveInterfaceForward(const std::string& fromIface,
868 const std::string& toIface) {
869 ENFORCE_PERMISSION(NETWORK_STACK);
870 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(fromIface).arg(toIface);
871 int res = RouteController::disableTethering(fromIface.c_str(), toIface.c_str());
872 gLog.log(entry.returns(res).withAutomaticDuration());
873 return statusFromErrcode(res);
874}
875
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900876} // namespace net
877} // namespace android