Add locking to RouteController.
Test: netd_{unit,integration}_test passes
Change-Id: I12899e0304d266b25b0b021ae28f9073c8b42604
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index e2f317d..498ac11 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -136,7 +136,8 @@
}
}
-uint32_t RouteController::getRouteTableForInterface(const char* interface) {
+// Caller must hold sInterfaceToTableLock.
+uint32_t RouteController::getRouteTableForInterfaceLocked(const char* interface) {
uint32_t index = if_nametoindex(interface);
if (index) {
index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
@@ -153,6 +154,11 @@
return iter->second;
}
+uint32_t RouteController::getRouteTableForInterface(const char* interface) {
+ android::RWLock::AutoRLock lock(sInterfaceToTableLock);
+ return getRouteTableForInterfaceLocked(interface);
+}
+
void addTableName(uint32_t table, const std::string& name, std::string* contents) {
char tableString[UINT32_STRLEN];
snprintf(tableString, sizeof(tableString), "%u", table);
@@ -173,6 +179,7 @@
addTableName(ROUTE_TABLE_LEGACY_NETWORK, ROUTE_TABLE_NAME_LEGACY_NETWORK, &contents);
addTableName(ROUTE_TABLE_LEGACY_SYSTEM, ROUTE_TABLE_NAME_LEGACY_SYSTEM, &contents);
+ android::RWLock::AutoRLock lock(sInterfaceToTableLock);
for (const auto& entry : sInterfaceToTable) {
addTableName(entry.second, entry.first, &contents);
}
@@ -905,7 +912,9 @@
// Returns 0 on success or negative errno on failure.
WARN_UNUSED_RESULT int RouteController::flushRoutes(const char* interface) {
- uint32_t table = getRouteTableForInterface(interface);
+ android::RWLock::AutoWLock lock(sInterfaceToTableLock);
+
+ uint32_t table = getRouteTableForInterfaceLocked(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -1064,7 +1073,9 @@
return modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission);
}
-// No locks needed because RouteController is accessed only from one thread (in CommandListener).
+// Protects sInterfaceToTable.
+android::RWLock RouteController::sInterfaceToTableLock;
+
std::map<std::string, uint32_t> RouteController::sInterfaceToTable;
} // namespace net