• 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 #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 {
26 
addToDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)27 WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
28                                     Permission permission, PhysicalNetwork::Delegate* delegate) {
29     if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
30         ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
31         return ret;
32     }
33     if (int ret = delegate->addFallthrough(interface, permission)) {
34         return ret;
35     }
36     return 0;
37 }
38 
removeFromDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)39 WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
40                                          Permission permission,
41                                          PhysicalNetwork::Delegate* delegate) {
42     if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
43                                                                      permission)) {
44         ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
45         return ret;
46     }
47     if (int ret = delegate->removeFallthrough(interface, permission)) {
48         return ret;
49     }
50     return 0;
51 }
52 
53 }  // namespace
54 
~Delegate()55 PhysicalNetwork::Delegate::~Delegate() {
56 }
57 
PhysicalNetwork(unsigned netId,PhysicalNetwork::Delegate * delegate)58 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
59         Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
60 }
61 
~PhysicalNetwork()62 PhysicalNetwork::~PhysicalNetwork() {
63 }
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 
setPermission(Permission permission)86 int PhysicalNetwork::setPermission(Permission permission) {
87     if (permission == mPermission) {
88         return 0;
89     }
90     if (mInterfaces.empty()) {
91         mPermission = permission;
92         return 0;
93     }
94 
95     destroySocketsLackingPermission(permission);
96     for (const std::string& interface : mInterfaces) {
97         if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
98                                                                        mPermission, permission)) {
99             ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
100                   interface.c_str(), mNetId, mPermission, permission);
101             return ret;
102         }
103     }
104     if (mIsDefault) {
105         for (const std::string& interface : mInterfaces) {
106             if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
107                 return ret;
108             }
109             if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
110                 return ret;
111             }
112         }
113     }
114     // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
115     // above and before we changed the permissions. These sockets won't be able to send any RST
116     // packets because they are now no longer routed, but at least the apps will get errors.
117     destroySocketsLackingPermission(permission);
118     mPermission = permission;
119     return 0;
120 }
121 
addAsDefault()122 int PhysicalNetwork::addAsDefault() {
123     if (mIsDefault) {
124         return 0;
125     }
126     for (const std::string& interface : mInterfaces) {
127         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
128             return ret;
129         }
130     }
131     mIsDefault = true;
132     return 0;
133 }
134 
removeAsDefault()135 int PhysicalNetwork::removeAsDefault() {
136     if (!mIsDefault) {
137         return 0;
138     }
139     for (const std::string& interface : mInterfaces) {
140         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
141             return ret;
142         }
143     }
144     mIsDefault = false;
145     return 0;
146 }
147 
getType() const148 Network::Type PhysicalNetwork::getType() const {
149     return PHYSICAL;
150 }
151 
addInterface(const std::string & interface)152 int PhysicalNetwork::addInterface(const std::string& interface) {
153     if (hasInterface(interface)) {
154         return 0;
155     }
156     if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
157                                                                  mPermission)) {
158         ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
159         return ret;
160     }
161     if (mIsDefault) {
162         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
163             return ret;
164         }
165     }
166     mInterfaces.insert(interface);
167     return 0;
168 }
169 
removeInterface(const std::string & interface)170 int PhysicalNetwork::removeInterface(const std::string& interface) {
171     if (!hasInterface(interface)) {
172         return 0;
173     }
174     if (mIsDefault) {
175         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
176             return ret;
177         }
178     }
179     // This step will flush the interface index from the cache in RouteController so it must be
180     // done last as further requests to the RouteController regarding this interface will fail
181     // to find the interface index in the cache in cases where the interface is already gone
182     // (e.g. bt-pan).
183     if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
184                                                                       mPermission)) {
185         ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
186         return ret;
187     }
188     mInterfaces.erase(interface);
189     return 0;
190 }
191