netd: reorder the operations in getRouteTableForInterfaceLocked.
when network was switched quickly between wifi and cellular,
netd should always use old ifindex to delete ip rule/route,
and new ifindex to add ip rule/route.
BUG: 128805131
Test: built, booted, datausage, Phone call, Internet under
wifi and cellular data
Change-Id: I2d88709a00d50e318b02362ffac543a1e7e40a81
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index d0ceefa..d993c85 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -139,20 +139,28 @@
// 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;
- 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.
+ // If we already know the routing table for this interface name, use it.
+ // This ensures we can remove rules and routes for an interface that has been removed,
+ // or has been removed and re-added with a different interface index.
+ //
+ // The caller is responsible for ensuring that an interface is never added to a network
+ // until it has been removed from any network it was previously in. This ensures that
+ // if the same interface disconnects and then reconnects with a different interface ID
+ // when the reconnect happens the interface will not be in the map, and the code will
+ // determine the new routing table from the interface ID, below.
auto iter = sInterfaceToTable.find(interface);
- if (iter == sInterfaceToTable.end()) {
+ if (iter != sInterfaceToTable.end()) {
+ return iter->second;
+ }
+
+ uint32_t index = if_nametoindex(interface);
+ if (index == 0) {
ALOGE("cannot find interface %s", interface);
return RT_TABLE_UNSPEC;
}
- return iter->second;
+ index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
+ sInterfaceToTable[interface] = index;
+ return index;
}
uint32_t RouteController::getIfIndex(const char* interface) {