shill: Connection: Create a link route if we are bound
Due to the behavior of some VPN servers, we may lose our route
to the default gateway of a physical interface due to the routes
assigned by a virtual interfaces. To avert this, set a host route
for the default gateway as we bind a lower connection.
BUG=chromium-os:32643
TEST=New unit tests; tried on a known-misbehaving net (actually
working from there right now); VPN autotests
Change-Id: I68db1da339f61c415f9ba8c2c26d8cdb0276b209
Reviewed-on: https://gerrit.chromium.org/gerrit/27705
Commit-Ready: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/routing_table.cc b/routing_table.cc
index 1b3f6db..7a3b002 100644
--- a/routing_table.cc
+++ b/routing_table.cc
@@ -533,4 +533,31 @@
return true;
}
+bool RoutingTable::CreateLinkRoute(int interface_index,
+ const IPAddress &local_address,
+ const IPAddress &remote_address) {
+ if (!local_address.CanReachAddress(remote_address)) {
+ LOG(ERROR) << __func__ << " failed: "
+ << remote_address.ToString() << " is not reachable from "
+ << local_address.ToString();
+ return false;
+ }
+
+ IPAddress default_address(local_address.family());
+ default_address.SetAddressToDefault();
+ IPAddress destination_address(remote_address);
+ destination_address.set_prefix(
+ IPAddress::GetMaxPrefixLength(remote_address.family()));
+ SLOG(Route, 2) << "Creating link route to " << destination_address.ToString()
+ << " from " << local_address.ToString()
+ << " on interface index " << interface_index;
+ return AddRoute(interface_index,
+ RoutingTableEntry(destination_address,
+ local_address,
+ default_address,
+ 0,
+ RT_SCOPE_LINK,
+ false));
+}
+
} // namespace shill