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