blob: ee0e7c7bccc161394ed0662c2547f7e2d590ecca [file] [log] [blame]
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -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
17#include "PhysicalNetwork.h"
18
19#include "RouteController.h"
Lorenzo Colittifbe76b92016-09-14 02:25:05 +090020#include "SockDiag.h"
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070021
22#define LOG_TAG "Netd"
23#include "log/log.h"
24
25namespace {
26
27WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070028 Permission permission, PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070029 if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070030 ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
31 return ret;
32 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070033 if (int ret = delegate->addFallthrough(interface, permission)) {
34 return ret;
35 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070036 return 0;
37}
38
39WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070040 Permission permission,
41 PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070042 if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
43 permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070044 ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
45 return ret;
46 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070047 if (int ret = delegate->removeFallthrough(interface, permission)) {
48 return ret;
49 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070050 return 0;
51}
52
53} // namespace
54
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070055PhysicalNetwork::Delegate::~Delegate() {
56}
57
58PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
59 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070060}
61
62PhysicalNetwork::~PhysicalNetwork() {
63}
64
65Permission PhysicalNetwork::getPermission() const {
66 return mPermission;
67}
68
Lorenzo Colittifbe76b92016-09-14 02:25:05 +090069int PhysicalNetwork::destroySocketsLackingPermission(Permission permission) {
70 if (permission == PERMISSION_NONE) return 0;
71
72 SockDiag sd;
73 if (!sd.open()) {
74 ALOGE("Error closing sockets for netId %d permission change", mNetId);
75 return -EBADFD;
76 }
77 if (int ret = sd.destroySocketsLackingPermission(mNetId, permission,
78 true /* excludeLoopback */)) {
79 ALOGE("Failed to close sockets changing netId %d to permission %d: %s",
80 mNetId, permission, strerror(-ret));
81 return ret;
82 }
83 return 0;
84}
85
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070086int PhysicalNetwork::setPermission(Permission permission) {
87 if (permission == mPermission) {
88 return 0;
89 }
Lorenzo Colittifbe76b92016-09-14 02:25:05 +090090 if (mInterfaces.empty()) {
91 mPermission = permission;
92 return 0;
93 }
94
95 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070096 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070097 if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
98 mPermission, permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070099 ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
100 interface.c_str(), mNetId, mPermission, permission);
101 return ret;
102 }
103 }
104 if (mIsDefault) {
105 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700106 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700107 return ret;
108 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700109 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700110 return ret;
111 }
112 }
113 }
Lorenzo Colittifbe76b92016-09-14 02:25:05 +0900114 // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
115 // above and before we changed the permissions. These sockets won't be able to send any RST
116 // packets because they are now no longer routed, but at least the apps will get errors.
117 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700118 mPermission = permission;
119 return 0;
120}
121
122int PhysicalNetwork::addAsDefault() {
123 if (mIsDefault) {
124 return 0;
125 }
126 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700127 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700128 return ret;
129 }
130 }
131 mIsDefault = true;
132 return 0;
133}
134
135int PhysicalNetwork::removeAsDefault() {
136 if (!mIsDefault) {
137 return 0;
138 }
139 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700140 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700141 return ret;
142 }
143 }
144 mIsDefault = false;
145 return 0;
146}
147
Sreeram Ramachandran36ed53e2014-07-01 19:01:56 -0700148Network::Type PhysicalNetwork::getType() const {
149 return PHYSICAL;
150}
151
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700152int PhysicalNetwork::addInterface(const std::string& interface) {
153 if (hasInterface(interface)) {
154 return 0;
155 }
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700156 if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
157 mPermission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700158 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
159 return ret;
160 }
161 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700162 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700163 return ret;
164 }
165 }
166 mInterfaces.insert(interface);
167 return 0;
168}
169
170int PhysicalNetwork::removeInterface(const std::string& interface) {
171 if (!hasInterface(interface)) {
172 return 0;
173 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700174 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700175 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700176 return ret;
177 }
178 }
Paul Jensen6d7e6232014-08-01 10:54:03 -0400179 // This step will flush the interface index from the cache in RouteController so it must be
180 // done last as further requests to the RouteController regarding this interface will fail
181 // to find the interface index in the cache in cases where the interface is already gone
182 // (e.g. bt-pan).
183 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
184 mPermission)) {
185 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
186 return ret;
187 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700188 mInterfaces.erase(interface);
189 return 0;
190}