summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2017-10-30 19:21:06 +0900
committerLorenzo Colitti <lorenzo@google.com>2017-11-24 17:01:50 +0900
commit02cb80a71afbbe89e3ced8b417b2abe7578dbc82 (patch)
treef7c1f3c7ce79e82d4f13c0ded3b0d5afc34b6fa6
parentc2db59afb266f31e9657f8a21b9ec1a9d221cd2b (diff)
downloadnetd-02cb80a71afbbe89e3ced8b417b2abe7578dbc82.tar.gz
Change RouteController from free functions/members to class functions.
In a future change, this will make it more explicit which bits of state (e.g., locks) are part of the class and which are not. Test: netd_{unit,integration}_test passes Change-Id: Iff5a202cdcb26a7b6039dd95655cc2c26592fc36
-rw-r--r--server/RouteController.cpp59
-rw-r--r--server/RouteController.h24
-rw-r--r--server/RouteControllerTest.cpp4
3 files changed, 60 insertions, 27 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 27990759..e2f317d4 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -136,20 +136,17 @@ const char *familyName(uint8_t family) {
}
}
-// No locks needed because RouteController is accessed only from one thread (in CommandListener).
-std::map<std::string, uint32_t> interfaceToTable;
-
-uint32_t getRouteTableForInterface(const char* interface) {
+uint32_t RouteController::getRouteTableForInterface(const char* interface) {
uint32_t index = if_nametoindex(interface);
if (index) {
index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
- interfaceToTable[interface] = index;
+ sInterfaceToTable[interface] = index;
return index;
}
// If the interface goes away if_nametoindex() will return 0 but we still need to know
// the index so we can remove the rules and routes.
- auto iter = interfaceToTable.find(interface);
- if (iter == interfaceToTable.end()) {
+ auto iter = sInterfaceToTable.find(interface);
+ if (iter == sInterfaceToTable.end()) {
ALOGE("cannot find interface %s", interface);
return RT_TABLE_UNSPEC;
}
@@ -166,7 +163,7 @@ void addTableName(uint32_t table, const std::string& name, std::string* contents
}
// Doesn't return success/failure as the file is optional; it's okay if we fail to update it.
-void updateTableNamesFile() {
+void RouteController::updateTableNamesFile() {
std::string contents;
addTableName(RT_TABLE_LOCAL, ROUTE_TABLE_NAME_LOCAL, &contents);
@@ -176,7 +173,7 @@ void updateTableNamesFile() {
addTableName(ROUTE_TABLE_LEGACY_NETWORK, ROUTE_TABLE_NAME_LEGACY_NETWORK, &contents);
addTableName(ROUTE_TABLE_LEGACY_SYSTEM, ROUTE_TABLE_NAME_LEGACY_SYSTEM, &contents);
- for (const auto& entry : interfaceToTable) {
+ for (const auto& entry : sInterfaceToTable) {
addTableName(entry.second, entry.first, &contents);
}
@@ -577,9 +574,9 @@ WARN_UNUSED_RESULT int modifyImplicitNetworkRule(unsigned netId, uint32_t table,
// If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to
// go over the default network, provided it wasn't explicitly restricted to the VPN and has the
// permissions required by the default network.
-WARN_UNUSED_RESULT int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
- const char* physicalInterface,
- Permission permission) {
+WARN_UNUSED_RESULT int RouteController::modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
+ const char* physicalInterface,
+ Permission permission) {
uint32_t table = getRouteTableForInterface(physicalInterface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -644,7 +641,8 @@ WARN_UNUSED_RESULT int addLocalNetworkRules(unsigned localNetId) {
fwmark.intValue, mask.intValue);
}
-int configureDummyNetwork() {
+/* static */
+int RouteController::configureDummyNetwork() {
const char *interface = DummyNetwork::INTERFACE_NAME;
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
@@ -694,8 +692,9 @@ WARN_UNUSED_RESULT int modifyLocalNetwork(unsigned netId, const char* interface,
INVALID_UID, INVALID_UID, add);
}
-WARN_UNUSED_RESULT int modifyPhysicalNetwork(unsigned netId, const char* interface,
- Permission permission, bool add) {
+/* static */
+WARN_UNUSED_RESULT int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface,
+ Permission permission, bool add) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -757,9 +756,10 @@ WARN_UNUSED_RESULT int modifyRejectNonSecureNetworkRule(const UidRanges& uidRang
return 0;
}
-WARN_UNUSED_RESULT int modifyVirtualNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges, bool secure, bool add,
- bool modifyNonUidBasedRules) {
+WARN_UNUSED_RESULT int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
+ const UidRanges& uidRanges,
+ bool secure, bool add,
+ bool modifyNonUidBasedRules) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -796,8 +796,8 @@ WARN_UNUSED_RESULT int modifyVirtualNetwork(unsigned netId, const char* interfac
return 0;
}
-WARN_UNUSED_RESULT int modifyDefaultNetwork(uint16_t action, const char* interface,
- Permission permission) {
+WARN_UNUSED_RESULT int RouteController::modifyDefaultNetwork(uint16_t action, const char* interface,
+ Permission permission) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -816,8 +816,9 @@ WARN_UNUSED_RESULT int modifyDefaultNetwork(uint16_t action, const char* interfa
mask.intValue);
}
-WARN_UNUSED_RESULT int modifyTetheredNetwork(uint16_t action, const char* inputInterface,
- const char* outputInterface) {
+WARN_UNUSED_RESULT int RouteController::modifyTetheredNetwork(uint16_t action,
+ const char* inputInterface,
+ const char* outputInterface) {
uint32_t table = getRouteTableForInterface(outputInterface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -829,8 +830,9 @@ WARN_UNUSED_RESULT int modifyTetheredNetwork(uint16_t action, const char* inputI
// Adds or removes an IPv4 or IPv6 route to the specified table.
// Returns 0 on success or negative errno on failure.
-WARN_UNUSED_RESULT int modifyRoute(uint16_t action, const char* interface, const char* destination,
- const char* nexthop, RouteController::TableType tableType) {
+WARN_UNUSED_RESULT int RouteController::modifyRoute(uint16_t action, const char* interface,
+ const char* destination, const char* nexthop,
+ TableType tableType) {
uint32_t table;
switch (tableType) {
case RouteController::INTERFACE: {
@@ -893,7 +895,7 @@ WARN_UNUSED_RESULT int flushRules() {
return rtNetlinkFlush(RTM_GETRULE, RTM_DELRULE, "rules", shouldDelete);
}
-WARN_UNUSED_RESULT int flushRoutes(uint32_t table) {
+WARN_UNUSED_RESULT int RouteController::flushRoutes(uint32_t table) {
NetlinkDumpFilter shouldDelete = [table] (nlmsghdr *nlh) {
return getRouteTable(nlh) == table;
};
@@ -902,7 +904,7 @@ WARN_UNUSED_RESULT int flushRoutes(uint32_t table) {
}
// Returns 0 on success or negative errno on failure.
-WARN_UNUSED_RESULT int flushRoutes(const char* interface) {
+WARN_UNUSED_RESULT int RouteController::flushRoutes(const char* interface) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -913,7 +915,7 @@ WARN_UNUSED_RESULT int flushRoutes(const char* interface) {
// If we failed to flush routes, the caller may elect to keep this interface around, so keep
// track of its name.
if (ret == 0) {
- interfaceToTable.erase(interface);
+ sInterfaceToTable.erase(interface);
}
return ret;
@@ -1062,5 +1064,8 @@ int RouteController::removeVirtualNetworkFallthrough(unsigned vpnNetId,
return modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission);
}
+// No locks needed because RouteController is accessed only from one thread (in CommandListener).
+std::map<std::string, uint32_t> RouteController::sInterfaceToTable;
+
} // namespace net
} // namespace android
diff --git a/server/RouteController.h b/server/RouteController.h
index d13ea586..b01e283c 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -20,6 +20,7 @@
#include "NetdConstants.h"
#include "Permission.h"
+#include <map>
#include <sys/types.h>
#include <linux/netlink.h>
@@ -97,6 +98,29 @@ public:
// For testing.
static int (*iptablesRestoreCommandFunction)(IptablesTarget, const std::string&,
const std::string&, std::string *);
+
+private:
+ friend class RouteControllerTest;
+
+ static std::map<std::string, uint32_t> sInterfaceToTable;
+
+ static int configureDummyNetwork();
+ static int flushRoutes(const char* interface);
+ static int flushRoutes(uint32_t table);
+ static uint32_t getRouteTableForInterface(const char *interface);
+ static int modifyDefaultNetwork(uint16_t action, const char* interface, Permission permission);
+ static int modifyPhysicalNetwork(unsigned netId, const char* interface, Permission permission,
+ bool add);
+ static int modifyRoute(uint16_t action, const char* interface, const char* destination,
+ const char* nexthop, TableType tableType);
+ static int modifyTetheredNetwork(uint16_t action, const char* inputInterface,
+ const char* outputInterface);
+ static int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
+ const char* physicalInterface, Permission permission);
+ static int modifyVirtualNetwork(unsigned netId, const char* interface,
+ const UidRanges& uidRanges, bool secure, bool add,
+ bool modifyNonUidBasedRules);
+ static void updateTableNamesFile();
};
// Public because they are called by by RouteControllerTest.cpp.
diff --git a/server/RouteControllerTest.cpp b/server/RouteControllerTest.cpp
index 090b383b..62540b93 100644
--- a/server/RouteControllerTest.cpp
+++ b/server/RouteControllerTest.cpp
@@ -30,6 +30,10 @@ public:
RouteControllerTest() {
RouteController::iptablesRestoreCommandFunction = fakeExecIptablesRestoreCommand;
}
+
+ int flushRoutes(uint32_t a) {
+ return RouteController::flushRoutes(a);
+ }
};
TEST_F(RouteControllerTest, TestGetRulePriority) {