blob: 161fa2a78171b90cf8da3a86e5230cf3ed69f4c8 [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
Chalard Jean04845142022-12-02 19:39:36 +090059PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate, bool local)
60 : Network(netId),
61 mDelegate(delegate),
62 mPermission(PERMISSION_NONE),
63 mIsDefault(false),
Chalard Jeane479f312022-12-12 18:27:49 +090064 mIsLocalNetwork(local) {}
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070065
Bernie Innocenti762dcf42019-06-14 19:52:49 +090066PhysicalNetwork::~PhysicalNetwork() {}
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070067
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) {
Taras Antoshchuk0cceda22021-09-24 18:40:03 +020090 // This method invalidates all socket destination cache entries in the kernel by creating and
91 // removing a low-priority route.
92 // This number is an arbitrary number that need to be higher than any other route created either
93 // by netd or by an IPv6 RouterAdvertisement.
94 int priority = 100000;
95
Lorenzo Colitti4662e162017-09-08 11:31:59 +090096 for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
97 // If any of these operations fail, there's no point in logging because RouteController will
98 // have already logged a message. There's also no point returning an error since there's
99 // nothing we can do.
Tyler Wearfa94a272019-12-05 15:01:48 -0800100 (void)RouteController::addRoute(interface.c_str(), dst, "throw", RouteController::INTERFACE,
Taras Antoshchuk0cceda22021-09-24 18:40:03 +0200101 0 /* mtu */, priority);
102 (void)RouteController::removeRoute(interface.c_str(), dst, "throw",
103 RouteController::INTERFACE, priority);
Lorenzo Colitti4662e162017-09-08 11:31:59 +0900104 }
105}
106
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700107int PhysicalNetwork::setPermission(Permission permission) {
108 if (permission == mPermission) {
109 return 0;
110 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900111 if (mInterfaces.empty()) {
112 mPermission = permission;
113 return 0;
114 }
115
116 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700117 for (const std::string& interface : mInterfaces) {
Chalard Jeane479f312022-12-12 18:27:49 +0900118 if (int ret = RouteController::modifyPhysicalNetworkPermission(
119 mNetId, interface.c_str(), mPermission, permission, mIsLocalNetwork)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700120 ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
121 interface.c_str(), mNetId, mPermission, permission);
122 return ret;
123 }
Lorenzo Colitti4662e162017-09-08 11:31:59 +0900124 invalidateRouteCache(interface);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700125 }
126 if (mIsDefault) {
127 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700128 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700129 return ret;
130 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700131 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700132 return ret;
133 }
134 }
135 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900136 // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
137 // above and before we changed the permissions. These sockets won't be able to send any RST
138 // packets because they are now no longer routed, but at least the apps will get errors.
139 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700140 mPermission = permission;
141 return 0;
142}
143
144int PhysicalNetwork::addAsDefault() {
145 if (mIsDefault) {
146 return 0;
147 }
148 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700149 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700150 return ret;
151 }
152 }
153 mIsDefault = true;
154 return 0;
155}
156
157int PhysicalNetwork::removeAsDefault() {
158 if (!mIsDefault) {
159 return 0;
160 }
161 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700162 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700163 return ret;
164 }
165 }
166 mIsDefault = false;
167 return 0;
168}
169
Ken Chen53360bf2021-12-10 02:41:05 +0800170int PhysicalNetwork::addUsers(const UidRanges& uidRanges, int32_t subPriority) {
chiachangwang65bc4ea2022-09-07 08:10:30 +0000171 if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges)) {
Ken Chenc929e8a2021-03-22 11:37:17 +0800172 return -EINVAL;
173 }
174
175 for (const std::string& interface : mInterfaces) {
Chalard Jeane479f312022-12-12 18:27:49 +0900176 int ret = RouteController::addUsersToPhysicalNetwork(
177 mNetId, interface.c_str(), {{subPriority, uidRanges}}, mIsLocalNetwork);
Ken Chenc929e8a2021-03-22 11:37:17 +0800178 if (ret) {
179 ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
180 return ret;
181 }
182 }
Ken Chen4ea88462021-05-23 14:56:43 +0800183 addToUidRangeMap(uidRanges, subPriority);
Ken Chenc929e8a2021-03-22 11:37:17 +0800184 return 0;
185}
186
Ken Chen53360bf2021-12-10 02:41:05 +0800187int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, int32_t subPriority) {
Ken Chen4ea88462021-05-23 14:56:43 +0800188 if (!isValidSubPriority(subPriority)) return -EINVAL;
189
Ken Chenc929e8a2021-03-22 11:37:17 +0800190 for (const std::string& interface : mInterfaces) {
Chalard Jeane479f312022-12-12 18:27:49 +0900191 int ret = RouteController::removeUsersFromPhysicalNetwork(
192 mNetId, interface.c_str(), {{subPriority, uidRanges}}, mIsLocalNetwork);
Ken Chenc929e8a2021-03-22 11:37:17 +0800193 if (ret) {
194 ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
195 return ret;
196 }
197 }
Ken Chen4ea88462021-05-23 14:56:43 +0800198 removeFromUidRangeMap(uidRanges, subPriority);
Ken Chenc929e8a2021-03-22 11:37:17 +0800199 return 0;
200}
201
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700202int PhysicalNetwork::addInterface(const std::string& interface) {
203 if (hasInterface(interface)) {
204 return 0;
205 }
Chalard Jeane479f312022-12-12 18:27:49 +0900206 if (int ret = RouteController::addInterfaceToPhysicalNetwork(
207 mNetId, interface.c_str(), mPermission, mUidRangeMap, mIsLocalNetwork)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700208 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
209 return ret;
210 }
211 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700212 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700213 return ret;
214 }
215 }
216 mInterfaces.insert(interface);
217 return 0;
218}
219
220int PhysicalNetwork::removeInterface(const std::string& interface) {
221 if (!hasInterface(interface)) {
222 return 0;
223 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700224 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700225 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700226 return ret;
227 }
228 }
Paul Jensen6d7e6232014-08-01 10:54:03 -0400229 // This step will flush the interface index from the cache in RouteController so it must be
230 // done last as further requests to the RouteController regarding this interface will fail
231 // to find the interface index in the cache in cases where the interface is already gone
232 // (e.g. bt-pan).
Chalard Jeane479f312022-12-12 18:27:49 +0900233 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(
234 mNetId, interface.c_str(), mPermission, mUidRangeMap, mIsLocalNetwork)) {
Paul Jensen6d7e6232014-08-01 10:54:03 -0400235 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
236 return ret;
237 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700238 mInterfaces.erase(interface);
239 return 0;
240}
Lorenzo Colitti7035f222017-02-13 18:29:00 +0900241
Ken Chen53360bf2021-12-10 02:41:05 +0800242bool PhysicalNetwork::isValidSubPriority(int32_t priority) {
Patrick Rohre6f198c2022-01-25 13:50:31 +0100243 // SUB_PRIORITY_NO_DEFAULT is a special value, see UidRanges.h.
244 return (priority >= UidRanges::SUB_PRIORITY_HIGHEST &&
245 priority <= UidRanges::SUB_PRIORITY_LOWEST) ||
246 priority == UidRanges::SUB_PRIORITY_NO_DEFAULT;
Ken Chen4ea88462021-05-23 14:56:43 +0800247}
248
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900249} // namespace android::net