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 25namespace { 26 27WARN_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 39WARN_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 55PhysicalNetwork::Delegate::~Delegate() { 56} 57 58PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) : 59 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) { 60} 61 62PhysicalNetwork::~PhysicalNetwork() { 63} 64 65Permission PhysicalNetwork::getPermission() const { 66 return mPermission; 67} 68 69int 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 86int 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 122int 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 135int 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 148Network::Type PhysicalNetwork::getType() const { 149 return PHYSICAL; 150} 151 152int 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 170int 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