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 #define LOG_TAG "Netd"
18
19 #include "PhysicalNetwork.h"
20
21 #include "RouteController.h"
22 #include "SockDiag.h"
23
24 #include "log/log.h"
25
26 namespace android::net {
27
28 namespace {
29
addToDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)30 [[nodiscard]] int addToDefault(unsigned netId, const std::string& interface, Permission permission,
31 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 [[nodiscard]] int removeFromDefault(unsigned netId, const std::string& interface,
43 Permission permission, PhysicalNetwork::Delegate* delegate) {
44 if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
45 permission)) {
46 ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
47 return ret;
48 }
49 if (int ret = delegate->removeFallthrough(interface, permission)) {
50 return ret;
51 }
52 return 0;
53 }
54
55 } // namespace
56
~Delegate()57 PhysicalNetwork::Delegate::~Delegate() {}
58
PhysicalNetwork(unsigned netId,PhysicalNetwork::Delegate * delegate)59 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
60 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
61 }
62
~PhysicalNetwork()63 PhysicalNetwork::~PhysicalNetwork() {}
64
getPermission() const65 Permission PhysicalNetwork::getPermission() const {
66 return mPermission;
67 }
68
destroySocketsLackingPermission(Permission permission)69 int 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
invalidateRouteCache(const std::string & interface)86 void 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", RouteController::INTERFACE,
92 0 /* mtu */);
93 (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
94 RouteController::INTERFACE);
95 }
96 }
97
setPermission(Permission permission)98 int PhysicalNetwork::setPermission(Permission permission) {
99 if (permission == mPermission) {
100 return 0;
101 }
102 if (mInterfaces.empty()) {
103 mPermission = permission;
104 return 0;
105 }
106
107 destroySocketsLackingPermission(permission);
108 for (const std::string& interface : mInterfaces) {
109 if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
110 mPermission, permission)) {
111 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 }
115 invalidateRouteCache(interface);
116 }
117 if (mIsDefault) {
118 for (const std::string& interface : mInterfaces) {
119 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
120 return ret;
121 }
122 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
123 return ret;
124 }
125 }
126 }
127 // 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);
131 mPermission = permission;
132 return 0;
133 }
134
addAsDefault()135 int PhysicalNetwork::addAsDefault() {
136 if (mIsDefault) {
137 return 0;
138 }
139 for (const std::string& interface : mInterfaces) {
140 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
141 return ret;
142 }
143 }
144 mIsDefault = true;
145 return 0;
146 }
147
removeAsDefault()148 int PhysicalNetwork::removeAsDefault() {
149 if (!mIsDefault) {
150 return 0;
151 }
152 for (const std::string& interface : mInterfaces) {
153 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
154 return ret;
155 }
156 }
157 mIsDefault = false;
158 return 0;
159 }
160
addUsers(const UidRanges & uidRanges,uint32_t subPriority)161 int PhysicalNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
162 if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
163 return -EINVAL;
164 }
165
166 for (const std::string& interface : mInterfaces) {
167 int ret = RouteController::addUsersToPhysicalNetwork(mNetId, interface.c_str(),
168 {{subPriority, uidRanges}});
169 if (ret) {
170 ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
171 return ret;
172 }
173 }
174 addToUidRangeMap(uidRanges, subPriority);
175 return 0;
176 }
177
removeUsers(const UidRanges & uidRanges,uint32_t subPriority)178 int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
179 if (!isValidSubPriority(subPriority)) return -EINVAL;
180
181 for (const std::string& interface : mInterfaces) {
182 int ret = RouteController::removeUsersFromPhysicalNetwork(mNetId, interface.c_str(),
183 {{subPriority, uidRanges}});
184 if (ret) {
185 ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
186 return ret;
187 }
188 }
189 removeFromUidRangeMap(uidRanges, subPriority);
190 return 0;
191 }
192
addInterface(const std::string & interface)193 int PhysicalNetwork::addInterface(const std::string& interface) {
194 if (hasInterface(interface)) {
195 return 0;
196 }
197 if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
198 mPermission, mUidRangeMap)) {
199 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
200 return ret;
201 }
202 if (mIsDefault) {
203 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
204 return ret;
205 }
206 }
207 mInterfaces.insert(interface);
208 return 0;
209 }
210
removeInterface(const std::string & interface)211 int PhysicalNetwork::removeInterface(const std::string& interface) {
212 if (!hasInterface(interface)) {
213 return 0;
214 }
215 if (mIsDefault) {
216 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
217 return ret;
218 }
219 }
220 // This step will flush the interface index from the cache in RouteController so it must be
221 // done last as further requests to the RouteController regarding this interface will fail
222 // to find the interface index in the cache in cases where the interface is already gone
223 // (e.g. bt-pan).
224 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
225 mPermission, mUidRangeMap)) {
226 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
227 return ret;
228 }
229 mInterfaces.erase(interface);
230 return 0;
231 }
232
isValidSubPriority(uint32_t priority)233 bool PhysicalNetwork::isValidSubPriority(uint32_t priority) {
234 return priority >= UidRanges::DEFAULT_SUB_PRIORITY &&
235 priority <= UidRanges::LOWEST_SUB_PRIORITY;
236 }
237
238 } // namespace android::net
239