blob: 56f4ac3d5e2b2b0464d77e35edcdfbab891cb28b [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
Luke Huang94658ac2018-10-18 19:35:12 +090017#define LOG_TAG "Netd"
18
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070019#include "PhysicalNetwork.h"
20
21#include "RouteController.h"
Lorenzo Colittic6201c32016-09-14 02:25:05 +090022#include "SockDiag.h"
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070023
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070024#include "log/log.h"
25
Bernie Innocenti762dcf42019-06-14 19:52:49 +090026namespace android::net {
Lorenzo Colitti7035f222017-02-13 18:29:00 +090027
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070028namespace {
29
Bernie Innocenti762dcf42019-06-14 19:52:49 +090030[[nodiscard]] int addToDefault(unsigned netId, const std::string& interface, Permission permission,
31 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
Bernie Innocenti762dcf42019-06-14 19:52:49 +090042[[nodiscard]] int removeFromDefault(unsigned netId, const std::string& interface,
43 Permission permission, PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070044 if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
45 permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070046 ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
47 return ret;
48 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070049 if (int ret = delegate->removeFallthrough(interface, permission)) {
50 return ret;
51 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070052 return 0;
53}
54
55} // namespace
56
Bernie Innocenti762dcf42019-06-14 19:52:49 +090057PhysicalNetwork::Delegate::~Delegate() {}
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070058
59PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
60 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070061}
62
Bernie Innocenti762dcf42019-06-14 19:52:49 +090063PhysicalNetwork::~PhysicalNetwork() {}
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070064
65Permission PhysicalNetwork::getPermission() const {
66 return mPermission;
67}
68
Lorenzo Colittic6201c32016-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
Lorenzo Colitti4662e162017-09-08 11:31:59 +090086void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
87 for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
88 // If any of these operations fail, there's no point in logging because RouteController will
89 // have already logged a message. There's also no point returning an error since there's
90 // nothing we can do.
91 (void) RouteController::addRoute(interface.c_str(), dst, "throw",
92 RouteController::INTERFACE);
93 (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
94 RouteController::INTERFACE);
95 }
96}
97
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070098int PhysicalNetwork::setPermission(Permission permission) {
99 if (permission == mPermission) {
100 return 0;
101 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900102 if (mInterfaces.empty()) {
103 mPermission = permission;
104 return 0;
105 }
106
107 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700108 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700109 if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
110 mPermission, permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700111 ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
112 interface.c_str(), mNetId, mPermission, permission);
113 return ret;
114 }
Lorenzo Colitti4662e162017-09-08 11:31:59 +0900115 invalidateRouteCache(interface);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700116 }
117 if (mIsDefault) {
118 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700119 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700120 return ret;
121 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700122 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700123 return ret;
124 }
125 }
126 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900127 // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
128 // above and before we changed the permissions. These sockets won't be able to send any RST
129 // packets because they are now no longer routed, but at least the apps will get errors.
130 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700131 mPermission = permission;
132 return 0;
133}
134
135int PhysicalNetwork::addAsDefault() {
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 = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700141 return ret;
142 }
143 }
144 mIsDefault = true;
145 return 0;
146}
147
148int PhysicalNetwork::removeAsDefault() {
149 if (!mIsDefault) {
150 return 0;
151 }
152 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700153 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700154 return ret;
155 }
156 }
157 mIsDefault = false;
158 return 0;
159}
160
Sreeram Ramachandran36ed53e2014-07-01 19:01:56 -0700161Network::Type PhysicalNetwork::getType() const {
162 return PHYSICAL;
163}
164
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700165int PhysicalNetwork::addInterface(const std::string& interface) {
166 if (hasInterface(interface)) {
167 return 0;
168 }
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700169 if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
170 mPermission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700171 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
172 return ret;
173 }
174 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700175 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700176 return ret;
177 }
178 }
179 mInterfaces.insert(interface);
180 return 0;
181}
182
183int PhysicalNetwork::removeInterface(const std::string& interface) {
184 if (!hasInterface(interface)) {
185 return 0;
186 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700187 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700188 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700189 return ret;
190 }
191 }
Paul Jensen6d7e6232014-08-01 10:54:03 -0400192 // This step will flush the interface index from the cache in RouteController so it must be
193 // done last as further requests to the RouteController regarding this interface will fail
194 // to find the interface index in the cache in cases where the interface is already gone
195 // (e.g. bt-pan).
196 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
197 mPermission)) {
198 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
199 return ret;
200 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700201 mInterfaces.erase(interface);
202 return 0;
203}
Lorenzo Colitti7035f222017-02-13 18:29:00 +0900204
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900205} // namespace android::net