Home | History | Annotate | Download | only in shill
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "shill/connection.h"
     18 
     19 #include <arpa/inet.h>
     20 #include <linux/rtnetlink.h>
     21 
     22 #include <set>
     23 
     24 #include <base/strings/stringprintf.h>
     25 
     26 #include "shill/control_interface.h"
     27 #include "shill/device_info.h"
     28 #include "shill/firewall_proxy_interface.h"
     29 #include "shill/logging.h"
     30 #include "shill/net/rtnl_handler.h"
     31 #include "shill/routing_table.h"
     32 
     33 #if !defined(__ANDROID__)
     34 #include "shill/resolver.h"
     35 #else
     36 #include "shill/dns_server_proxy.h"
     37 #include "shill/dns_server_proxy_factory.h"
     38 #endif  // __ANDROID__
     39 
     40 using base::Bind;
     41 using base::Closure;
     42 using base::Unretained;
     43 using std::deque;
     44 using std::set;
     45 using std::string;
     46 using std::vector;
     47 
     48 namespace shill {
     49 
     50 namespace Logging {
     51 static auto kModuleLogScope = ScopeLogger::kConnection;
     52 static string ObjectID(Connection* c) {
     53   if (c == nullptr)
     54     return "(connection)";
     55   return c->interface_name();
     56 }
     57 }
     58 
     59 #if defined(__ANDROID__)
     60 namespace {
     61 const char* kGoogleDNSServers[] = {
     62     "8.8.4.4",
     63     "8.8.8.8"
     64 };
     65 }  // namespace
     66 #endif  // __ANDROID__
     67 
     68 // static
     69 const uint32_t Connection::kDefaultMetric = 1;
     70 // static
     71 const uint32_t Connection::kNonDefaultMetricBase = 10;
     72 // static
     73 const uint32_t Connection::kMarkForUserTraffic = 0x1;
     74 // static
     75 const uint8_t Connection::kSecondaryTableId = 0x1;
     76 
     77 Connection::Binder::Binder(const string& name,
     78                            const Closure& disconnect_callback)
     79     : name_(name),
     80       client_disconnect_callback_(disconnect_callback) {}
     81 
     82 Connection::Binder::~Binder() {
     83   Attach(nullptr);
     84 }
     85 
     86 void Connection::Binder::Attach(const ConnectionRefPtr& to_connection) {
     87   if (connection_) {
     88     connection_->DetachBinder(this);
     89     LOG(INFO) << name_ << ": unbound from connection: "
     90               << connection_->interface_name();
     91     connection_.reset();
     92   }
     93   if (to_connection) {
     94     connection_ = to_connection->weak_ptr_factory_.GetWeakPtr();
     95     connection_->AttachBinder(this);
     96     LOG(INFO) << name_ << ": bound to connection: "
     97               << connection_->interface_name();
     98   }
     99 }
    100 
    101 void Connection::Binder::OnDisconnect() {
    102   LOG(INFO) << name_ << ": bound connection disconnected: "
    103             << connection_->interface_name();
    104   connection_.reset();
    105   if (!client_disconnect_callback_.is_null()) {
    106     SLOG(connection_.get(), 2) << "Running client disconnect callback.";
    107     client_disconnect_callback_.Run();
    108   }
    109 }
    110 
    111 Connection::Connection(int interface_index,
    112                        const std::string& interface_name,
    113                        Technology::Identifier technology,
    114                        const DeviceInfo* device_info,
    115                        ControlInterface* control_interface)
    116     : weak_ptr_factory_(this),
    117       is_default_(false),
    118       has_broadcast_domain_(false),
    119       routing_request_count_(0),
    120       interface_index_(interface_index),
    121       interface_name_(interface_name),
    122       technology_(technology),
    123       user_traffic_only_(false),
    124       table_id_(RT_TABLE_MAIN),
    125       local_(IPAddress::kFamilyUnknown),
    126       gateway_(IPAddress::kFamilyUnknown),
    127       lower_binder_(
    128           interface_name_,
    129           // Connection owns a single instance of |lower_binder_| so it's safe
    130           // to use an Unretained callback.
    131           Bind(&Connection::OnLowerDisconnect, Unretained(this))),
    132       device_info_(device_info),
    133 #if !defined(__ANDROID__)
    134       resolver_(Resolver::GetInstance()),
    135 #else
    136       dns_server_proxy_factory_(DNSServerProxyFactory::GetInstance()),
    137 #endif  // __ANDROID__
    138       routing_table_(RoutingTable::GetInstance()),
    139       rtnl_handler_(RTNLHandler::GetInstance()),
    140       control_interface_(control_interface) {
    141   SLOG(this, 2) << __func__ << "(" << interface_index << ", "
    142                 << interface_name << ", "
    143                 << Technology::NameFromIdentifier(technology) << ")";
    144 }
    145 
    146 Connection::~Connection() {
    147   SLOG(this, 2) << __func__ << " " << interface_name_;
    148 
    149   NotifyBindersOnDisconnect();
    150 
    151   DCHECK(!routing_request_count_);
    152   routing_table_->FlushRoutes(interface_index_);
    153   routing_table_->FlushRoutesWithTag(interface_index_);
    154   device_info_->FlushAddresses(interface_index_);
    155   TearDownIptableEntries();
    156 }
    157 
    158 void Connection::UpdateFromIPConfig(const IPConfigRefPtr& config) {
    159   SLOG(this, 2) << __func__ << " " << interface_name_;
    160 
    161   const IPConfig::Properties& properties = config->properties();
    162   user_traffic_only_ = properties.user_traffic_only;
    163   table_id_ = user_traffic_only_ ? kSecondaryTableId : (uint8_t)RT_TABLE_MAIN;
    164 
    165   IPAddress gateway(properties.address_family);
    166   if (!properties.gateway.empty() &&
    167       !gateway.SetAddressFromString(properties.gateway)) {
    168     LOG(ERROR) << "Gateway address " << properties.gateway << " is invalid";
    169     return;
    170   }
    171 
    172   excluded_ips_cidr_ = properties.exclusion_list;
    173 
    174   IPAddress trusted_ip(properties.address_family);
    175   if (!excluded_ips_cidr_.empty()) {
    176     const std::string first_excluded_ip = excluded_ips_cidr_[0];
    177     excluded_ips_cidr_.erase(excluded_ips_cidr_.begin());
    178     // A VPN connection can currently be bound to exactly one lower connection
    179     // such as eth0 or wan0. The excluded IPs are pinned to the gateway of
    180     // that connection. Setting up the routing table this way ensures that when
    181     // the lower connection goes offline, the associated entries in the routing
    182     // table are removed. On the flip side, when there are multiple connections
    183     // such as eth0 and wan0 and some IPs can be reached quickly over one
    184     // connection and the others over a different connection, all routes are
    185     // still pinned to a connection.
    186     //
    187     // The optimal connection to reach the first excluded IP is found below.
    188     // When this is found the route for the remaining excluded IPs are pinned in
    189     // the method PinPendingRoutes below.
    190     if (!trusted_ip.SetAddressAndPrefixFromString(first_excluded_ip)) {
    191       LOG(ERROR) << "Trusted IP address "
    192                  << first_excluded_ip << " is invalid";
    193       return;
    194     }
    195     if (!PinHostRoute(trusted_ip, gateway)) {
    196       LOG(ERROR) << "Unable to pin host route to " << first_excluded_ip;
    197       return;
    198     }
    199   }
    200 
    201   IPAddress local(properties.address_family);
    202   if (!local.SetAddressFromString(properties.address)) {
    203     LOG(ERROR) << "Local address " << properties.address << " is invalid";
    204     return;
    205   }
    206   local.set_prefix(properties.subnet_prefix);
    207 
    208   IPAddress broadcast(properties.address_family);
    209   if (properties.broadcast_address.empty()) {
    210     if (properties.peer_address.empty()) {
    211       LOG(WARNING) << "Broadcast address is not set.  Using default.";
    212       broadcast = local.GetDefaultBroadcast();
    213     }
    214   } else if (!broadcast.SetAddressFromString(properties.broadcast_address)) {
    215     LOG(ERROR) << "Broadcast address " << properties.broadcast_address
    216                << " is invalid";
    217     return;
    218   }
    219 
    220   IPAddress peer(properties.address_family);
    221   if (!properties.peer_address.empty() &&
    222       !peer.SetAddressFromString(properties.peer_address)) {
    223     LOG(ERROR) << "Peer address " << properties.peer_address
    224                << " is invalid";
    225     return;
    226   }
    227 
    228   if (!FixGatewayReachability(local, &peer, &gateway, trusted_ip)) {
    229     LOG(WARNING) << "Expect limited network connectivity.";
    230   }
    231 
    232   if (device_info_->HasOtherAddress(interface_index_, local)) {
    233     // The address has changed for this interface.  We need to flush
    234     // everything and start over.
    235     LOG(INFO) << __func__ << ": Flushing old addresses and routes.";
    236     routing_table_->FlushRoutes(interface_index_);
    237     device_info_->FlushAddresses(interface_index_);
    238   }
    239 
    240   LOG(INFO) << __func__ << ": Installing with parameters:"
    241             << " local=" << local.ToString()
    242             << " broadcast=" << broadcast.ToString()
    243             << " peer=" << peer.ToString()
    244             << " gateway=" << gateway.ToString();
    245   rtnl_handler_->AddInterfaceAddress(interface_index_, local, broadcast, peer);
    246 
    247   if (gateway.IsValid() && properties.default_route) {
    248     routing_table_->SetDefaultRoute(interface_index_, gateway,
    249                                     GetMetric(is_default_),
    250                                     table_id_);
    251   }
    252 
    253   if (user_traffic_only_) {
    254     SetupIptableEntries();
    255   }
    256 
    257   // Install any explicitly configured routes at the default metric.
    258   routing_table_->ConfigureRoutes(interface_index_, config, kDefaultMetric,
    259                                   table_id_);
    260 
    261   SetMTU(properties.mtu);
    262 
    263   if (properties.blackhole_ipv6) {
    264     routing_table_->CreateBlackholeRoute(interface_index_,
    265                                          IPAddress::kFamilyIPv6,
    266                                          kDefaultMetric,
    267                                          table_id_);
    268   }
    269 
    270   // Save a copy of the last non-null DNS config.
    271   if (!config->properties().dns_servers.empty()) {
    272     dns_servers_ = config->properties().dns_servers;
    273   }
    274 
    275 #if defined(__ANDROID__)
    276   // Default to Google's DNS server if it is not provided through DHCP.
    277   if (config->properties().dns_servers.empty()) {
    278     LOG(INFO) << "Default to use Google DNS servers";
    279     dns_servers_ =
    280         vector<string>(std::begin(kGoogleDNSServers),
    281                        std::end(kGoogleDNSServers));
    282   }
    283 #endif  // __ANDROID__
    284 
    285   if (!config->properties().domain_search.empty()) {
    286     dns_domain_search_ = config->properties().domain_search;
    287   }
    288 
    289   if (!config->properties().domain_name.empty()) {
    290     dns_domain_name_ = config->properties().domain_name;
    291   }
    292 
    293   ipconfig_rpc_identifier_ = config->GetRpcIdentifier();
    294 
    295   PushDNSConfig();
    296 
    297   local_ = local;
    298   gateway_ = gateway;
    299   has_broadcast_domain_ = !peer.IsValid();
    300 }
    301 
    302 bool Connection::SetupIptableEntries() {
    303   if (!firewall_proxy_) {
    304     firewall_proxy_.reset(control_interface_->CreateFirewallProxy());
    305   }
    306 
    307   std::vector<std::string> user_names;
    308   user_names.push_back("chronos");
    309   user_names.push_back("debugd");
    310 
    311   if (!firewall_proxy_->RequestVpnSetup(user_names, interface_name_)) {
    312     LOG(ERROR) << "VPN iptables setup request failed.";
    313     return false;
    314   }
    315 
    316   return true;
    317 }
    318 
    319 bool Connection::TearDownIptableEntries() {
    320   return firewall_proxy_ ? firewall_proxy_->RemoveVpnSetup() : true;
    321 }
    322 
    323 void Connection::SetIsDefault(bool is_default) {
    324   SLOG(this, 2) << __func__ << " " << interface_name_
    325                 << " (index " << interface_index_ << ") "
    326                 << is_default_ << " -> " << is_default;
    327   if (is_default == is_default_) {
    328     return;
    329   }
    330 
    331   routing_table_->SetDefaultMetric(interface_index_, GetMetric(is_default));
    332 
    333   is_default_ = is_default;
    334 
    335   PushDNSConfig();
    336   if (is_default) {
    337     DeviceRefPtr device = device_info_->GetDevice(interface_index_);
    338     if (device) {
    339       device->RequestPortalDetection();
    340     }
    341   }
    342   routing_table_->FlushCache();
    343 }
    344 
    345 void Connection::UpdateDNSServers(const vector<string>& dns_servers) {
    346   dns_servers_ = dns_servers;
    347   PushDNSConfig();
    348 }
    349 
    350 void Connection::PushDNSConfig() {
    351   if (!is_default_) {
    352 #if defined(__ANDROID__)
    353     // Stop DNS server proxy to avoid having multiple instances of it running.
    354     // Only run DNS server proxy for the current default connection.
    355     dns_server_proxy_.reset();
    356 #endif  // __ANDROID__
    357     return;
    358   }
    359 
    360   vector<string> domain_search = dns_domain_search_;
    361   if (domain_search.empty() && !dns_domain_name_.empty()) {
    362     SLOG(this, 2) << "Setting domain search to domain name "
    363                   << dns_domain_name_;
    364     domain_search.push_back(dns_domain_name_ + ".");
    365   }
    366 #if !defined(__ANDROID__)
    367   resolver_->SetDNSFromLists(dns_servers_, domain_search);
    368 #else
    369   dns_server_proxy_.reset(
    370       dns_server_proxy_factory_->CreateDNSServerProxy(dns_servers_));
    371   dns_server_proxy_->Start();
    372 #endif  // __ANDROID__
    373 }
    374 
    375 void Connection::RequestRouting() {
    376   if (routing_request_count_++ == 0) {
    377     DeviceRefPtr device = device_info_->GetDevice(interface_index_);
    378     DCHECK(device.get());
    379     if (!device.get()) {
    380       LOG(ERROR) << "Device is NULL!";
    381       return;
    382     }
    383     device->SetLooseRouting(true);
    384   }
    385 }
    386 
    387 void Connection::ReleaseRouting() {
    388   DCHECK_GT(routing_request_count_, 0);
    389   if (--routing_request_count_ == 0) {
    390     DeviceRefPtr device = device_info_->GetDevice(interface_index_);
    391     DCHECK(device.get());
    392     if (!device.get()) {
    393       LOG(ERROR) << "Device is NULL!";
    394       return;
    395     }
    396     device->SetLooseRouting(false);
    397 
    398     // Clear any cached routes that might have accumulated while reverse-path
    399     // filtering was disabled.
    400     routing_table_->FlushCache();
    401   }
    402 }
    403 
    404 bool Connection::RequestHostRoute(const IPAddress& address) {
    405   // Do not set interface_index_ since this may not be the default route through
    406   // which this destination can be found.  However, we should tag the created
    407   // route with our interface index so we can clean this route up when this
    408   // connection closes.  Also, add route query callback to determine the lower
    409   // connection and bind to it.
    410   if (!routing_table_->RequestRouteToHost(
    411           address,
    412           -1,
    413           interface_index_,
    414           Bind(&Connection::OnRouteQueryResponse,
    415                weak_ptr_factory_.GetWeakPtr()),
    416           table_id_)) {
    417     LOG(ERROR) << "Could not request route to " << address.ToString();
    418     return false;
    419   }
    420 
    421   return true;
    422 }
    423 
    424 bool Connection::PinPendingRoutes(int interface_index,
    425                                   RoutingTableEntry entry) {
    426   // The variable entry is locally modified, hence is passed by value in the
    427   // second argument above.
    428   for (auto excluded_ip = excluded_ips_cidr_.begin();
    429        excluded_ip != excluded_ips_cidr_.end(); ++excluded_ip) {
    430     if (!entry.dst.SetAddressAndPrefixFromString(*excluded_ip) ||
    431         !entry.dst.IsValid() ||
    432         !routing_table_->AddRoute(interface_index, entry)) {
    433       LOG(ERROR) << "Unable to setup route for " << *excluded_ip << ".";
    434     }
    435   }
    436 
    437   return true;
    438 }
    439 
    440 string Connection::GetSubnetName() const {
    441   if (!local().IsValid()) {
    442     return "";
    443   }
    444   return base::StringPrintf("%s/%d",
    445                             local().GetNetworkPart().ToString().c_str(),
    446                             local().prefix());
    447 }
    448 
    449 bool Connection::FixGatewayReachability(const IPAddress& local,
    450                                         IPAddress* peer,
    451                                         IPAddress* gateway,
    452                                         const IPAddress& trusted_ip) {
    453   SLOG(nullptr, 2) << __func__
    454       << " local " << local.ToString()
    455       << ", peer " << peer->ToString()
    456       << ", gateway " << gateway->ToString()
    457       << ", trusted_ip " << trusted_ip.ToString();
    458   if (!gateway->IsValid()) {
    459     LOG(WARNING) << "No gateway address was provided for this connection.";
    460     return false;
    461   }
    462 
    463   if (peer->IsValid()) {
    464     if (!gateway->HasSameAddressAs(*peer)) {
    465       LOG(WARNING) << "Gateway address "
    466                    << gateway->ToString()
    467                    << " does not match peer address "
    468                    << peer->ToString();
    469       return false;
    470     }
    471     if (gateway->HasSameAddressAs(trusted_ip)) {
    472       // In order to send outgoing traffic in a point-to-point network,
    473       // the gateway IP address isn't of significance.  As opposed to
    474       // broadcast networks, we never ARP for the gateway IP address,
    475       // but just send the IP packet addressed to the recipient.  As
    476       // such, since using the external trusted IP address as the
    477       // gateway or peer wreaks havoc on the routing rules, we choose
    478       // not to supply a gateway address.  Here's an example:
    479       //
    480       //     Client    <->  Internet  <->  VPN Gateway  <->  Internal Network
    481       //   192.168.1.2                      10.0.1.25         172.16.5.0/24
    482       //
    483       // In this example, a client connects to a VPN gateway on its
    484       // public IP address 10.0.1.25.  It gets issued an IP address
    485       // from the VPN internal pool.  For some VPN gateways, this
    486       // results in a pushed-down PPP configuration which specifies:
    487       //
    488       //    Client local address:   172.16.5.13
    489       //    Client peer address:    10.0.1.25
    490       //    Client default gateway: 10.0.1.25
    491       //
    492       // If we take this literally, we need to resolve the fact that
    493       // 10.0.1.25 is now listed as the default gateway and interface
    494       // peer address for the point-to-point interface.  However, in
    495       // order to route tunneled packets to the VPN gateway we must
    496       // use the external route through the physical interface and
    497       // not the tunnel, or else we end up in an infinite loop
    498       // re-entering the tunnel trying to route towards the VPN server.
    499       //
    500       // We can do this by pinning a route, but we would need to wait
    501       // for the pinning process to complete before assigning this
    502       // address.  Currently this process is asynchronous and will
    503       // complete only after returning to the event loop.  Additionally,
    504       // since there's no metric associated with assigning an address
    505       // to an interface, it's always possible that having the peer
    506       // address of the interface might still trump a host route.
    507       //
    508       // To solve this problem, we reset the peer and gateway
    509       // addresses.  Neither is required in order to perform the
    510       // underlying routing task.  A gateway route can be specified
    511       // without an IP endpoint on point-to-point links, and simply
    512       // specify the outbound interface index.  Similarly, a peer
    513       // IP address is not necessary either, and will be assigned
    514       // the same IP address as the local IP.  This approach
    515       // simplifies routing and doesn't change the desired
    516       // functional behavior.
    517       //
    518       LOG(INFO) << "Removing gateway and peer addresses to preserve "
    519                 << "routability to trusted IP address.";
    520       peer->SetAddressToDefault();
    521       gateway->SetAddressToDefault();
    522     }
    523     return true;
    524   }
    525 
    526   if (local.CanReachAddress(*gateway)) {
    527     return true;
    528   }
    529 
    530   LOG(WARNING) << "Gateway "
    531                << gateway->ToString()
    532                << " is unreachable from local address/prefix "
    533                << local.ToString() << "/" << local.prefix();
    534 
    535   IPAddress gateway_with_max_prefix(*gateway);
    536   gateway_with_max_prefix.set_prefix(
    537       IPAddress::GetMaxPrefixLength(gateway_with_max_prefix.family()));
    538   IPAddress default_address(gateway->family());
    539   RoutingTableEntry entry(gateway_with_max_prefix,
    540                           default_address,
    541                           default_address,
    542                           0,
    543                           RT_SCOPE_LINK,
    544                           false,
    545                           table_id_,
    546                           RoutingTableEntry::kDefaultTag);
    547 
    548   if (!routing_table_->AddRoute(interface_index_, entry)) {
    549     LOG(ERROR) << "Unable to add link-scoped route to gateway.";
    550     return false;
    551   }
    552 
    553   LOG(WARNING) << "Mitigating this by creating a link route to the gateway.";
    554 
    555   return true;
    556 }
    557 
    558 uint32_t Connection::GetMetric(bool is_default) {
    559   // If this is not the default route, assign a metric based on the interface
    560   // index.  This way all non-default routes (even to the same gateway IP) end
    561   // up with unique metrics so they do not collide.
    562   return is_default ? kDefaultMetric : kNonDefaultMetricBase + interface_index_;
    563 }
    564 
    565 bool Connection::PinHostRoute(const IPAddress& trusted_ip,
    566                               const IPAddress& gateway) {
    567   SLOG(this, 2) << __func__;
    568   if (!trusted_ip.IsValid()) {
    569     LOG(ERROR) << "No trusted IP -- unable to pin host route.";
    570     return false;
    571   }
    572 
    573   if (!gateway.IsValid()) {
    574     // Although we cannot pin a host route, we are also not going to create
    575     // a gateway route that will interfere with our primary connection, so
    576     // it is okay to return success here.
    577     LOG(WARNING) << "No gateway -- unable to pin host route.";
    578     return true;
    579   }
    580 
    581   return RequestHostRoute(trusted_ip);
    582 }
    583 
    584 void Connection::SetMTU(int32_t mtu) {
    585   SLOG(this, 2) << __func__ << " " << mtu;
    586   // Make sure the MTU value is valid.
    587   if (mtu == IPConfig::kUndefinedMTU) {
    588     mtu = IPConfig::kDefaultMTU;
    589   } else {
    590     int min_mtu = IsIPv6() ? IPConfig::kMinIPv6MTU : IPConfig::kMinIPv4MTU;
    591     if (mtu < min_mtu) {
    592       SLOG(this, 2) << __func__ << " MTU " << mtu
    593                     << " is too small; adjusting up to " << min_mtu;
    594       mtu = min_mtu;
    595     }
    596   }
    597 
    598   rtnl_handler_->SetInterfaceMTU(interface_index_, mtu);
    599 }
    600 
    601 void Connection::OnRouteQueryResponse(int interface_index,
    602                                       const RoutingTableEntry& entry) {
    603   SLOG(this, 2) << __func__ << "(" << interface_index << ", "
    604                 << entry.tag << ")" << " @ " << interface_name_;
    605   lower_binder_.Attach(nullptr);
    606   DeviceRefPtr device = device_info_->GetDevice(interface_index);
    607   if (!device) {
    608     LOG(ERROR) << "Unable to lookup device for index " << interface_index;
    609     return;
    610   }
    611   ConnectionRefPtr connection = device->connection();
    612   if (!connection) {
    613     LOG(ERROR) << "Device " << interface_index << " has no connection.";
    614     return;
    615   }
    616   if (connection == this) {
    617     LOG(ERROR) << "Avoiding a connection bind loop for " << interface_name();
    618     return;
    619   }
    620   lower_binder_.Attach(connection);
    621   connection->CreateGatewayRoute();
    622   device->OnConnectionUpdated();
    623   PinPendingRoutes(interface_index, entry);
    624 }
    625 
    626 bool Connection::CreateGatewayRoute() {
    627   // Ensure that the gateway for the lower connection remains reachable,
    628   // since we may create routes that conflict with it.
    629   if (!has_broadcast_domain_) {
    630     return false;
    631   }
    632 
    633   // If there is no gateway, don't try to create a route to it.
    634   if (!gateway_.IsValid()) {
    635     return false;
    636   }
    637 
    638   // It is not worth keeping track of this route, since it is benign,
    639   // and only pins persistent state that was already true of the connection.
    640   // If DHCP parameters change later (without the connection having been
    641   // destroyed and recreated), the binding processes will likely terminate
    642   // and restart, causing a new link route to be created.
    643   return routing_table_->CreateLinkRoute(interface_index_, local_, gateway_,
    644                                          table_id_);
    645 }
    646 
    647 void Connection::OnLowerDisconnect() {
    648   SLOG(this, 2) << __func__ << " @ " << interface_name_;
    649   // Ensures that |this| instance doesn't get destroyed in the middle of
    650   // notifying the binders. This method needs to be separate from
    651   // NotifyBindersOnDisconnect because the latter may be invoked by Connection's
    652   // destructor when |this| instance's reference count is already 0.
    653   ConnectionRefPtr connection(this);
    654   connection->NotifyBindersOnDisconnect();
    655 }
    656 
    657 void Connection::NotifyBindersOnDisconnect() {
    658   // Note that this method may be invoked by the destructor.
    659   SLOG(this, 2) << __func__ << " @ " << interface_name_;
    660 
    661   // Unbinds the lower connection before notifying the binders. This ensures
    662   // correct behavior in case of circular binding.
    663   lower_binder_.Attach(nullptr);
    664   while (!binders_.empty()) {
    665     // Pop the binder first and then notify it to ensure that each binder is
    666     // notified only once.
    667     Binder* binder = binders_.front();
    668     binders_.pop_front();
    669     binder->OnDisconnect();
    670   }
    671 }
    672 
    673 void Connection::AttachBinder(Binder* binder) {
    674   SLOG(this, 2) << __func__ << "(" << binder->name() << ")" << " @ "
    675                             << interface_name_;
    676   binders_.push_back(binder);
    677 }
    678 
    679 void Connection::DetachBinder(Binder* binder) {
    680   SLOG(this, 2) << __func__ << "(" << binder->name() << ")" << " @ "
    681                             << interface_name_;
    682   for (auto it = binders_.begin(); it != binders_.end(); ++it) {
    683     if (binder == *it) {
    684       binders_.erase(it);
    685       return;
    686     }
    687   }
    688 }
    689 
    690 ConnectionRefPtr Connection::GetCarrierConnection() {
    691   SLOG(this, 2) << __func__ << " @ " << interface_name_;
    692   set<Connection*> visited;
    693   ConnectionRefPtr carrier = this;
    694   while (carrier->GetLowerConnection()) {
    695     if (ContainsKey(visited, carrier.get())) {
    696       LOG(ERROR) << "Circular connection chain starting at: "
    697                  << carrier->interface_name();
    698       // If a loop is detected return a NULL value to signal that the carrier
    699       // connection is unknown.
    700       return nullptr;
    701     }
    702     visited.insert(carrier.get());
    703     carrier = carrier->GetLowerConnection();
    704   }
    705   SLOG(this, 2) << "Carrier connection: " << carrier->interface_name()
    706                 << " @ " << interface_name_;
    707   return carrier;
    708 }
    709 
    710 bool Connection::IsIPv6() {
    711   return local_.family() == IPAddress::kFamilyIPv6;
    712 }
    713 
    714 }  // namespace shill
    715