Home | History | Annotate | Download | only in server
      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 
     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 
     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 
     58 PhysicalNetwork::Delegate::~Delegate() {
     59 }
     60 
     61 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
     62         Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
     63 }
     64 
     65 PhysicalNetwork::~PhysicalNetwork() {
     66 }
     67 
     68 Permission PhysicalNetwork::getPermission() const {
     69     return mPermission;
     70 }
     71 
     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 
     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 
    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 
    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 
    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 
    164 Network::Type PhysicalNetwork::getType() const {
    165     return PHYSICAL;
    166 }
    167 
    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 
    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