• 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 {
27 namespace net {
28 
29 namespace {
30 
addToDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)31 WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
32                                     Permission permission, PhysicalNetwork::Delegate* delegate) {
33     if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
34         ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
35         return ret;
36     }
37     if (int ret = delegate->addFallthrough(interface, permission)) {
38         return ret;
39     }
40     return 0;
41 }
42 
removeFromDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)43 WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
44                                          Permission permission,
45                                          PhysicalNetwork::Delegate* delegate) {
46     if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
47                                                                      permission)) {
48         ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
49         return ret;
50     }
51     if (int ret = delegate->removeFallthrough(interface, permission)) {
52         return ret;
53     }
54     return 0;
55 }
56 
57 }  // namespace
58 
~Delegate()59 PhysicalNetwork::Delegate::~Delegate() {
60 }
61 
PhysicalNetwork(unsigned netId,PhysicalNetwork::Delegate * delegate)62 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
63         Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
64 }
65 
~PhysicalNetwork()66 PhysicalNetwork::~PhysicalNetwork() {
67 }
68 
getPermission() const69 Permission PhysicalNetwork::getPermission() const {
70     return mPermission;
71 }
72 
destroySocketsLackingPermission(Permission permission)73 int PhysicalNetwork::destroySocketsLackingPermission(Permission permission) {
74     if (permission == PERMISSION_NONE) return 0;
75 
76     SockDiag sd;
77     if (!sd.open()) {
78        ALOGE("Error closing sockets for netId %d permission change", mNetId);
79        return -EBADFD;
80     }
81     if (int ret = sd.destroySocketsLackingPermission(mNetId, permission,
82                                                      true /* excludeLoopback */)) {
83         ALOGE("Failed to close sockets changing netId %d to permission %d: %s",
84               mNetId, permission, strerror(-ret));
85         return ret;
86     }
87     return 0;
88 }
89 
invalidateRouteCache(const std::string & interface)90 void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
91     for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
92         // If any of these operations fail, there's no point in logging because RouteController will
93         // have already logged a message. There's also no point returning an error since there's
94         // nothing we can do.
95         (void) RouteController::addRoute(interface.c_str(), dst, "throw",
96                                          RouteController::INTERFACE);
97         (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
98                                          RouteController::INTERFACE);
99     }
100 }
101 
setPermission(Permission permission)102 int PhysicalNetwork::setPermission(Permission permission) {
103     if (permission == mPermission) {
104         return 0;
105     }
106     if (mInterfaces.empty()) {
107         mPermission = permission;
108         return 0;
109     }
110 
111     destroySocketsLackingPermission(permission);
112     for (const std::string& interface : mInterfaces) {
113         if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
114                                                                        mPermission, permission)) {
115             ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
116                   interface.c_str(), mNetId, mPermission, permission);
117             return ret;
118         }
119         invalidateRouteCache(interface);
120     }
121     if (mIsDefault) {
122         for (const std::string& interface : mInterfaces) {
123             if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
124                 return ret;
125             }
126             if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
127                 return ret;
128             }
129         }
130     }
131     // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
132     // above and before we changed the permissions. These sockets won't be able to send any RST
133     // packets because they are now no longer routed, but at least the apps will get errors.
134     destroySocketsLackingPermission(permission);
135     mPermission = permission;
136     return 0;
137 }
138 
addAsDefault()139 int PhysicalNetwork::addAsDefault() {
140     if (mIsDefault) {
141         return 0;
142     }
143     for (const std::string& interface : mInterfaces) {
144         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
145             return ret;
146         }
147     }
148     mIsDefault = true;
149     return 0;
150 }
151 
removeAsDefault()152 int PhysicalNetwork::removeAsDefault() {
153     if (!mIsDefault) {
154         return 0;
155     }
156     for (const std::string& interface : mInterfaces) {
157         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
158             return ret;
159         }
160     }
161     mIsDefault = false;
162     return 0;
163 }
164 
getType() const165 Network::Type PhysicalNetwork::getType() const {
166     return PHYSICAL;
167 }
168 
addInterface(const std::string & interface)169 int PhysicalNetwork::addInterface(const std::string& interface) {
170     if (hasInterface(interface)) {
171         return 0;
172     }
173     if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
174                                                                  mPermission)) {
175         ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
176         return ret;
177     }
178     if (mIsDefault) {
179         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
180             return ret;
181         }
182     }
183     mInterfaces.insert(interface);
184     return 0;
185 }
186 
removeInterface(const std::string & interface)187 int PhysicalNetwork::removeInterface(const std::string& interface) {
188     if (!hasInterface(interface)) {
189         return 0;
190     }
191     if (mIsDefault) {
192         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
193             return ret;
194         }
195     }
196     // This step will flush the interface index from the cache in RouteController so it must be
197     // done last as further requests to the RouteController regarding this interface will fail
198     // to find the interface index in the cache in cases where the interface is already gone
199     // (e.g. bt-pan).
200     if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
201                                                                       mPermission)) {
202         ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
203         return ret;
204     }
205     mInterfaces.erase(interface);
206     return 0;
207 }
208 
209 }  // namespace net
210 }  // namespace android
211