blob: 579d0bddc8e2ba18c65f721b13ae4208bd4257a3 [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 Colittic6201c32016-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
Lorenzo Colitti7035f222017-02-13 18:29:00 +090025namespace android {
26namespace net {
27
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070028namespace {
29
30WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070031 Permission permission, PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070032 if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070033 ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
34 return ret;
35 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070036 if (int ret = delegate->addFallthrough(interface, permission)) {
37 return ret;
38 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070039 return 0;
40}
41
42WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070043 Permission permission,
44 PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070045 if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
46 permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070047 ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
48 return ret;
49 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070050 if (int ret = delegate->removeFallthrough(interface, permission)) {
51 return ret;
52 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070053 return 0;
54}
55
56} // namespace
57
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070058PhysicalNetwork::Delegate::~Delegate() {
59}
60
61PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
62 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070063}
64
65PhysicalNetwork::~PhysicalNetwork() {
66}
67
68Permission PhysicalNetwork::getPermission() const {
69 return mPermission;
70}
71
Lorenzo Colittic6201c32016-09-14 02:25:05 +090072int 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
Lorenzo Colitti4662e162017-09-08 11:31:59 +090089void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
90 for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
91 // If any of these operations fail, there's no point in logging because RouteController will
92 // have already logged a message. There's also no point returning an error since there's
93 // nothing we can do.
94 (void) RouteController::addRoute(interface.c_str(), dst, "throw",
95 RouteController::INTERFACE);
96 (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
97 RouteController::INTERFACE);
98 }
99}
100
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700101int PhysicalNetwork::setPermission(Permission permission) {
102 if (permission == mPermission) {
103 return 0;
104 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900105 if (mInterfaces.empty()) {
106 mPermission = permission;
107 return 0;
108 }
109
110 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700111 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700112 if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
113 mPermission, permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700114 ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
115 interface.c_str(), mNetId, mPermission, permission);
116 return ret;
117 }
Lorenzo Colitti4662e162017-09-08 11:31:59 +0900118 invalidateRouteCache(interface);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700119 }
120 if (mIsDefault) {
121 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700122 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700123 return ret;
124 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700125 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700126 return ret;
127 }
128 }
129 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900130 // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
131 // above and before we changed the permissions. These sockets won't be able to send any RST
132 // packets because they are now no longer routed, but at least the apps will get errors.
133 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700134 mPermission = permission;
135 return 0;
136}
137
138int PhysicalNetwork::addAsDefault() {
139 if (mIsDefault) {
140 return 0;
141 }
142 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700143 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700144 return ret;
145 }
146 }
147 mIsDefault = true;
148 return 0;
149}
150
151int PhysicalNetwork::removeAsDefault() {
152 if (!mIsDefault) {
153 return 0;
154 }
155 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700156 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700157 return ret;
158 }
159 }
160 mIsDefault = false;
161 return 0;
162}
163
Sreeram Ramachandran36ed53e2014-07-01 19:01:56 -0700164Network::Type PhysicalNetwork::getType() const {
165 return PHYSICAL;
166}
167
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700168int PhysicalNetwork::addInterface(const std::string& interface) {
169 if (hasInterface(interface)) {
170 return 0;
171 }
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700172 if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
173 mPermission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700174 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
175 return ret;
176 }
177 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700178 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700179 return ret;
180 }
181 }
182 mInterfaces.insert(interface);
183 return 0;
184}
185
186int PhysicalNetwork::removeInterface(const std::string& interface) {
187 if (!hasInterface(interface)) {
188 return 0;
189 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700190 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700191 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700192 return ret;
193 }
194 }
Paul Jensen6d7e6232014-08-01 10:54:03 -0400195 // This step will flush the interface index from the cache in RouteController so it must be
196 // done last as further requests to the RouteController regarding this interface will fail
197 // to find the interface index in the cache in cases where the interface is already gone
198 // (e.g. bt-pan).
199 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
200 mPermission)) {
201 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
202 return ret;
203 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700204 mInterfaces.erase(interface);
205 return 0;
206}
Lorenzo Colitti7035f222017-02-13 18:29:00 +0900207
208} // namespace net
209} // namespace android