1 /*
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
17 #include "PhysicalNetwork.h"
18
19 #include "RouteController.h"
20 #include "SockDiag.h"
21
22 #define LOG_TAG "Netd"
23 #include "log/log.h"
24
25 namespace android {
26 namespace net {
27
28 namespace {
29
addToDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)30 WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
31 Permission permission, PhysicalNetwork::Delegate* delegate) {
32 if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
33 ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
34 return ret;
35 }
36 if (int ret = delegate->addFallthrough(interface, permission)) {
37 return ret;
38 }
39 return 0;
40 }
41
removeFromDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)42 WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
43 Permission permission,
44 PhysicalNetwork::Delegate* delegate) {
45 if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
46 permission)) {
47 ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
48 return ret;
49 }
50 if (int ret = delegate->removeFallthrough(interface, permission)) {
51 return ret;
52 }
53 return 0;
54 }
55
56 } // namespace
57
~Delegate()58 PhysicalNetwork::Delegate::~Delegate() {
59 }
60
PhysicalNetwork(unsigned netId,PhysicalNetwork::Delegate * delegate)61 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
62 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
63 }
64
~PhysicalNetwork()65 PhysicalNetwork::~PhysicalNetwork() {
66 }
67
getPermission() const68 Permission PhysicalNetwork::getPermission() const {
69 return mPermission;
70 }
71
destroySocketsLackingPermission(Permission permission)72 int PhysicalNetwork::destroySocketsLackingPermission(Permission permission) {
73 if (permission == PERMISSION_NONE) return 0;
74
75 SockDiag sd;
76 if (!sd.open()) {
77 ALOGE("Error closing sockets for netId %d permission change", mNetId);
78 return -EBADFD;
79 }
80 if (int ret = sd.destroySocketsLackingPermission(mNetId, permission,
81 true /* excludeLoopback */)) {
82 ALOGE("Failed to close sockets changing netId %d to permission %d: %s",
83 mNetId, permission, strerror(-ret));
84 return ret;
85 }
86 return 0;
87 }
88
setPermission(Permission permission)89 int PhysicalNetwork::setPermission(Permission permission) {
90 if (permission == mPermission) {
91 return 0;
92 }
93 if (mInterfaces.empty()) {
94 mPermission = permission;
95 return 0;
96 }
97
98 destroySocketsLackingPermission(permission);
99 for (const std::string& interface : mInterfaces) {
100 if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
101 mPermission, permission)) {
102 ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
103 interface.c_str(), mNetId, mPermission, permission);
104 return ret;
105 }
106 }
107 if (mIsDefault) {
108 for (const std::string& interface : mInterfaces) {
109 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
110 return ret;
111 }
112 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
113 return ret;
114 }
115 }
116 }
117 // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
118 // above and before we changed the permissions. These sockets won't be able to send any RST
119 // packets because they are now no longer routed, but at least the apps will get errors.
120 destroySocketsLackingPermission(permission);
121 mPermission = permission;
122 return 0;
123 }
124
addAsDefault()125 int PhysicalNetwork::addAsDefault() {
126 if (mIsDefault) {
127 return 0;
128 }
129 for (const std::string& interface : mInterfaces) {
130 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
131 return ret;
132 }
133 }
134 mIsDefault = true;
135 return 0;
136 }
137
removeAsDefault()138 int PhysicalNetwork::removeAsDefault() {
139 if (!mIsDefault) {
140 return 0;
141 }
142 for (const std::string& interface : mInterfaces) {
143 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
144 return ret;
145 }
146 }
147 mIsDefault = false;
148 return 0;
149 }
150
getType() const151 Network::Type PhysicalNetwork::getType() const {
152 return PHYSICAL;
153 }
154
addInterface(const std::string & interface)155 int PhysicalNetwork::addInterface(const std::string& interface) {
156 if (hasInterface(interface)) {
157 return 0;
158 }
159 if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
160 mPermission)) {
161 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
162 return ret;
163 }
164 if (mIsDefault) {
165 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
166 return ret;
167 }
168 }
169 mInterfaces.insert(interface);
170 return 0;
171 }
172
removeInterface(const std::string & interface)173 int PhysicalNetwork::removeInterface(const std::string& interface) {
174 if (!hasInterface(interface)) {
175 return 0;
176 }
177 if (mIsDefault) {
178 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
179 return ret;
180 }
181 }
182 // This step will flush the interface index from the cache in RouteController so it must be
183 // done last as further requests to the RouteController regarding this interface will fail
184 // to find the interface index in the cache in cases where the interface is already gone
185 // (e.g. bt-pan).
186 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
187 mPermission)) {
188 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
189 return ret;
190 }
191 mInterfaces.erase(interface);
192 return 0;
193 }
194
195 } // namespace net
196 } // namespace android
197