• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
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 
19 #include <cinttypes>
20 #include <numeric>
21 #include <set>
22 #include <string>
23 #include <tuple>
24 #include <vector>
25 
26 #include <android-base/file.h>
27 #include <android-base/stringprintf.h>
28 #include <android-base/strings.h>
29 #include <binder/IPCThreadState.h>
30 #include <binder/IServiceManager.h>
31 #include <binder/Status.h>
32 #include <cutils/properties.h>
33 #include <log/log.h>
34 #include <netdutils/DumpWriter.h>
35 #include <utils/Errors.h>
36 #include <utils/String16.h>
37 
38 #include "Controllers.h"
39 #include "Fwmark.h"
40 #include "InterfaceController.h"
41 #include "NetdNativeService.h"
42 #include "OemNetdListener.h"
43 #include "Permission.h"
44 #include "Process.h"
45 #include "RouteController.h"
46 #include "SockDiag.h"
47 #include "UidRanges.h"
48 #include "android/net/BnNetd.h"
49 #include "binder_utils/BinderUtil.h"
50 #include "binder_utils/NetdPermissions.h"
51 #include "netid_client.h"  // NETID_UNSET
52 
53 using android::base::StringPrintf;
54 using android::base::WriteStringToFile;
55 using android::net::TetherOffloadRuleParcel;
56 using android::net::TetherStatsParcel;
57 using android::net::UidRangeParcel;
58 using android::netdutils::DumpWriter;
59 using android::netdutils::ScopedIndent;
60 using android::os::ParcelFileDescriptor;
61 
62 namespace android {
63 namespace net {
64 
65 namespace {
66 const char OPT_SHORT[] = "--short";
67 
68 // The input permissions should be equivalent that this function would return ok if any of them is
69 // granted.
checkAnyPermission(const std::vector<const char * > & permissions)70 binder::Status checkAnyPermission(const std::vector<const char*>& permissions) {
71     pid_t pid = IPCThreadState::self()->getCallingPid();
72     uid_t uid = IPCThreadState::self()->getCallingUid();
73 
74     // TODO: Do the pure permission check in this function. Have another method
75     // (e.g. checkNetworkStackPermission) to wrap AID_SYSTEM and
76     // AID_NETWORK_STACK uid check.
77     // If the caller is the system UID, don't check permissions.
78     // Otherwise, if the system server's binder thread pool is full, and all the threads are
79     // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
80     //
81     // From a security perspective, there is currently no difference, because:
82     // 1. The system server has the NETWORK_STACK permission, which grants access to all the
83     //    IPCs in this file.
84     // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
85     if (uid == AID_SYSTEM) {
86         return binder::Status::ok();
87     }
88     // AID_NETWORK_STACK own MAINLINE_NETWORK_STACK permission, don't IPC to system server to check
89     // MAINLINE_NETWORK_STACK permission. Cross-process(netd, networkstack and system server)
90     // deadlock: http://b/149766727
91     if (uid == AID_NETWORK_STACK) {
92         for (const char* permission : permissions) {
93             if (std::strcmp(permission, PERM_MAINLINE_NETWORK_STACK) == 0) {
94                 return binder::Status::ok();
95             }
96         }
97     }
98 
99     for (const char* permission : permissions) {
100         if (checkPermission(String16(permission), pid, uid)) {
101             return binder::Status::ok();
102         }
103     }
104 
105     auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s",
106                             uid, pid, android::base::Join(permissions, ',').c_str());
107     return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, err.c_str());
108 }
109 
110 #define ENFORCE_ANY_PERMISSION(...)                                \
111     do {                                                           \
112         binder::Status status = checkAnyPermission({__VA_ARGS__}); \
113         if (!status.isOk()) {                                      \
114             return status;                                         \
115         }                                                          \
116     } while (0)
117 
118 #define NETD_LOCKING_RPC(lock, ... /* permissions */) \
119     ENFORCE_ANY_PERMISSION(__VA_ARGS__);              \
120     std::lock_guard _lock(lock);
121 
122 #define NETD_BIG_LOCK_RPC(... /* permissions */) NETD_LOCKING_RPC(gBigNetdLock, __VA_ARGS__)
123 
124 #define RETURN_BINDER_STATUS_IF_NOT_OK(logEntry, res) \
125     do {                                              \
126         if (!isOk((res))) {                           \
127             logErrorStatus((logEntry), (res));        \
128             return asBinderStatus((res));             \
129         }                                             \
130     } while (0)
131 
132 #define ENFORCE_NETWORK_STACK_PERMISSIONS() \
133     ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK)
134 
logErrorStatus(netdutils::LogEntry & logEntry,const netdutils::Status & status)135 void logErrorStatus(netdutils::LogEntry& logEntry, const netdutils::Status& status) {
136     gLog.log(logEntry.returns(status.code()).withAutomaticDuration());
137 }
138 
asBinderStatus(const netdutils::Status & status)139 binder::Status asBinderStatus(const netdutils::Status& status) {
140     if (isOk(status)) {
141         return binder::Status::ok();
142     }
143     return binder::Status::fromServiceSpecificError(status.code(), status.msg().c_str());
144 }
145 
146 template <typename T>
asBinderStatus(const base::Result<T> result)147 binder::Status asBinderStatus(const base::Result<T> result) {
148     if (result.ok()) return binder::Status::ok();
149 
150     return binder::Status::fromServiceSpecificError(result.error().code(),
151                                                     result.error().message().c_str());
152 }
153 
statusFromErrcode(int ret)154 inline binder::Status statusFromErrcode(int ret) {
155     if (ret) {
156         return binder::Status::fromServiceSpecificError(-ret, strerror(-ret));
157     }
158     return binder::Status::ok();
159 }
160 
contains(const Vector<String16> & words,const String16 & word)161 bool contains(const Vector<String16>& words, const String16& word) {
162     for (const auto& w : words) {
163         if (w == word) return true;
164     }
165 
166     return false;
167 }
168 
169 }  // namespace
170 
NetdNativeService()171 NetdNativeService::NetdNativeService() {
172     // register log callback to BnNetd::logFunc
173     BnNetd::logFunc = std::bind(binderCallLogFn, std::placeholders::_1,
174                                 [](const std::string& msg) { gLog.info("%s", msg.c_str()); });
175 }
176 
start()177 status_t NetdNativeService::start() {
178     IPCThreadState::self()->disableBackgroundScheduling(true);
179     const status_t ret = BinderService<NetdNativeService>::publish();
180     if (ret != android::OK) {
181         return ret;
182     }
183     sp<ProcessState> ps(ProcessState::self());
184     ps->startThreadPool();
185     ps->giveThreadPoolName();
186 
187     return android::OK;
188 }
189 
dump(int fd,const Vector<String16> & args)190 status_t NetdNativeService::dump(int fd, const Vector<String16> &args) {
191     const binder::Status dump_permission = checkAnyPermission({PERM_DUMP});
192     if (!dump_permission.isOk()) {
193         const String8 msg(dump_permission.toString8());
194         write(fd, msg.string(), msg.size());
195         return PERMISSION_DENIED;
196     }
197 
198     // This method does not grab any locks. If individual classes need locking
199     // their dump() methods MUST handle locking appropriately.
200 
201     DumpWriter dw(fd);
202 
203     if (!args.isEmpty() && args[0] == TcpSocketMonitor::DUMP_KEYWORD) {
204       dw.blankline();
205       gCtls->tcpSocketMonitor.dump(dw);
206       dw.blankline();
207       return NO_ERROR;
208     }
209 
210     if (!args.isEmpty() && args[0] == TrafficController::DUMP_KEYWORD) {
211         dw.blankline();
212         gCtls->trafficCtrl.dump(dw, true);
213         dw.blankline();
214         return NO_ERROR;
215     }
216 
217     process::dump(dw);
218     dw.blankline();
219     gCtls->netCtrl.dump(dw);
220     dw.blankline();
221 
222     gCtls->trafficCtrl.dump(dw, false);
223     dw.blankline();
224 
225     gCtls->xfrmCtrl.dump(dw);
226     dw.blankline();
227 
228     gCtls->clatdCtrl.dump(dw);
229     dw.blankline();
230 
231     gCtls->tetherCtrl.dump(dw);
232     dw.blankline();
233 
234     {
235         ScopedIndent indentLog(dw);
236         if (contains(args, String16(OPT_SHORT))) {
237             dw.println("Log: <omitted>");
238         } else {
239             dw.println("Log:");
240             ScopedIndent indentLogEntries(dw);
241             gLog.forEachEntry([&dw](const std::string& entry) mutable { dw.println(entry); });
242         }
243         dw.blankline();
244     }
245 
246     {
247         ScopedIndent indentLog(dw);
248         if (contains(args, String16(OPT_SHORT))) {
249             dw.println("UnsolicitedLog: <omitted>");
250         } else {
251             dw.println("UnsolicitedLog:");
252             ScopedIndent indentLogEntries(dw);
253             gUnsolicitedLog.forEachEntry(
254                     [&dw](const std::string& entry) mutable { dw.println(entry); });
255         }
256         dw.blankline();
257     }
258 
259     return NO_ERROR;
260 }
261 
isAlive(bool * alive)262 binder::Status NetdNativeService::isAlive(bool *alive) {
263     NETD_BIG_LOCK_RPC(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
264 
265     *alive = true;
266 
267     return binder::Status::ok();
268 }
269 
firewallReplaceUidChain(const std::string & chainName,bool isWhitelist,const std::vector<int32_t> & uids,bool * ret)270 binder::Status NetdNativeService::firewallReplaceUidChain(const std::string& chainName,
271         bool isWhitelist, const std::vector<int32_t>& uids, bool *ret) {
272     NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
273     int err = gCtls->firewallCtrl.replaceUidChain(chainName, isWhitelist, uids);
274     *ret = (err == 0);
275     return binder::Status::ok();
276 }
277 
bandwidthEnableDataSaver(bool enable,bool * ret)278 binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
279     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
280     int err = gCtls->bandwidthCtrl.enableDataSaver(enable);
281     *ret = (err == 0);
282     return binder::Status::ok();
283 }
284 
bandwidthSetInterfaceQuota(const std::string & ifName,int64_t bytes)285 binder::Status NetdNativeService::bandwidthSetInterfaceQuota(const std::string& ifName,
286                                                              int64_t bytes) {
287     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
288     int res = gCtls->bandwidthCtrl.setInterfaceQuota(ifName, bytes);
289     return statusFromErrcode(res);
290 }
291 
bandwidthRemoveInterfaceQuota(const std::string & ifName)292 binder::Status NetdNativeService::bandwidthRemoveInterfaceQuota(const std::string& ifName) {
293     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
294     int res = gCtls->bandwidthCtrl.removeInterfaceQuota(ifName);
295     return statusFromErrcode(res);
296 }
297 
bandwidthSetInterfaceAlert(const std::string & ifName,int64_t bytes)298 binder::Status NetdNativeService::bandwidthSetInterfaceAlert(const std::string& ifName,
299                                                              int64_t bytes) {
300     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
301     int res = gCtls->bandwidthCtrl.setInterfaceAlert(ifName, bytes);
302     return statusFromErrcode(res);
303 }
304 
bandwidthRemoveInterfaceAlert(const std::string & ifName)305 binder::Status NetdNativeService::bandwidthRemoveInterfaceAlert(const std::string& ifName) {
306     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
307     int res = gCtls->bandwidthCtrl.removeInterfaceAlert(ifName);
308     return statusFromErrcode(res);
309 }
310 
bandwidthSetGlobalAlert(int64_t bytes)311 binder::Status NetdNativeService::bandwidthSetGlobalAlert(int64_t bytes) {
312     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
313     int res = gCtls->bandwidthCtrl.setGlobalAlert(bytes);
314     return statusFromErrcode(res);
315 }
316 
bandwidthAddNaughtyApp(int32_t uid)317 binder::Status NetdNativeService::bandwidthAddNaughtyApp(int32_t uid) {
318     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
319     std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
320     int res = gCtls->bandwidthCtrl.addNaughtyApps(appStrUids);
321     return statusFromErrcode(res);
322 }
323 
bandwidthRemoveNaughtyApp(int32_t uid)324 binder::Status NetdNativeService::bandwidthRemoveNaughtyApp(int32_t uid) {
325     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
326     std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
327     int res = gCtls->bandwidthCtrl.removeNaughtyApps(appStrUids);
328     return statusFromErrcode(res);
329 }
330 
bandwidthAddNiceApp(int32_t uid)331 binder::Status NetdNativeService::bandwidthAddNiceApp(int32_t uid) {
332     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
333     std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
334     int res = gCtls->bandwidthCtrl.addNiceApps(appStrUids);
335     return statusFromErrcode(res);
336 }
337 
bandwidthRemoveNiceApp(int32_t uid)338 binder::Status NetdNativeService::bandwidthRemoveNiceApp(int32_t uid) {
339     NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
340     std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
341     int res = gCtls->bandwidthCtrl.removeNiceApps(appStrUids);
342     return statusFromErrcode(res);
343 }
344 
networkCreatePhysical(int32_t netId,int32_t permission)345 binder::Status NetdNativeService::networkCreatePhysical(int32_t netId, int32_t permission) {
346     ENFORCE_NETWORK_STACK_PERMISSIONS();
347     int ret = gCtls->netCtrl.createPhysicalNetwork(netId, convertPermission(permission));
348     return statusFromErrcode(ret);
349 }
350 
networkCreateVpn(int32_t netId,bool secure)351 binder::Status NetdNativeService::networkCreateVpn(int32_t netId, bool secure) {
352     ENFORCE_NETWORK_STACK_PERMISSIONS();
353     int ret = gCtls->netCtrl.createVirtualNetwork(netId, secure);
354     return statusFromErrcode(ret);
355 }
356 
networkDestroy(int32_t netId)357 binder::Status NetdNativeService::networkDestroy(int32_t netId) {
358     ENFORCE_NETWORK_STACK_PERMISSIONS();
359     // NetworkController::destroyNetwork is thread-safe.
360     const int ret = gCtls->netCtrl.destroyNetwork(netId);
361     return statusFromErrcode(ret);
362 }
363 
networkAddInterface(int32_t netId,const std::string & iface)364 binder::Status NetdNativeService::networkAddInterface(int32_t netId, const std::string& iface) {
365     ENFORCE_NETWORK_STACK_PERMISSIONS();
366     int ret = gCtls->netCtrl.addInterfaceToNetwork(netId, iface.c_str());
367     return statusFromErrcode(ret);
368 }
369 
networkRemoveInterface(int32_t netId,const std::string & iface)370 binder::Status NetdNativeService::networkRemoveInterface(int32_t netId, const std::string& iface) {
371     ENFORCE_NETWORK_STACK_PERMISSIONS();
372     int ret = gCtls->netCtrl.removeInterfaceFromNetwork(netId, iface.c_str());
373     return statusFromErrcode(ret);
374 }
375 
networkAddUidRanges(int32_t netId,const std::vector<UidRangeParcel> & uidRangeArray)376 binder::Status NetdNativeService::networkAddUidRanges(
377         int32_t netId, const std::vector<UidRangeParcel>& uidRangeArray) {
378     // NetworkController::addUsersToNetwork is thread-safe.
379     ENFORCE_NETWORK_STACK_PERMISSIONS();
380     int ret = gCtls->netCtrl.addUsersToNetwork(netId, UidRanges(uidRangeArray));
381     return statusFromErrcode(ret);
382 }
383 
networkRemoveUidRanges(int32_t netId,const std::vector<UidRangeParcel> & uidRangeArray)384 binder::Status NetdNativeService::networkRemoveUidRanges(
385         int32_t netId, const std::vector<UidRangeParcel>& uidRangeArray) {
386     // NetworkController::removeUsersFromNetwork is thread-safe.
387     ENFORCE_NETWORK_STACK_PERMISSIONS();
388     int ret = gCtls->netCtrl.removeUsersFromNetwork(netId, UidRanges(uidRangeArray));
389     return statusFromErrcode(ret);
390 }
391 
networkRejectNonSecureVpn(bool add,const std::vector<UidRangeParcel> & uidRangeArray)392 binder::Status NetdNativeService::networkRejectNonSecureVpn(
393         bool add, const std::vector<UidRangeParcel>& uidRangeArray) {
394     // TODO: elsewhere RouteController is only used from the tethering and network controllers, so
395     // it should be possible to use the same lock as NetworkController. However, every call through
396     // the CommandListener "network" command will need to hold this lock too, not just the ones that
397     // read/modify network internal state (that is sufficient for ::dump() because it doesn't
398     // look at routes, but it's not enough here).
399     NETD_BIG_LOCK_RPC(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
400     UidRanges uidRanges(uidRangeArray);
401 
402     int err;
403     if (add) {
404         err = RouteController::addUsersToRejectNonSecureNetworkRule(uidRanges);
405     } else {
406         err = RouteController::removeUsersFromRejectNonSecureNetworkRule(uidRanges);
407     }
408     return statusFromErrcode(err);
409 }
410 
socketDestroy(const std::vector<UidRangeParcel> & uids,const std::vector<int32_t> & skipUids)411 binder::Status NetdNativeService::socketDestroy(const std::vector<UidRangeParcel>& uids,
412                                                 const std::vector<int32_t>& skipUids) {
413     ENFORCE_NETWORK_STACK_PERMISSIONS();
414 
415     SockDiag sd;
416     if (!sd.open()) {
417         return binder::Status::fromServiceSpecificError(EIO,
418                 String8("Could not open SOCK_DIAG socket"));
419     }
420 
421     UidRanges uidRanges(uids);
422     int err = sd.destroySockets(uidRanges, std::set<uid_t>(skipUids.begin(), skipUids.end()),
423                                 true /* excludeLoopback */);
424     if (err) {
425         return binder::Status::fromServiceSpecificError(-err,
426                 String8::format("destroySockets: %s", strerror(-err)));
427     }
428     return binder::Status::ok();
429 }
430 
tetherApplyDnsInterfaces(bool * ret)431 binder::Status NetdNativeService::tetherApplyDnsInterfaces(bool *ret) {
432     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
433     *ret = gCtls->tetherCtrl.applyDnsInterfaces();
434     return binder::Status::ok();
435 }
436 
437 namespace {
438 
439 constexpr const int UNUSED_IFINDEX = 0;
440 
tetherAddStatsByInterface(TetherController::TetherStats * tetherStatsParcel,const TetherController::TetherStats & tetherStats)441 void tetherAddStatsByInterface(TetherController::TetherStats* tetherStatsParcel,
442                                const TetherController::TetherStats& tetherStats) {
443     if (tetherStatsParcel->extIface == tetherStats.extIface) {
444         tetherStatsParcel->rxBytes += tetherStats.rxBytes;
445         tetherStatsParcel->rxPackets += tetherStats.rxPackets;
446         tetherStatsParcel->txBytes += tetherStats.txBytes;
447         tetherStatsParcel->txPackets += tetherStats.txPackets;
448     }
449 }
450 
toTetherStatsParcel(const TetherController::TetherStats & stats)451 TetherStatsParcel toTetherStatsParcel(const TetherController::TetherStats& stats) {
452     TetherStatsParcel result;
453     result.iface = stats.extIface;
454     result.rxBytes = stats.rxBytes;
455     result.rxPackets = stats.rxPackets;
456     result.txBytes = stats.txBytes;
457     result.txPackets = stats.txPackets;
458     result.ifIndex = UNUSED_IFINDEX;
459     return result;
460 }
461 
setTetherStatsParcelVecByInterface(std::vector<TetherStatsParcel> * tetherStatsVec,const TetherController::TetherStatsList & statsList)462 void setTetherStatsParcelVecByInterface(std::vector<TetherStatsParcel>* tetherStatsVec,
463                                         const TetherController::TetherStatsList& statsList) {
464     std::map<std::string, TetherController::TetherStats> statsMap;
465     for (const auto& stats : statsList) {
466         auto iter = statsMap.find(stats.extIface);
467         if (iter != statsMap.end()) {
468             tetherAddStatsByInterface(&(iter->second), stats);
469         } else {
470             statsMap.insert(
471                     std::pair<std::string, TetherController::TetherStats>(stats.extIface, stats));
472         }
473     }
474     for (auto iter = statsMap.begin(); iter != statsMap.end(); iter++) {
475         tetherStatsVec->push_back(toTetherStatsParcel(iter->second));
476     }
477 }
478 
tetherStatsParcelVecToStringVec(std::vector<TetherStatsParcel> * tVec)479 std::vector<std::string> tetherStatsParcelVecToStringVec(std::vector<TetherStatsParcel>* tVec) {
480     std::vector<std::string> result;
481     for (const auto& t : *tVec) {
482         result.push_back(StringPrintf("%s:%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64,
483                                       t.iface.c_str(), t.rxBytes, t.rxPackets, t.txBytes,
484                                       t.txPackets));
485     }
486     return result;
487 }
488 
489 }  // namespace
490 
tetherGetStats(std::vector<TetherStatsParcel> * tetherStatsParcelVec)491 binder::Status NetdNativeService::tetherGetStats(
492         std::vector<TetherStatsParcel>* tetherStatsParcelVec) {
493     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
494     const auto& statsList = gCtls->tetherCtrl.getTetherStats();
495     if (!isOk(statsList)) {
496         return asBinderStatus(statsList);
497     }
498     setTetherStatsParcelVecByInterface(tetherStatsParcelVec, statsList.value());
499     auto statsResults = tetherStatsParcelVecToStringVec(tetherStatsParcelVec);
500     return binder::Status::ok();
501 }
502 
interfaceAddAddress(const std::string & ifName,const std::string & addrString,int prefixLength)503 binder::Status NetdNativeService::interfaceAddAddress(const std::string &ifName,
504         const std::string &addrString, int prefixLength) {
505     ENFORCE_NETWORK_STACK_PERMISSIONS();
506     const int err = InterfaceController::addAddress(
507             ifName.c_str(), addrString.c_str(), prefixLength);
508     if (err != 0) {
509         return binder::Status::fromServiceSpecificError(-err,
510                 String8::format("InterfaceController error: %s", strerror(-err)));
511     }
512     return binder::Status::ok();
513 }
514 
interfaceDelAddress(const std::string & ifName,const std::string & addrString,int prefixLength)515 binder::Status NetdNativeService::interfaceDelAddress(const std::string &ifName,
516         const std::string &addrString, int prefixLength) {
517     ENFORCE_NETWORK_STACK_PERMISSIONS();
518     const int err = InterfaceController::delAddress(
519             ifName.c_str(), addrString.c_str(), prefixLength);
520     if (err != 0) {
521         return binder::Status::fromServiceSpecificError(-err,
522                 String8::format("InterfaceController error: %s", strerror(-err)));
523     }
524     return binder::Status::ok();
525 }
526 
527 namespace {
528 
getPathComponents(int32_t ipversion,int32_t category)529 std::tuple<binder::Status, const char*, const char*> getPathComponents(int32_t ipversion,
530                                                                        int32_t category) {
531     const char* ipversionStr = nullptr;
532     switch (ipversion) {
533         case INetd::IPV4:
534             ipversionStr = "ipv4";
535             break;
536         case INetd::IPV6:
537             ipversionStr = "ipv6";
538             break;
539         default:
540             return {binder::Status::fromServiceSpecificError(EAFNOSUPPORT, "Bad IP version"),
541                     nullptr, nullptr};
542     }
543 
544     const char* whichStr = nullptr;
545     switch (category) {
546         case INetd::CONF:
547             whichStr = "conf";
548             break;
549         case INetd::NEIGH:
550             whichStr = "neigh";
551             break;
552         default:
553             return {binder::Status::fromServiceSpecificError(EINVAL, "Bad category"), nullptr,
554                     nullptr};
555     }
556 
557     return {binder::Status::ok(), ipversionStr, whichStr};
558 }
559 
560 }  // namespace
561 
getProcSysNet(int32_t ipversion,int32_t which,const std::string & ifname,const std::string & parameter,std::string * value)562 binder::Status NetdNativeService::getProcSysNet(int32_t ipversion, int32_t which,
563                                                 const std::string& ifname,
564                                                 const std::string& parameter, std::string* value) {
565     ENFORCE_NETWORK_STACK_PERMISSIONS();
566     const auto pathParts = getPathComponents(ipversion, which);
567     const auto& pathStatus = std::get<0>(pathParts);
568     if (!pathStatus.isOk()) {
569         return pathStatus;
570     }
571 
572     const int err = InterfaceController::getParameter(std::get<1>(pathParts),
573                                                       std::get<2>(pathParts), ifname.c_str(),
574                                                       parameter.c_str(), value);
575     return statusFromErrcode(err);
576 }
577 
setProcSysNet(int32_t ipversion,int32_t which,const std::string & ifname,const std::string & parameter,const std::string & value)578 binder::Status NetdNativeService::setProcSysNet(int32_t ipversion, int32_t which,
579                                                 const std::string& ifname,
580                                                 const std::string& parameter,
581                                                 const std::string& value) {
582     ENFORCE_NETWORK_STACK_PERMISSIONS();
583     const auto pathParts = getPathComponents(ipversion, which);
584     const auto& pathStatus = std::get<0>(pathParts);
585     if (!pathStatus.isOk()) {
586         return pathStatus;
587     }
588 
589     const int err = InterfaceController::setParameter(std::get<1>(pathParts),
590                                                       std::get<2>(pathParts), ifname.c_str(),
591                                                       parameter.c_str(), value.c_str());
592     return statusFromErrcode(err);
593 }
594 
ipSecSetEncapSocketOwner(const ParcelFileDescriptor & socket,int newUid)595 binder::Status NetdNativeService::ipSecSetEncapSocketOwner(const ParcelFileDescriptor& socket,
596                                                            int newUid) {
597     ENFORCE_NETWORK_STACK_PERMISSIONS();
598 
599     uid_t callerUid = IPCThreadState::self()->getCallingUid();
600     return asBinderStatus(
601             gCtls->xfrmCtrl.ipSecSetEncapSocketOwner(socket.get(), newUid, callerUid));
602 }
603 
ipSecAllocateSpi(int32_t transformId,const std::string & sourceAddress,const std::string & destinationAddress,int32_t inSpi,int32_t * outSpi)604 binder::Status NetdNativeService::ipSecAllocateSpi(
605         int32_t transformId,
606         const std::string& sourceAddress,
607         const std::string& destinationAddress,
608         int32_t inSpi,
609         int32_t* outSpi) {
610     // Necessary locking done in IpSecService and kernel
611     ENFORCE_NETWORK_STACK_PERMISSIONS();
612     return asBinderStatus(gCtls->xfrmCtrl.ipSecAllocateSpi(
613                     transformId,
614                     sourceAddress,
615                     destinationAddress,
616                     inSpi,
617                     outSpi));
618 }
619 
ipSecAddSecurityAssociation(int32_t transformId,int32_t mode,const std::string & sourceAddress,const std::string & destinationAddress,int32_t underlyingNetId,int32_t spi,int32_t markValue,int32_t markMask,const std::string & authAlgo,const std::vector<uint8_t> & authKey,int32_t authTruncBits,const std::string & cryptAlgo,const std::vector<uint8_t> & cryptKey,int32_t cryptTruncBits,const std::string & aeadAlgo,const std::vector<uint8_t> & aeadKey,int32_t aeadIcvBits,int32_t encapType,int32_t encapLocalPort,int32_t encapRemotePort,int32_t interfaceId)620 binder::Status NetdNativeService::ipSecAddSecurityAssociation(
621         int32_t transformId, int32_t mode, const std::string& sourceAddress,
622         const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
623         int32_t markValue, int32_t markMask, const std::string& authAlgo,
624         const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo,
625         const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo,
626         const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
627         int32_t encapLocalPort, int32_t encapRemotePort, int32_t interfaceId) {
628     // Necessary locking done in IpSecService and kernel
629     ENFORCE_NETWORK_STACK_PERMISSIONS();
630     return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityAssociation(
631             transformId, mode, sourceAddress, destinationAddress, underlyingNetId, spi, markValue,
632             markMask, authAlgo, authKey, authTruncBits, cryptAlgo, cryptKey, cryptTruncBits,
633             aeadAlgo, aeadKey, aeadIcvBits, encapType, encapLocalPort, encapRemotePort,
634             interfaceId));
635 }
636 
ipSecDeleteSecurityAssociation(int32_t transformId,const std::string & sourceAddress,const std::string & destinationAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t interfaceId)637 binder::Status NetdNativeService::ipSecDeleteSecurityAssociation(
638         int32_t transformId, const std::string& sourceAddress,
639         const std::string& destinationAddress, int32_t spi, int32_t markValue, int32_t markMask,
640         int32_t interfaceId) {
641     // Necessary locking done in IpSecService and kernel
642     ENFORCE_NETWORK_STACK_PERMISSIONS();
643     return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityAssociation(
644             transformId, sourceAddress, destinationAddress, spi, markValue, markMask, interfaceId));
645 }
646 
ipSecApplyTransportModeTransform(const ParcelFileDescriptor & socket,int32_t transformId,int32_t direction,const std::string & sourceAddress,const std::string & destinationAddress,int32_t spi)647 binder::Status NetdNativeService::ipSecApplyTransportModeTransform(
648         const ParcelFileDescriptor& socket, int32_t transformId, int32_t direction,
649         const std::string& sourceAddress, const std::string& destinationAddress, int32_t spi) {
650     // Necessary locking done in IpSecService and kernel
651     ENFORCE_NETWORK_STACK_PERMISSIONS();
652     return asBinderStatus(gCtls->xfrmCtrl.ipSecApplyTransportModeTransform(
653             socket.get(), transformId, direction, sourceAddress, destinationAddress, spi));
654 }
655 
ipSecRemoveTransportModeTransform(const ParcelFileDescriptor & socket)656 binder::Status NetdNativeService::ipSecRemoveTransportModeTransform(
657         const ParcelFileDescriptor& socket) {
658     // Necessary locking done in IpSecService and kernel
659     ENFORCE_NETWORK_STACK_PERMISSIONS();
660     return asBinderStatus(gCtls->xfrmCtrl.ipSecRemoveTransportModeTransform(socket.get()));
661 }
662 
ipSecAddSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,const std::string & tmplSrcAddress,const std::string & tmplDstAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t interfaceId)663 binder::Status NetdNativeService::ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
664                                                          int32_t direction,
665                                                          const std::string& tmplSrcAddress,
666                                                          const std::string& tmplDstAddress,
667                                                          int32_t spi, int32_t markValue,
668                                                          int32_t markMask, int32_t interfaceId) {
669     // Necessary locking done in IpSecService and kernel
670     ENFORCE_NETWORK_STACK_PERMISSIONS();
671     return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityPolicy(
672             transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
673             markMask, interfaceId));
674 }
675 
ipSecUpdateSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,const std::string & tmplSrcAddress,const std::string & tmplDstAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t interfaceId)676 binder::Status NetdNativeService::ipSecUpdateSecurityPolicy(
677         int32_t transformId, int32_t selAddrFamily, int32_t direction,
678         const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
679         int32_t markValue, int32_t markMask, int32_t interfaceId) {
680     // Necessary locking done in IpSecService and kernel
681     ENFORCE_NETWORK_STACK_PERMISSIONS();
682     return asBinderStatus(gCtls->xfrmCtrl.ipSecUpdateSecurityPolicy(
683             transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
684             markMask, interfaceId));
685 }
686 
ipSecDeleteSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,int32_t markValue,int32_t markMask,int32_t interfaceId)687 binder::Status NetdNativeService::ipSecDeleteSecurityPolicy(int32_t transformId,
688                                                             int32_t selAddrFamily,
689                                                             int32_t direction, int32_t markValue,
690                                                             int32_t markMask, int32_t interfaceId) {
691     // Necessary locking done in IpSecService and kernel
692     ENFORCE_NETWORK_STACK_PERMISSIONS();
693     return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityPolicy(
694             transformId, selAddrFamily, direction, markValue, markMask, interfaceId));
695 }
696 
ipSecAddTunnelInterface(const std::string & deviceName,const std::string & localAddress,const std::string & remoteAddress,int32_t iKey,int32_t oKey,int32_t interfaceId)697 binder::Status NetdNativeService::ipSecAddTunnelInterface(const std::string& deviceName,
698                                                           const std::string& localAddress,
699                                                           const std::string& remoteAddress,
700                                                           int32_t iKey, int32_t oKey,
701                                                           int32_t interfaceId) {
702     // Necessary locking done in IpSecService and kernel
703     ENFORCE_NETWORK_STACK_PERMISSIONS();
704     netdutils::Status result = gCtls->xfrmCtrl.ipSecAddTunnelInterface(
705             deviceName, localAddress, remoteAddress, iKey, oKey, interfaceId, false);
706     return binder::Status::ok();
707 }
708 
ipSecUpdateTunnelInterface(const std::string & deviceName,const std::string & localAddress,const std::string & remoteAddress,int32_t iKey,int32_t oKey,int32_t interfaceId)709 binder::Status NetdNativeService::ipSecUpdateTunnelInterface(const std::string& deviceName,
710                                                              const std::string& localAddress,
711                                                              const std::string& remoteAddress,
712                                                              int32_t iKey, int32_t oKey,
713                                                              int32_t interfaceId) {
714     // Necessary locking done in IpSecService and kernel
715     ENFORCE_NETWORK_STACK_PERMISSIONS();
716     netdutils::Status result = gCtls->xfrmCtrl.ipSecAddTunnelInterface(
717             deviceName, localAddress, remoteAddress, iKey, oKey, interfaceId, true);
718     return binder::Status::ok();
719 }
720 
ipSecRemoveTunnelInterface(const std::string & deviceName)721 binder::Status NetdNativeService::ipSecRemoveTunnelInterface(const std::string& deviceName) {
722     // Necessary locking done in IpSecService and kernel
723     ENFORCE_NETWORK_STACK_PERMISSIONS();
724     netdutils::Status result = gCtls->xfrmCtrl.ipSecRemoveTunnelInterface(deviceName);
725     return binder::Status::ok();
726 }
727 
setIPv6AddrGenMode(const std::string & ifName,int32_t mode)728 binder::Status NetdNativeService::setIPv6AddrGenMode(const std::string& ifName,
729                                                      int32_t mode) {
730     ENFORCE_NETWORK_STACK_PERMISSIONS();
731     return asBinderStatus(InterfaceController::setIPv6AddrGenMode(ifName, mode));
732 }
733 
wakeupAddInterface(const std::string & ifName,const std::string & prefix,int32_t mark,int32_t mask)734 binder::Status NetdNativeService::wakeupAddInterface(const std::string& ifName,
735                                                      const std::string& prefix, int32_t mark,
736                                                      int32_t mask) {
737     ENFORCE_NETWORK_STACK_PERMISSIONS();
738     return asBinderStatus(gCtls->wakeupCtrl.addInterface(ifName, prefix, mark, mask));
739 }
740 
wakeupDelInterface(const std::string & ifName,const std::string & prefix,int32_t mark,int32_t mask)741 binder::Status NetdNativeService::wakeupDelInterface(const std::string& ifName,
742                                                      const std::string& prefix, int32_t mark,
743                                                      int32_t mask) {
744     ENFORCE_NETWORK_STACK_PERMISSIONS();
745     return asBinderStatus(gCtls->wakeupCtrl.delInterface(ifName, prefix, mark, mask));
746 }
747 
trafficSwapActiveStatsMap()748 binder::Status NetdNativeService::trafficSwapActiveStatsMap() {
749     ENFORCE_NETWORK_STACK_PERMISSIONS();
750     return asBinderStatus(gCtls->trafficCtrl.swapActiveStatsMap());
751 }
752 
idletimerAddInterface(const std::string & ifName,int32_t timeout,const std::string & classLabel)753 binder::Status NetdNativeService::idletimerAddInterface(const std::string& ifName, int32_t timeout,
754                                                         const std::string& classLabel) {
755     NETD_LOCKING_RPC(gCtls->idletimerCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
756     int res =
757             gCtls->idletimerCtrl.addInterfaceIdletimer(ifName.c_str(), timeout, classLabel.c_str());
758     return statusFromErrcode(res);
759 }
760 
idletimerRemoveInterface(const std::string & ifName,int32_t timeout,const std::string & classLabel)761 binder::Status NetdNativeService::idletimerRemoveInterface(const std::string& ifName,
762                                                            int32_t timeout,
763                                                            const std::string& classLabel) {
764     NETD_LOCKING_RPC(gCtls->idletimerCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
765     int res = gCtls->idletimerCtrl.removeInterfaceIdletimer(ifName.c_str(), timeout,
766                                                             classLabel.c_str());
767     return statusFromErrcode(res);
768 }
769 
strictUidCleartextPenalty(int32_t uid,int32_t policyPenalty)770 binder::Status NetdNativeService::strictUidCleartextPenalty(int32_t uid, int32_t policyPenalty) {
771     NETD_LOCKING_RPC(gCtls->strictCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
772     StrictPenalty penalty;
773     switch (policyPenalty) {
774         case INetd::PENALTY_POLICY_REJECT:
775             penalty = REJECT;
776             break;
777         case INetd::PENALTY_POLICY_LOG:
778             penalty = LOG;
779             break;
780         case INetd::PENALTY_POLICY_ACCEPT:
781             penalty = ACCEPT;
782             break;
783         default:
784             return statusFromErrcode(-EINVAL);
785             break;
786     }
787     int res = gCtls->strictCtrl.setUidCleartextPenalty((uid_t) uid, penalty);
788     return statusFromErrcode(res);
789 }
790 
clatdStart(const std::string & ifName,const std::string & nat64Prefix,std::string * v6Addr)791 binder::Status NetdNativeService::clatdStart(const std::string& ifName,
792                                              const std::string& nat64Prefix, std::string* v6Addr) {
793     ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
794     int res = gCtls->clatdCtrl.startClatd(ifName.c_str(), nat64Prefix, v6Addr);
795     return statusFromErrcode(res);
796 }
797 
clatdStop(const std::string & ifName)798 binder::Status NetdNativeService::clatdStop(const std::string& ifName) {
799     ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
800     int res = gCtls->clatdCtrl.stopClatd(ifName.c_str());
801     return statusFromErrcode(res);
802 }
803 
ipfwdEnabled(bool * status)804 binder::Status NetdNativeService::ipfwdEnabled(bool* status) {
805     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
806     *status = (gCtls->tetherCtrl.getIpfwdRequesterList().size() > 0) ? true : false;
807     return binder::Status::ok();
808 }
809 
ipfwdGetRequesterList(std::vector<std::string> * requesterList)810 binder::Status NetdNativeService::ipfwdGetRequesterList(std::vector<std::string>* requesterList) {
811     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
812     for (const auto& requester : gCtls->tetherCtrl.getIpfwdRequesterList()) {
813         requesterList->push_back(requester);
814     }
815     return binder::Status::ok();
816 }
817 
ipfwdEnableForwarding(const std::string & requester)818 binder::Status NetdNativeService::ipfwdEnableForwarding(const std::string& requester) {
819     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
820     int res = (gCtls->tetherCtrl.enableForwarding(requester.c_str())) ? 0 : -EREMOTEIO;
821     return statusFromErrcode(res);
822 }
823 
ipfwdDisableForwarding(const std::string & requester)824 binder::Status NetdNativeService::ipfwdDisableForwarding(const std::string& requester) {
825     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
826     int res = (gCtls->tetherCtrl.disableForwarding(requester.c_str())) ? 0 : -EREMOTEIO;
827     return statusFromErrcode(res);
828 }
829 
ipfwdAddInterfaceForward(const std::string & fromIface,const std::string & toIface)830 binder::Status NetdNativeService::ipfwdAddInterfaceForward(const std::string& fromIface,
831                                                            const std::string& toIface) {
832     ENFORCE_NETWORK_STACK_PERMISSIONS();
833     int res = RouteController::enableTethering(fromIface.c_str(), toIface.c_str());
834     return statusFromErrcode(res);
835 }
836 
ipfwdRemoveInterfaceForward(const std::string & fromIface,const std::string & toIface)837 binder::Status NetdNativeService::ipfwdRemoveInterfaceForward(const std::string& fromIface,
838                                                               const std::string& toIface) {
839     ENFORCE_NETWORK_STACK_PERMISSIONS();
840     int res = RouteController::disableTethering(fromIface.c_str(), toIface.c_str());
841     return statusFromErrcode(res);
842 }
843 
844 namespace {
845 
addCurlyBrackets(const std::string & s)846 std::string addCurlyBrackets(const std::string& s) {
847     return "{" + s + "}";
848 }
849 
850 }  // namespace
851 
interfaceGetList(std::vector<std::string> * interfaceListResult)852 binder::Status NetdNativeService::interfaceGetList(std::vector<std::string>* interfaceListResult) {
853     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
854     const auto& ifaceList = InterfaceController::getIfaceNames();
855 
856     interfaceListResult->clear();
857     interfaceListResult->reserve(ifaceList.value().size());
858     interfaceListResult->insert(end(*interfaceListResult), begin(ifaceList.value()),
859                                 end(ifaceList.value()));
860 
861     return binder::Status::ok();
862 }
863 
interfaceConfigurationParcelToString(const InterfaceConfigurationParcel & cfg)864 std::string interfaceConfigurationParcelToString(const InterfaceConfigurationParcel& cfg) {
865     std::vector<std::string> result{cfg.ifName, cfg.hwAddr, cfg.ipv4Addr,
866                                     std::to_string(cfg.prefixLength)};
867     result.insert(end(result), begin(cfg.flags), end(cfg.flags));
868     return addCurlyBrackets(base::Join(result, ", "));
869 }
870 
interfaceGetCfg(const std::string & ifName,InterfaceConfigurationParcel * interfaceGetCfgResult)871 binder::Status NetdNativeService::interfaceGetCfg(
872         const std::string& ifName, InterfaceConfigurationParcel* interfaceGetCfgResult) {
873     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
874     auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
875 
876     const auto& cfgRes = InterfaceController::getCfg(ifName);
877     RETURN_BINDER_STATUS_IF_NOT_OK(entry, cfgRes);
878 
879     *interfaceGetCfgResult = cfgRes.value();
880     gLog.log(entry.returns(interfaceConfigurationParcelToString(*interfaceGetCfgResult))
881                      .withAutomaticDuration());
882     return binder::Status::ok();
883 }
884 
interfaceSetCfg(const InterfaceConfigurationParcel & cfg)885 binder::Status NetdNativeService::interfaceSetCfg(const InterfaceConfigurationParcel& cfg) {
886     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
887     auto entry = gLog.newEntry()
888                          .prettyFunction(__PRETTY_FUNCTION__)
889                          .arg(interfaceConfigurationParcelToString(cfg));
890 
891     const auto& res = InterfaceController::setCfg(cfg);
892     RETURN_BINDER_STATUS_IF_NOT_OK(entry, res);
893 
894     gLog.log(entry.withAutomaticDuration());
895     return binder::Status::ok();
896 }
897 
interfaceSetIPv6PrivacyExtensions(const std::string & ifName,bool enable)898 binder::Status NetdNativeService::interfaceSetIPv6PrivacyExtensions(const std::string& ifName,
899                                                                     bool enable) {
900     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
901     int res = InterfaceController::setIPv6PrivacyExtensions(ifName.c_str(), enable);
902     return statusFromErrcode(res);
903 }
904 
interfaceClearAddrs(const std::string & ifName)905 binder::Status NetdNativeService::interfaceClearAddrs(const std::string& ifName) {
906     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
907     int res = InterfaceController::clearAddrs(ifName.c_str());
908     return statusFromErrcode(res);
909 }
910 
interfaceSetEnableIPv6(const std::string & ifName,bool enable)911 binder::Status NetdNativeService::interfaceSetEnableIPv6(const std::string& ifName, bool enable) {
912     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
913     int res = InterfaceController::setEnableIPv6(ifName.c_str(), enable);
914     return statusFromErrcode(res);
915 }
916 
interfaceSetMtu(const std::string & ifName,int32_t mtuValue)917 binder::Status NetdNativeService::interfaceSetMtu(const std::string& ifName, int32_t mtuValue) {
918     NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
919     std::string mtu = std::to_string(mtuValue);
920     int res = InterfaceController::setMtu(ifName.c_str(), mtu.c_str());
921     return statusFromErrcode(res);
922 }
923 
tetherStart(const std::vector<std::string> & dhcpRanges)924 binder::Status NetdNativeService::tetherStart(const std::vector<std::string>& dhcpRanges) {
925     TetherConfigParcel config;
926     config.usingLegacyDnsProxy = true;
927     config.dhcpRanges = dhcpRanges;
928     return tetherStartWithConfiguration(config);
929 }
930 
tetherStartWithConfiguration(const TetherConfigParcel & config)931 binder::Status NetdNativeService::tetherStartWithConfiguration(const TetherConfigParcel& config) {
932     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
933     if (config.dhcpRanges.size() % 2 == 1) {
934         return statusFromErrcode(-EINVAL);
935     }
936     // TODO: Pass TetherConfigParcel directly.
937     int res = gCtls->tetherCtrl.startTethering(config.usingLegacyDnsProxy, config.dhcpRanges);
938     return statusFromErrcode(res);
939 }
940 
tetherStop()941 binder::Status NetdNativeService::tetherStop() {
942     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
943     int res = gCtls->tetherCtrl.stopTethering();
944     return statusFromErrcode(res);
945 }
946 
tetherIsEnabled(bool * enabled)947 binder::Status NetdNativeService::tetherIsEnabled(bool* enabled) {
948     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
949     *enabled = gCtls->tetherCtrl.isTetheringStarted();
950     return binder::Status::ok();
951 }
952 
tetherInterfaceAdd(const std::string & ifName)953 binder::Status NetdNativeService::tetherInterfaceAdd(const std::string& ifName) {
954     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
955     int res = gCtls->tetherCtrl.tetherInterface(ifName.c_str());
956     return statusFromErrcode(res);
957 }
958 
tetherInterfaceRemove(const std::string & ifName)959 binder::Status NetdNativeService::tetherInterfaceRemove(const std::string& ifName) {
960     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
961     int res = gCtls->tetherCtrl.untetherInterface(ifName.c_str());
962     return statusFromErrcode(res);
963 }
964 
tetherInterfaceList(std::vector<std::string> * ifList)965 binder::Status NetdNativeService::tetherInterfaceList(std::vector<std::string>* ifList) {
966     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
967     for (const auto& ifname : gCtls->tetherCtrl.getTetheredInterfaceList()) {
968         ifList->push_back(ifname);
969     }
970     return binder::Status::ok();
971 }
972 
tetherDnsSet(int32_t netId,const std::vector<std::string> & dnsAddrs)973 binder::Status NetdNativeService::tetherDnsSet(int32_t netId,
974                                                const std::vector<std::string>& dnsAddrs) {
975     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
976     int res = gCtls->tetherCtrl.setDnsForwarders(netId, dnsAddrs);
977     return statusFromErrcode(res);
978 }
979 
tetherDnsList(std::vector<std::string> * dnsList)980 binder::Status NetdNativeService::tetherDnsList(std::vector<std::string>* dnsList) {
981     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
982     for (const auto& fwdr : gCtls->tetherCtrl.getDnsForwarders()) {
983         dnsList->push_back(fwdr);
984     }
985     return binder::Status::ok();
986 }
987 
networkAddRouteParcel(int32_t netId,const RouteInfoParcel & route)988 binder::Status NetdNativeService::networkAddRouteParcel(int32_t netId,
989                                                         const RouteInfoParcel& route) {
990     // Public methods of NetworkController are thread-safe.
991     ENFORCE_NETWORK_STACK_PERMISSIONS();
992     bool legacy = false;
993     uid_t uid = 0;  // UID is only meaningful for legacy routes.
994 
995     // convert Parcel to parameters
996     int res = gCtls->netCtrl.addRoute(netId, route.ifName.c_str(), route.destination.c_str(),
997                                       route.nextHop.empty() ? nullptr : route.nextHop.c_str(),
998                                       legacy, uid, route.mtu);
999     return statusFromErrcode(res);
1000 }
1001 
networkUpdateRouteParcel(int32_t netId,const RouteInfoParcel & route)1002 binder::Status NetdNativeService::networkUpdateRouteParcel(int32_t netId,
1003                                                            const RouteInfoParcel& route) {
1004     // Public methods of NetworkController are thread-safe.
1005     ENFORCE_NETWORK_STACK_PERMISSIONS();
1006     bool legacy = false;
1007     uid_t uid = 0;  // UID is only meaningful for legacy routes.
1008 
1009     // convert Parcel to parameters
1010     int res = gCtls->netCtrl.updateRoute(netId, route.ifName.c_str(), route.destination.c_str(),
1011                                          route.nextHop.empty() ? nullptr : route.nextHop.c_str(),
1012                                          legacy, uid, route.mtu);
1013     return statusFromErrcode(res);
1014 }
1015 
networkRemoveRouteParcel(int32_t netId,const RouteInfoParcel & route)1016 binder::Status NetdNativeService::networkRemoveRouteParcel(int32_t netId,
1017                                                            const RouteInfoParcel& route) {
1018     return networkRemoveRoute(netId, route.ifName, route.destination, route.nextHop);
1019 }
1020 
networkAddRoute(int32_t netId,const std::string & ifName,const std::string & destination,const std::string & nextHop)1021 binder::Status NetdNativeService::networkAddRoute(int32_t netId, const std::string& ifName,
1022                                                   const std::string& destination,
1023                                                   const std::string& nextHop) {
1024     // Public methods of NetworkController are thread-safe.
1025     ENFORCE_NETWORK_STACK_PERMISSIONS();
1026     bool legacy = false;
1027     uid_t uid = 0;  // UID is only meaningful for legacy routes.
1028     int res = gCtls->netCtrl.addRoute(netId, ifName.c_str(), destination.c_str(),
1029                                       nextHop.empty() ? nullptr : nextHop.c_str(), legacy, uid, 0);
1030     return statusFromErrcode(res);
1031 }
1032 
networkRemoveRoute(int32_t netId,const std::string & ifName,const std::string & destination,const std::string & nextHop)1033 binder::Status NetdNativeService::networkRemoveRoute(int32_t netId, const std::string& ifName,
1034                                                      const std::string& destination,
1035                                                      const std::string& nextHop) {
1036     ENFORCE_NETWORK_STACK_PERMISSIONS();
1037     bool legacy = false;
1038     uid_t uid = 0;  // UID is only meaningful for legacy routes.
1039     int res = gCtls->netCtrl.removeRoute(netId, ifName.c_str(), destination.c_str(),
1040                                          nextHop.empty() ? nullptr : nextHop.c_str(), legacy, uid);
1041     return statusFromErrcode(res);
1042 }
1043 
networkAddLegacyRoute(int32_t netId,const std::string & ifName,const std::string & destination,const std::string & nextHop,int32_t uid)1044 binder::Status NetdNativeService::networkAddLegacyRoute(int32_t netId, const std::string& ifName,
1045                                                         const std::string& destination,
1046                                                         const std::string& nextHop, int32_t uid) {
1047     ENFORCE_NETWORK_STACK_PERMISSIONS();
1048     bool legacy = true;
1049     int res = gCtls->netCtrl.addRoute(netId, ifName.c_str(), destination.c_str(),
1050                                       nextHop.empty() ? nullptr : nextHop.c_str(), legacy,
1051                                       (uid_t)uid, 0);
1052     return statusFromErrcode(res);
1053 }
1054 
networkRemoveLegacyRoute(int32_t netId,const std::string & ifName,const std::string & destination,const std::string & nextHop,int32_t uid)1055 binder::Status NetdNativeService::networkRemoveLegacyRoute(int32_t netId, const std::string& ifName,
1056                                                            const std::string& destination,
1057                                                            const std::string& nextHop,
1058                                                            int32_t uid) {
1059     ENFORCE_NETWORK_STACK_PERMISSIONS();
1060     bool legacy = true;
1061     int res = gCtls->netCtrl.removeRoute(netId, ifName.c_str(), destination.c_str(),
1062                                          nextHop.empty() ? nullptr : nextHop.c_str(), legacy,
1063                                          (uid_t) uid);
1064     return statusFromErrcode(res);
1065 }
1066 
networkGetDefault(int32_t * netId)1067 binder::Status NetdNativeService::networkGetDefault(int32_t* netId) {
1068     ENFORCE_NETWORK_STACK_PERMISSIONS();
1069     *netId = gCtls->netCtrl.getDefaultNetwork();
1070     return binder::Status::ok();
1071 }
1072 
networkSetDefault(int32_t netId)1073 binder::Status NetdNativeService::networkSetDefault(int32_t netId) {
1074     ENFORCE_NETWORK_STACK_PERMISSIONS();
1075     int res = gCtls->netCtrl.setDefaultNetwork(netId);
1076     return statusFromErrcode(res);
1077 }
1078 
networkClearDefault()1079 binder::Status NetdNativeService::networkClearDefault() {
1080     ENFORCE_NETWORK_STACK_PERMISSIONS();
1081     unsigned netId = NETID_UNSET;
1082     int res = gCtls->netCtrl.setDefaultNetwork(netId);
1083     return statusFromErrcode(res);
1084 }
1085 
intsToUids(const std::vector<int32_t> & intUids)1086 std::vector<uid_t> NetdNativeService::intsToUids(const std::vector<int32_t>& intUids) {
1087     return {begin(intUids), end(intUids)};
1088 }
1089 
convertPermission(int32_t permission)1090 Permission NetdNativeService::convertPermission(int32_t permission) {
1091     switch (permission) {
1092         case INetd::PERMISSION_NETWORK:
1093             return Permission::PERMISSION_NETWORK;
1094         case INetd::PERMISSION_SYSTEM:
1095             return Permission::PERMISSION_SYSTEM;
1096         default:
1097             return Permission::PERMISSION_NONE;
1098     }
1099 }
1100 
networkSetPermissionForNetwork(int32_t netId,int32_t permission)1101 binder::Status NetdNativeService::networkSetPermissionForNetwork(int32_t netId,
1102                                                                  int32_t permission) {
1103     ENFORCE_NETWORK_STACK_PERMISSIONS();
1104     std::vector<unsigned> netIds = {(unsigned) netId};
1105     int res = gCtls->netCtrl.setPermissionForNetworks(convertPermission(permission), netIds);
1106     return statusFromErrcode(res);
1107 }
1108 
networkSetPermissionForUser(int32_t permission,const std::vector<int32_t> & uids)1109 binder::Status NetdNativeService::networkSetPermissionForUser(int32_t permission,
1110                                                               const std::vector<int32_t>& uids) {
1111     ENFORCE_NETWORK_STACK_PERMISSIONS();
1112     gCtls->netCtrl.setPermissionForUsers(convertPermission(permission), intsToUids(uids));
1113     return binder::Status::ok();
1114 }
1115 
networkClearPermissionForUser(const std::vector<int32_t> & uids)1116 binder::Status NetdNativeService::networkClearPermissionForUser(const std::vector<int32_t>& uids) {
1117     ENFORCE_NETWORK_STACK_PERMISSIONS();
1118     Permission permission = Permission::PERMISSION_NONE;
1119     gCtls->netCtrl.setPermissionForUsers(permission, intsToUids(uids));
1120     return binder::Status::ok();
1121 }
1122 
networkSetProtectAllow(int32_t uid)1123 binder::Status NetdNativeService::NetdNativeService::networkSetProtectAllow(int32_t uid) {
1124     ENFORCE_NETWORK_STACK_PERMISSIONS();
1125     std::vector<uid_t> uids = {(uid_t) uid};
1126     gCtls->netCtrl.allowProtect(uids);
1127     return binder::Status::ok();
1128 }
1129 
networkSetProtectDeny(int32_t uid)1130 binder::Status NetdNativeService::networkSetProtectDeny(int32_t uid) {
1131     ENFORCE_NETWORK_STACK_PERMISSIONS();
1132     std::vector<uid_t> uids = {(uid_t) uid};
1133     gCtls->netCtrl.denyProtect(uids);
1134     return binder::Status::ok();
1135 }
1136 
networkCanProtect(int32_t uid,bool * ret)1137 binder::Status NetdNativeService::networkCanProtect(int32_t uid, bool* ret) {
1138     ENFORCE_NETWORK_STACK_PERMISSIONS();
1139     *ret = gCtls->netCtrl.canProtect((uid_t) uid);
1140     return binder::Status::ok();
1141 }
1142 
trafficSetNetPermForUids(int32_t permission,const std::vector<int32_t> & uids)1143 binder::Status NetdNativeService::trafficSetNetPermForUids(int32_t permission,
1144                                                            const std::vector<int32_t>& uids) {
1145     ENFORCE_NETWORK_STACK_PERMISSIONS();
1146     gCtls->trafficCtrl.setPermissionForUids(permission, intsToUids(uids));
1147     return binder::Status::ok();
1148 }
1149 
firewallSetFirewallType(int32_t firewallType)1150 binder::Status NetdNativeService::firewallSetFirewallType(int32_t firewallType) {
1151     NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1152     auto type = static_cast<FirewallType>(firewallType);
1153 
1154     int res = gCtls->firewallCtrl.setFirewallType(type);
1155     return statusFromErrcode(res);
1156 }
1157 
firewallSetInterfaceRule(const std::string & ifName,int32_t firewallRule)1158 binder::Status NetdNativeService::firewallSetInterfaceRule(const std::string& ifName,
1159                                                            int32_t firewallRule) {
1160     NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1161     auto rule = static_cast<FirewallRule>(firewallRule);
1162 
1163     int res = gCtls->firewallCtrl.setInterfaceRule(ifName.c_str(), rule);
1164     return statusFromErrcode(res);
1165 }
1166 
firewallSetUidRule(int32_t childChain,int32_t uid,int32_t firewallRule)1167 binder::Status NetdNativeService::firewallSetUidRule(int32_t childChain, int32_t uid,
1168                                                      int32_t firewallRule) {
1169     NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1170     auto chain = static_cast<ChildChain>(childChain);
1171     auto rule = static_cast<FirewallRule>(firewallRule);
1172 
1173     int res = gCtls->firewallCtrl.setUidRule(chain, uid, rule);
1174     return statusFromErrcode(res);
1175 }
1176 
firewallEnableChildChain(int32_t childChain,bool enable)1177 binder::Status NetdNativeService::firewallEnableChildChain(int32_t childChain, bool enable) {
1178     NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1179     auto chain = static_cast<ChildChain>(childChain);
1180 
1181     int res = gCtls->firewallCtrl.enableChildChains(chain, enable);
1182     return statusFromErrcode(res);
1183 }
1184 
firewallAddUidInterfaceRules(const std::string & ifName,const std::vector<int32_t> & uids)1185 binder::Status NetdNativeService::firewallAddUidInterfaceRules(const std::string& ifName,
1186                                                                const std::vector<int32_t>& uids) {
1187     ENFORCE_NETWORK_STACK_PERMISSIONS();
1188 
1189     return asBinderStatus(gCtls->trafficCtrl.addUidInterfaceRules(
1190             RouteController::getIfIndex(ifName.c_str()), uids));
1191 }
1192 
firewallRemoveUidInterfaceRules(const std::vector<int32_t> & uids)1193 binder::Status NetdNativeService::firewallRemoveUidInterfaceRules(
1194         const std::vector<int32_t>& uids) {
1195     ENFORCE_NETWORK_STACK_PERMISSIONS();
1196 
1197     return asBinderStatus(gCtls->trafficCtrl.removeUidInterfaceRules(uids));
1198 }
1199 
tetherAddForward(const std::string & intIface,const std::string & extIface)1200 binder::Status NetdNativeService::tetherAddForward(const std::string& intIface,
1201                                                    const std::string& extIface) {
1202     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1203 
1204     int res = gCtls->tetherCtrl.enableNat(intIface.c_str(), extIface.c_str());
1205     return statusFromErrcode(res);
1206 }
1207 
tetherRemoveForward(const std::string & intIface,const std::string & extIface)1208 binder::Status NetdNativeService::tetherRemoveForward(const std::string& intIface,
1209                                                       const std::string& extIface) {
1210     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1211     int res = gCtls->tetherCtrl.disableNat(intIface.c_str(), extIface.c_str());
1212     return statusFromErrcode(res);
1213 }
1214 
setTcpRWmemorySize(const std::string & rmemValues,const std::string & wmemValues)1215 binder::Status NetdNativeService::setTcpRWmemorySize(const std::string& rmemValues,
1216                                                      const std::string& wmemValues) {
1217     ENFORCE_NETWORK_STACK_PERMISSIONS();
1218     if (!WriteStringToFile(rmemValues, TCP_RMEM_PROC_FILE)) {
1219         int ret = -errno;
1220         return statusFromErrcode(ret);
1221     }
1222 
1223     if (!WriteStringToFile(wmemValues, TCP_WMEM_PROC_FILE)) {
1224         int ret = -errno;
1225         return statusFromErrcode(ret);
1226     }
1227     return binder::Status::ok();
1228 }
1229 
registerUnsolicitedEventListener(const android::sp<android::net::INetdUnsolicitedEventListener> & listener)1230 binder::Status NetdNativeService::registerUnsolicitedEventListener(
1231         const android::sp<android::net::INetdUnsolicitedEventListener>& listener) {
1232     ENFORCE_NETWORK_STACK_PERMISSIONS();
1233     gCtls->eventReporter.registerUnsolEventListener(listener);
1234     return binder::Status::ok();
1235 }
1236 
getOemNetd(android::sp<android::IBinder> * listener)1237 binder::Status NetdNativeService::getOemNetd(android::sp<android::IBinder>* listener) {
1238     ENFORCE_NETWORK_STACK_PERMISSIONS();
1239     *listener = com::android::internal::net::OemNetdListener::getListener();
1240 
1241     return binder::Status::ok();
1242 }
1243 
getFwmarkForNetwork(int32_t netId,MarkMaskParcel * markMask)1244 binder::Status NetdNativeService::getFwmarkForNetwork(int32_t netId, MarkMaskParcel* markMask) {
1245     ENFORCE_NETWORK_STACK_PERMISSIONS();
1246 
1247     Fwmark fwmark;
1248     fwmark.netId = netId;
1249     markMask->mask = FWMARK_NET_ID_MASK;
1250     markMask->mark = fwmark.intValue;
1251     return binder::Status::ok();
1252 }
1253 
tetherOffloadRuleAdd(const TetherOffloadRuleParcel & rule)1254 binder::Status NetdNativeService::tetherOffloadRuleAdd(const TetherOffloadRuleParcel& rule) {
1255     ENFORCE_NETWORK_STACK_PERMISSIONS();
1256 
1257     return asBinderStatus(gCtls->tetherCtrl.addOffloadRule(rule));
1258 }
1259 
tetherOffloadRuleRemove(const TetherOffloadRuleParcel & rule)1260 binder::Status NetdNativeService::tetherOffloadRuleRemove(const TetherOffloadRuleParcel& rule) {
1261     ENFORCE_NETWORK_STACK_PERMISSIONS();
1262 
1263     return asBinderStatus(gCtls->tetherCtrl.removeOffloadRule(rule));
1264 }
1265 
1266 namespace {
1267 
1268 constexpr const char UNUSED_IFNAME[] = "";
1269 
toTetherStatsParcel(const TetherController::TetherOffloadStats & stats)1270 TetherStatsParcel toTetherStatsParcel(const TetherController::TetherOffloadStats& stats) {
1271     TetherStatsParcel result;
1272     result.iface = UNUSED_IFNAME;
1273     result.rxBytes = stats.rxBytes;
1274     result.rxPackets = stats.rxPackets;
1275     result.txBytes = stats.txBytes;
1276     result.txPackets = stats.txPackets;
1277     result.ifIndex = stats.ifIndex;
1278     return result;
1279 }
1280 
1281 }  // namespace
1282 
tetherOffloadGetStats(std::vector<TetherStatsParcel> * tetherStatsParcelVec)1283 binder::Status NetdNativeService::tetherOffloadGetStats(
1284         std::vector<TetherStatsParcel>* tetherStatsParcelVec) {
1285     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1286 
1287     tetherStatsParcelVec->clear();
1288     const auto& statsList = gCtls->tetherCtrl.getTetherOffloadStats();
1289     if (!isOk(statsList)) {
1290         return asBinderStatus(statsList);
1291     }
1292     for (const auto& stats : statsList.value()) {
1293         tetherStatsParcelVec->push_back(toTetherStatsParcel(stats));
1294     }
1295     return binder::Status::ok();
1296 }
1297 
tetherOffloadSetInterfaceQuota(int ifIndex,int64_t quotaBytes)1298 binder::Status NetdNativeService::tetherOffloadSetInterfaceQuota(int ifIndex, int64_t quotaBytes) {
1299     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1300     int res = gCtls->tetherCtrl.setTetherOffloadInterfaceQuota(ifIndex, quotaBytes);
1301     return statusFromErrcode(res);
1302 }
1303 
tetherOffloadGetAndClearStats(int ifIndex,android::net::TetherStatsParcel * tetherStats)1304 binder::Status NetdNativeService::tetherOffloadGetAndClearStats(
1305         int ifIndex, android::net::TetherStatsParcel* tetherStats) {
1306     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
1307     const auto& stats = gCtls->tetherCtrl.getAndClearTetherOffloadStats(ifIndex);
1308     if (!stats.ok()) {
1309         return asBinderStatus(stats);
1310     }
1311     *tetherStats = toTetherStatsParcel(stats.value());
1312     return binder::Status::ok();
1313 }
1314 
1315 }  // namespace net
1316 }  // namespace android
1317