shill: Assign unique metrics to non-default interfaces
Assign a metric based on the interface index to routes
for interfaces that are not default. As a result even
if the gateway address is the same (e.g, if you're connected
to a home AP via both wireless and wired) that the routes
do not conflict with each other.
BUG=chromium-os:23917
TEST=Manual: As above, connect to a home AP over Ethernet
and WiFi, and ensure that both gateway routes appear.
Change-Id: I85ffad74ec53dda535578367242114b30846b7ac
Reviewed-on: https://gerrit.chromium.org/gerrit/12651
Commit-Ready: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/connection.cc b/connection.cc
index 847ac4d..25291b5 100644
--- a/connection.cc
+++ b/connection.cc
@@ -19,7 +19,7 @@
// static
const uint32 Connection::kDefaultMetric = 1;
// static
-const uint32 Connection::kNonDefaultMetric = 10;
+const uint32 Connection::kNonDefaultMetricBase = 10;
Connection::Connection(int interface_index,
const std::string& interface_name,
@@ -61,8 +61,8 @@
rtnl_handler_->AddInterfaceAddress(interface_index_, local, broadcast);
- uint32 metric = is_default_ ? kDefaultMetric : kNonDefaultMetric;
- routing_table_->SetDefaultRoute(interface_index_, config, metric);
+ routing_table_->SetDefaultRoute(interface_index_, config,
+ GetMetric(is_default_));
// Save a copy of the last non-null DNS config
if (!config->properties().dns_servers.empty()) {
@@ -81,8 +81,7 @@
return;
}
- routing_table_->SetDefaultMetric(interface_index_,
- is_default ? kDefaultMetric : kNonDefaultMetric);
+ routing_table_->SetDefaultMetric(interface_index_, GetMetric(is_default));
if (is_default) {
resolver_->SetDNSFromLists(dns_servers_, dns_domain_search_);
@@ -91,4 +90,11 @@
is_default_ = is_default;
}
+uint32 Connection::GetMetric(bool is_default) {
+ // If this is not the default route, assign a metric based on the interface
+ // index. This way all non-default routes (even to the same gateway IP) end
+ // up with unique metrics so they do not collide.
+ return is_default ? kDefaultMetric : kNonDefaultMetricBase + interface_index_;
+}
+
} // namespace shill