shill: connection: Use peer-to-peer if netmask is all-ones
Special case IP configurations where the netmask is set to
the "all-ones" address. Since this netmask indicates that
no other addresses should be reachable via broadcast domain,
this should imply that there is only a point-to-point link
with the gateway.
BUG=chrome-os-partner:10676
TEST=New unit test
Change-Id: I51f6cb8a1e71376f75be5122426172a6929e09d1
Reviewed-on: https://gerrit.chromium.org/gerrit/25910
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
diff --git a/connection.cc b/connection.cc
index 071ce8c..3f76578 100644
--- a/connection.cc
+++ b/connection.cc
@@ -274,16 +274,23 @@
<< " is unreachable from local address/prefix "
<< local->ToString() << "/" << local->prefix();
+ bool found_new_prefix = false;
size_t original_prefix = local->prefix();
- size_t prefix = original_prefix - 1;
- for (; prefix >= local->GetMinPrefixLength(); --prefix) {
- local->set_prefix(prefix);
- if (local->CanReachAddress(gateway)) {
- break;
+ // Only try to expand the netmask if the configured prefix is
+ // less than "all ones". This special-cases the "all-ones"
+ // prefix as a forced conversion to point-to-point networking.
+ if (local->prefix() < IPAddress::GetMaxPrefixLength(local->family())) {
+ size_t prefix = original_prefix - 1;
+ for (; prefix >= local->GetMinPrefixLength(); --prefix) {
+ local->set_prefix(prefix);
+ if (local->CanReachAddress(gateway)) {
+ found_new_prefix = true;
+ break;
+ }
}
}
- if (prefix < local->GetMinPrefixLength()) {
+ if (!found_new_prefix) {
// Restore the original prefix since we cannot find a better one.
local->set_prefix(original_prefix);
DCHECK(!peer->IsValid());
@@ -292,7 +299,8 @@
return true;
}
- LOG(WARNING) << "Mitigating this by setting local prefix to " << prefix;
+ LOG(WARNING) << "Mitigating this by setting local prefix to "
+ << local->prefix();
return true;
}