blob: 7a1f3052312d12376297a88a13e2ea1f2ce57a5b [file] [log] [blame]
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -07001/*
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
Luke Huang94658ac2018-10-18 19:35:12 +090017#define LOG_TAG "Netd"
18
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070019#include "PhysicalNetwork.h"
20
21#include "RouteController.h"
Lorenzo Colittic6201c32016-09-14 02:25:05 +090022#include "SockDiag.h"
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070023
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070024#include "log/log.h"
25
Lorenzo Colitti7035f222017-02-13 18:29:00 +090026namespace android {
27namespace net {
28
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070029namespace {
30
31WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070032 Permission permission, PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070033 if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070034 ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
35 return ret;
36 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070037 if (int ret = delegate->addFallthrough(interface, permission)) {
38 return ret;
39 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070040 return 0;
41}
42
43WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070044 Permission permission,
45 PhysicalNetwork::Delegate* delegate) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070046 if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
47 permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070048 ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
49 return ret;
50 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070051 if (int ret = delegate->removeFallthrough(interface, permission)) {
52 return ret;
53 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070054 return 0;
55}
56
57} // namespace
58
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -070059PhysicalNetwork::Delegate::~Delegate() {
60}
61
62PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
63 Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070064}
65
66PhysicalNetwork::~PhysicalNetwork() {
67}
68
69Permission PhysicalNetwork::getPermission() const {
70 return mPermission;
71}
72
Lorenzo Colittic6201c32016-09-14 02:25:05 +090073int PhysicalNetwork::destroySocketsLackingPermission(Permission permission) {
74 if (permission == PERMISSION_NONE) return 0;
75
76 SockDiag sd;
77 if (!sd.open()) {
78 ALOGE("Error closing sockets for netId %d permission change", mNetId);
79 return -EBADFD;
80 }
81 if (int ret = sd.destroySocketsLackingPermission(mNetId, permission,
82 true /* excludeLoopback */)) {
83 ALOGE("Failed to close sockets changing netId %d to permission %d: %s",
84 mNetId, permission, strerror(-ret));
85 return ret;
86 }
87 return 0;
88}
89
Lorenzo Colitti4662e162017-09-08 11:31:59 +090090void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
91 for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
92 // If any of these operations fail, there's no point in logging because RouteController will
93 // have already logged a message. There's also no point returning an error since there's
94 // nothing we can do.
95 (void) RouteController::addRoute(interface.c_str(), dst, "throw",
96 RouteController::INTERFACE);
97 (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
98 RouteController::INTERFACE);
99 }
100}
101
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700102int PhysicalNetwork::setPermission(Permission permission) {
103 if (permission == mPermission) {
104 return 0;
105 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900106 if (mInterfaces.empty()) {
107 mPermission = permission;
108 return 0;
109 }
110
111 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700112 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700113 if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
114 mPermission, permission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700115 ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
116 interface.c_str(), mNetId, mPermission, permission);
117 return ret;
118 }
Lorenzo Colitti4662e162017-09-08 11:31:59 +0900119 invalidateRouteCache(interface);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700120 }
121 if (mIsDefault) {
122 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700123 if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700124 return ret;
125 }
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700126 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700127 return ret;
128 }
129 }
130 }
Lorenzo Colittic6201c32016-09-14 02:25:05 +0900131 // Destroy sockets again in case any were opened after we called destroySocketsLackingPermission
132 // above and before we changed the permissions. These sockets won't be able to send any RST
133 // packets because they are now no longer routed, but at least the apps will get errors.
134 destroySocketsLackingPermission(permission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700135 mPermission = permission;
136 return 0;
137}
138
139int PhysicalNetwork::addAsDefault() {
140 if (mIsDefault) {
141 return 0;
142 }
143 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700144 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700145 return ret;
146 }
147 }
148 mIsDefault = true;
149 return 0;
150}
151
152int PhysicalNetwork::removeAsDefault() {
153 if (!mIsDefault) {
154 return 0;
155 }
156 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700157 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700158 return ret;
159 }
160 }
161 mIsDefault = false;
162 return 0;
163}
164
Sreeram Ramachandran36ed53e2014-07-01 19:01:56 -0700165Network::Type PhysicalNetwork::getType() const {
166 return PHYSICAL;
167}
168
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700169int PhysicalNetwork::addInterface(const std::string& interface) {
170 if (hasInterface(interface)) {
171 return 0;
172 }
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700173 if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
174 mPermission)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700175 ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
176 return ret;
177 }
178 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700179 if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700180 return ret;
181 }
182 }
183 mInterfaces.insert(interface);
184 return 0;
185}
186
187int PhysicalNetwork::removeInterface(const std::string& interface) {
188 if (!hasInterface(interface)) {
189 return 0;
190 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700191 if (mIsDefault) {
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700192 if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700193 return ret;
194 }
195 }
Paul Jensen6d7e6232014-08-01 10:54:03 -0400196 // This step will flush the interface index from the cache in RouteController so it must be
197 // done last as further requests to the RouteController regarding this interface will fail
198 // to find the interface index in the cache in cases where the interface is already gone
199 // (e.g. bt-pan).
200 if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
201 mPermission)) {
202 ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
203 return ret;
204 }
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700205 mInterfaces.erase(interface);
206 return 0;
207}
Lorenzo Colitti7035f222017-02-13 18:29:00 +0900208
209} // namespace net
210} // namespace android