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