blob: 33791c682480b68c9cd63a86558969133e5943be [file] [log] [blame]
Sreeram Ramachandran4043f012014-06-23 12:41:37 -07001/*
2 * Copyright (C) 2014 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
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090017#include <set>
Luke Huang94658ac2018-10-18 19:35:12 +090018
19#define LOG_TAG "Netd"
20
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070021#include "VirtualNetwork.h"
22
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090023#include "SockDiag.h"
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070024#include "RouteController.h"
25
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070026#include "log/log.h"
27
Lorenzo Colitti7035f222017-02-13 18:29:00 +090028namespace android {
29namespace net {
30
cken67cd14c2018-12-05 17:26:59 +090031VirtualNetwork::VirtualNetwork(unsigned netId, bool secure) : Network(netId), mSecure(secure) {}
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070032
cken67cd14c2018-12-05 17:26:59 +090033VirtualNetwork::~VirtualNetwork() {}
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070034
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070035bool VirtualNetwork::isSecure() const {
36 return mSecure;
37}
38
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070039bool VirtualNetwork::appliesToUser(uid_t uid) const {
40 return mUidRanges.hasUid(uid);
41}
42
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090043
44int VirtualNetwork::maybeCloseSockets(bool add, const UidRanges& uidRanges,
45 const std::set<uid_t>& protectableUsers) {
46 if (!mSecure) {
47 return 0;
48 }
49
50 SockDiag sd;
51 if (!sd.open()) {
52 return -EBADFD;
53 }
54
Lorenzo Colitti0726fec2016-07-26 17:53:50 +090055 if (int ret = sd.destroySockets(uidRanges, protectableUsers, true /* excludeLoopback */)) {
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090056 ALOGE("Failed to close sockets while %s %s to network %d: %s",
57 add ? "adding" : "removing", uidRanges.toString().c_str(), mNetId, strerror(-ret));
58 return ret;
59 }
60
61 return 0;
62}
63
64int VirtualNetwork::addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers) {
65 maybeCloseSockets(true, uidRanges, protectableUsers);
66
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070067 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070068 if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070069 uidRanges)) {
70 ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
71 return ret;
72 }
73 }
74 mUidRanges.add(uidRanges);
75 return 0;
76}
77
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090078int VirtualNetwork::removeUsers(const UidRanges& uidRanges,
79 const std::set<uid_t>& protectableUsers) {
80 maybeCloseSockets(false, uidRanges, protectableUsers);
81
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070082 for (const std::string& interface : mInterfaces) {
83 if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(),
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070084 mSecure, uidRanges)) {
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070085 ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
86 return ret;
87 }
88 }
89 mUidRanges.remove(uidRanges);
90 return 0;
91}
92
93Network::Type VirtualNetwork::getType() const {
94 return VIRTUAL;
95}
96
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070097int VirtualNetwork::addInterface(const std::string& interface) {
98 if (hasInterface(interface)) {
99 return 0;
100 }
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -0700101 if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700102 mUidRanges)) {
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700103 ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
104 return ret;
105 }
106 mInterfaces.insert(interface);
107 return 0;
108}
109
110int VirtualNetwork::removeInterface(const std::string& interface) {
111 if (!hasInterface(interface)) {
112 return 0;
113 }
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700114 if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -0700115 mSecure, mUidRanges)) {
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700116 ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
117 return ret;
118 }
119 mInterfaces.erase(interface);
120 return 0;
121}
Lorenzo Colitti7035f222017-02-13 18:29:00 +0900122
123} // namespace net
124} // namespace android