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 
21 #define LOG_TAG "Netd"
22 #include "log/log.h"
23 
24 namespace {
25 
addToDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)26 WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
27                                     Permission permission, PhysicalNetwork::Delegate* delegate) {
28     if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
29         ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
30         return ret;
31     }
32     if (int ret = delegate->addFallthrough(interface, permission)) {
33         return ret;
34     }
35     return 0;
36 }
37 
removeFromDefault(unsigned netId,const std::string & interface,Permission permission,PhysicalNetwork::Delegate * delegate)38 WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
39                                          Permission permission,
40                                          PhysicalNetwork::Delegate* delegate) {
41     if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
42                                                                      permission)) {
43         ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
44         return ret;
45     }
46     if (int ret = delegate->removeFallthrough(interface, permission)) {
47         return ret;
48     }
49     return 0;
50 }
51 
52 }  // namespace
53 
~Delegate()54 PhysicalNetwork::Delegate::~Delegate() {
55 }
56 
PhysicalNetwork(unsigned netId,PhysicalNetwork::Delegate * delegate)57 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
58         Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
59 }
60 
~PhysicalNetwork()61 PhysicalNetwork::~PhysicalNetwork() {
62 }
63 
getPermission() const64 Permission PhysicalNetwork::getPermission() const {
65     return mPermission;
66 }
67 
setPermission(Permission permission)68 int PhysicalNetwork::setPermission(Permission permission) {
69     if (permission == mPermission) {
70         return 0;
71     }
72     for (const std::string& interface : mInterfaces) {
73         if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
74                                                                        mPermission, permission)) {
75             ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
76                   interface.c_str(), mNetId, mPermission, permission);
77             return ret;
78         }
79     }
80     if (mIsDefault) {
81         for (const std::string& interface : mInterfaces) {
82             if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
83                 return ret;
84             }
85             if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
86                 return ret;
87             }
88         }
89     }
90     mPermission = permission;
91     return 0;
92 }
93 
addAsDefault()94 int PhysicalNetwork::addAsDefault() {
95     if (mIsDefault) {
96         return 0;
97     }
98     for (const std::string& interface : mInterfaces) {
99         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
100             return ret;
101         }
102     }
103     mIsDefault = true;
104     return 0;
105 }
106 
removeAsDefault()107 int PhysicalNetwork::removeAsDefault() {
108     if (!mIsDefault) {
109         return 0;
110     }
111     for (const std::string& interface : mInterfaces) {
112         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
113             return ret;
114         }
115     }
116     mIsDefault = false;
117     return 0;
118 }
119 
getType() const120 Network::Type PhysicalNetwork::getType() const {
121     return PHYSICAL;
122 }
123 
addInterface(const std::string & interface)124 int PhysicalNetwork::addInterface(const std::string& interface) {
125     if (hasInterface(interface)) {
126         return 0;
127     }
128     if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
129                                                                  mPermission)) {
130         ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
131         return ret;
132     }
133     if (mIsDefault) {
134         if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
135             return ret;
136         }
137     }
138     mInterfaces.insert(interface);
139     return 0;
140 }
141 
removeInterface(const std::string & interface)142 int PhysicalNetwork::removeInterface(const std::string& interface) {
143     if (!hasInterface(interface)) {
144         return 0;
145     }
146     if (mIsDefault) {
147         if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
148             return ret;
149         }
150     }
151     // This step will flush the interface index from the cache in RouteController so it must be
152     // done last as further requests to the RouteController regarding this interface will fail
153     // to find the interface index in the cache in cases where the interface is already gone
154     // (e.g. bt-pan).
155     if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
156                                                                       mPermission)) {
157         ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
158         return ret;
159     }
160     mInterfaces.erase(interface);
161     return 0;
162 }
163