• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,bool local)59 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate, bool local)
60     : Network(netId),
61       mDelegate(delegate),
62       mPermission(PERMISSION_NONE),
63       mIsDefault(false),
64       mIsLocalNetwork(local) {}
65 
~PhysicalNetwork()66 PhysicalNetwork::~PhysicalNetwork() {}
67 
getPermission() const68 Permission PhysicalNetwork::getPermission() const {
69     return mPermission;
70 }
71 
destroySocketsLackingPermission(Permission permission)72 int 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 
invalidateRouteCache(const std::string & interface)89 void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
90     // 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 
96     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.
100         (void)RouteController::addRoute(interface.c_str(), dst, "throw", RouteController::INTERFACE,
101                                         0 /* mtu */, priority);
102         (void)RouteController::removeRoute(interface.c_str(), dst, "throw",
103                                            RouteController::INTERFACE, priority);
104     }
105 }
106 
setPermission(Permission permission)107 int PhysicalNetwork::setPermission(Permission permission) {
108     if (permission == mPermission) {
109         return 0;
110     }
111     if (mInterfaces.empty()) {
112         mPermission = permission;
113         return 0;
114     }
115 
116     destroySocketsLackingPermission(permission);
117     for (const std::string& interface : mInterfaces) {
118         if (int ret = RouteController::modifyPhysicalNetworkPermission(
119                     mNetId, interface.c_str(), mPermission, permission, mIsLocalNetwork)) {
120             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         }
124         invalidateRouteCache(interface);
125     }
126     if (mIsDefault) {
127         for (const std::string& interface : mInterfaces) {
128             if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
129                 return ret;
130             }
131             if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
132                 return ret;
133             }
134         }
135     }
136     // 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);
140     mPermission = permission;
141     return 0;
142 }
143 
addAsDefault()144 int PhysicalNetwork::addAsDefault() {
145     if (mIsDefault) {
146         return 0;
147     }
148     for (const std::string& interface : mInterfaces) {
149         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
150             return ret;
151         }
152     }
153     mIsDefault = true;
154     return 0;
155 }
156 
removeAsDefault()157 int PhysicalNetwork::removeAsDefault() {
158     if (!mIsDefault) {
159         return 0;
160     }
161     for (const std::string& interface : mInterfaces) {
162         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
163             return ret;
164         }
165     }
166     mIsDefault = false;
167     return 0;
168 }
169 
addUsers(const UidRanges & uidRanges,int32_t subPriority)170 int PhysicalNetwork::addUsers(const UidRanges& uidRanges, int32_t subPriority) {
171     if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges)) {
172         return -EINVAL;
173     }
174 
175     for (const std::string& interface : mInterfaces) {
176         int ret = RouteController::addUsersToPhysicalNetwork(
177                 mNetId, interface.c_str(), {{subPriority, uidRanges}}, mIsLocalNetwork);
178         if (ret) {
179             ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
180             return ret;
181         }
182     }
183     addToUidRangeMap(uidRanges, subPriority);
184     return 0;
185 }
186 
removeUsers(const UidRanges & uidRanges,int32_t subPriority)187 int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, int32_t subPriority) {
188     if (!isValidSubPriority(subPriority)) return -EINVAL;
189 
190     for (const std::string& interface : mInterfaces) {
191         int ret = RouteController::removeUsersFromPhysicalNetwork(
192                 mNetId, interface.c_str(), {{subPriority, uidRanges}}, mIsLocalNetwork);
193         if (ret) {
194             ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
195             return ret;
196         }
197     }
198     removeFromUidRangeMap(uidRanges, subPriority);
199     return 0;
200 }
201 
addInterface(const std::string & interface)202 int PhysicalNetwork::addInterface(const std::string& interface) {
203     if (hasInterface(interface)) {
204         return 0;
205     }
206     if (int ret = RouteController::addInterfaceToPhysicalNetwork(
207                 mNetId, interface.c_str(), mPermission, mUidRangeMap, mIsLocalNetwork)) {
208         ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
209         return ret;
210     }
211     if (mIsDefault) {
212         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
213             return ret;
214         }
215     }
216     mInterfaces.insert(interface);
217     return 0;
218 }
219 
removeInterface(const std::string & interface)220 int PhysicalNetwork::removeInterface(const std::string& interface) {
221     if (!hasInterface(interface)) {
222         return 0;
223     }
224     if (mIsDefault) {
225         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
226             return ret;
227         }
228     }
229     // 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).
233     if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(
234                 mNetId, interface.c_str(), mPermission, mUidRangeMap, mIsLocalNetwork)) {
235         ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
236         return ret;
237     }
238     mInterfaces.erase(interface);
239     return 0;
240 }
241 
isValidSubPriority(int32_t priority)242 bool PhysicalNetwork::isValidSubPriority(int32_t priority) {
243     // 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;
247 }
248 
249 }  // namespace android::net
250