• 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)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     // This method invalidates all socket destination cache entries in the kernel by creating and
88     // removing a low-priority route.
89     // This number is an arbitrary number that need to be higher than any other route created either
90     // by netd or by an IPv6 RouterAdvertisement.
91     int priority = 100000;
92 
93     for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
94         // If any of these operations fail, there's no point in logging because RouteController will
95         // have already logged a message. There's also no point returning an error since there's
96         // nothing we can do.
97         (void)RouteController::addRoute(interface.c_str(), dst, "throw", RouteController::INTERFACE,
98                                         0 /* mtu */, priority);
99         (void)RouteController::removeRoute(interface.c_str(), dst, "throw",
100                                            RouteController::INTERFACE, priority);
101     }
102 }
103 
setPermission(Permission permission)104 int PhysicalNetwork::setPermission(Permission permission) {
105     if (permission == mPermission) {
106         return 0;
107     }
108     if (mInterfaces.empty()) {
109         mPermission = permission;
110         return 0;
111     }
112 
113     destroySocketsLackingPermission(permission);
114     for (const std::string& interface : mInterfaces) {
115         if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
116                                                                        mPermission, permission)) {
117             ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
118                   interface.c_str(), mNetId, mPermission, permission);
119             return ret;
120         }
121         invalidateRouteCache(interface);
122     }
123     if (mIsDefault) {
124         for (const std::string& interface : mInterfaces) {
125             if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
126                 return ret;
127             }
128             if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
129                 return ret;
130             }
131         }
132     }
133     // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
134     // above and before we changed the permissions. These sockets won't be able to send any RST
135     // packets because they are now no longer routed, but at least the apps will get errors.
136     destroySocketsLackingPermission(permission);
137     mPermission = permission;
138     return 0;
139 }
140 
addAsDefault()141 int PhysicalNetwork::addAsDefault() {
142     if (mIsDefault) {
143         return 0;
144     }
145     for (const std::string& interface : mInterfaces) {
146         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
147             return ret;
148         }
149     }
150     mIsDefault = true;
151     return 0;
152 }
153 
removeAsDefault()154 int PhysicalNetwork::removeAsDefault() {
155     if (!mIsDefault) {
156         return 0;
157     }
158     for (const std::string& interface : mInterfaces) {
159         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
160             return ret;
161         }
162     }
163     mIsDefault = false;
164     return 0;
165 }
166 
addUsers(const UidRanges & uidRanges,int32_t subPriority)167 int PhysicalNetwork::addUsers(const UidRanges& uidRanges, int32_t subPriority) {
168     if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges)) {
169         return -EINVAL;
170     }
171 
172     for (const std::string& interface : mInterfaces) {
173         int ret = RouteController::addUsersToPhysicalNetwork(mNetId, interface.c_str(),
174                                                              {{subPriority, uidRanges}});
175         if (ret) {
176             ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
177             return ret;
178         }
179     }
180     addToUidRangeMap(uidRanges, subPriority);
181     return 0;
182 }
183 
removeUsers(const UidRanges & uidRanges,int32_t subPriority)184 int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, int32_t subPriority) {
185     if (!isValidSubPriority(subPriority)) return -EINVAL;
186 
187     for (const std::string& interface : mInterfaces) {
188         int ret = RouteController::removeUsersFromPhysicalNetwork(mNetId, interface.c_str(),
189                                                                   {{subPriority, uidRanges}});
190         if (ret) {
191             ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
192             return ret;
193         }
194     }
195     removeFromUidRangeMap(uidRanges, subPriority);
196     return 0;
197 }
198 
addInterface(const std::string & interface)199 int PhysicalNetwork::addInterface(const std::string& interface) {
200     if (hasInterface(interface)) {
201         return 0;
202     }
203     if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
204                                                                  mPermission, mUidRangeMap)) {
205         ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
206         return ret;
207     }
208     if (mIsDefault) {
209         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
210             return ret;
211         }
212     }
213     mInterfaces.insert(interface);
214     return 0;
215 }
216 
removeInterface(const std::string & interface)217 int PhysicalNetwork::removeInterface(const std::string& interface) {
218     if (!hasInterface(interface)) {
219         return 0;
220     }
221     if (mIsDefault) {
222         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
223             return ret;
224         }
225     }
226     // This step will flush the interface index from the cache in RouteController so it must be
227     // done last as further requests to the RouteController regarding this interface will fail
228     // to find the interface index in the cache in cases where the interface is already gone
229     // (e.g. bt-pan).
230     if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
231                                                                       mPermission, mUidRangeMap)) {
232         ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
233         return ret;
234     }
235     mInterfaces.erase(interface);
236     return 0;
237 }
238 
isValidSubPriority(int32_t priority)239 bool PhysicalNetwork::isValidSubPriority(int32_t priority) {
240     // SUB_PRIORITY_NO_DEFAULT is a special value, see UidRanges.h.
241     return (priority >= UidRanges::SUB_PRIORITY_HIGHEST &&
242             priority <= UidRanges::SUB_PRIORITY_LOWEST) ||
243            priority == UidRanges::SUB_PRIORITY_NO_DEFAULT;
244 }
245 
246 }  // namespace android::net
247