Flush routing rules and add an "unreachable" rule on Init().
Without the flush, rules accumulate duplicates when netd is restarted due to a
runtime restart. Nothing functionally wrong with having duplicates; it just
makes the output of "ip rule" look as though something went wrong in the system.
Time to add the unreachable rule, to suss out issues with corner cases. With the
flush, there's no more a naked "from main" rule that we need to protect by
adding the unreachable rule. But it's a good idea to add the unreachable rule
anyway, in case somebody comes along and adds a rule below it later.
Change-Id: I975b2221868b7f5366bd7cf60937a82fb4b75913
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index ec51613..4b908e3 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -687,6 +687,23 @@
mask.intValue);
}
+// Returns 0 on success or negative errno on failure.
+WARN_UNUSED_RESULT int flushRules() {
+ for (size_t i = 0; i < ARRAY_SIZE(IP_VERSIONS); ++i) {
+ const char* argv[] = {
+ IP_PATH,
+ IP_VERSIONS[i],
+ "rule",
+ "flush",
+ };
+ if (android_fork_execvp(ARRAY_SIZE(argv), const_cast<char**>(argv), NULL, false, false)) {
+ ALOGE("failed to flush rules");
+ return -EREMOTEIO;
+ }
+ }
+ return 0;
+}
+
// Adds or removes an IPv4 or IPv6 route to the specified table and, if it's a directly-connected
// route, to the main table as well.
// Returns 0 on success or negative errno on failure.
@@ -771,22 +788,23 @@
} // namespace
int RouteController::Init(unsigned localNetId) {
+ if (int ret = flushRules()) {
+ return ret;
+ }
+
if (int ret = addDirectlyConnectedRule()) {
return ret;
}
if (int ret = addLegacyRouteRules()) {
return ret;
}
- // TODO: Enable once we are sure everything works.
- if (false) {
- if (int ret = addUnreachableRule()) {
- return ret;
- }
+ if (int ret = addUnreachableRule()) {
+ return ret;
}
if (int ret = addImplicitLocalNetworkRule()) {
return ret;
}
- // Add a rule to lookup the local network it has been explicitly selected.
+ // Add a rule to lookup the local network if it has been explicitly selected.
if (int ret = modifyExplicitNetworkRule(localNetId, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
INVALID_UID, INVALID_UID, ACTION_ADD)) {
return ret;