shill: connection: Allow missing broadcast

Teunnel interfaces do not have a broadcast address since they
are p-t-p.  Hand the Connection object a technology identifier
so it can make such decisions.  We may need to explore polymorphism
in the future if decisions of this sort become more prevalent.

BUG=chromium-os:27929
TEST=Unit tests

Change-Id: I1a81d010c60319015bf0ac690baf3edb62a39cdf
Reviewed-on: https://gerrit.chromium.org/gerrit/18361
Reviewed-by: Darin Petkov <petkov@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 cab4bd2..d34f547 100644
--- a/connection.cc
+++ b/connection.cc
@@ -23,11 +23,13 @@
 
 Connection::Connection(int interface_index,
                        const std::string& interface_name,
+                       Technology::Identifier technology,
                        const DeviceInfo *device_info)
     : is_default_(false),
       routing_request_count_(0),
       interface_index_(interface_index),
       interface_name_(interface_name),
+      technology_(technology),
       device_info_(device_info),
       resolver_(Resolver::GetInstance()),
       routing_table_(RoutingTable::GetInstance()),
@@ -55,7 +57,8 @@
   local.set_prefix(properties.subnet_cidr);
 
   IPAddress broadcast(properties.address_family);
-  if (!broadcast.SetAddressFromString(properties.broadcast_address)) {
+  if (!broadcast.SetAddressFromString(properties.broadcast_address) &&
+      technology_ != Technology::kTunnel) {
     LOG(ERROR) << "Broadcast address " << properties.broadcast_address
                << " is invalid";
     return;
diff --git a/connection.h b/connection.h
index a2e4374..fc81171 100644
--- a/connection.h
+++ b/connection.h
@@ -12,6 +12,7 @@
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include "shill/refptr_types.h"
+#include "shill/technology.h"
 
 namespace shill {
 
@@ -27,6 +28,7 @@
  public:
   Connection(int interface_index,
              const std::string &interface_name,
+             Technology::Identifier technology_,
              const DeviceInfo *device_info);
   virtual ~Connection();
 
@@ -69,6 +71,7 @@
   int routing_request_count_;
   int interface_index_;
   const std::string interface_name_;
+  Technology::Identifier technology_;
   std::vector<std::string> dns_servers_;
   std::vector<std::string> dns_domain_search_;
 
diff --git a/connection_unittest.cc b/connection_unittest.cc
index d43bd69..728f347 100644
--- a/connection_unittest.cc
+++ b/connection_unittest.cc
@@ -57,6 +57,7 @@
         connection_(new Connection(
             kTestDeviceInterfaceIndex0,
             kTestDeviceName0,
+            Technology::kUnknown,
             device_info_.get())),
         ipconfig_(new IPConfig(&control_, kTestDeviceName0)) {}
 
@@ -180,6 +181,7 @@
 TEST_F(ConnectionTest, RouteRequest) {
   ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
                                              kTestDeviceName0,
+                                             Technology::kUnknown,
                                              device_info_.get()));
   ReplaceSingletons(connection);
   scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
@@ -216,6 +218,7 @@
   {
     ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
                                                kTestDeviceName1,
+                                               Technology::kUnknown,
                                                device_info_.get()));
     connection->resolver_ = &resolver_;
     connection->routing_table_ = &routing_table_;
@@ -232,6 +235,7 @@
 TEST_F(ConnectionTest, RequestHostRoute) {
   ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
                                              kTestDeviceName0,
+                                             Technology::kUnknown,
                                              device_info_.get()));
   ReplaceSingletons(connection);
   IPAddress address(IPAddress::kFamilyIPv4);
diff --git a/device.cc b/device.cc
index d2be40e..2042c5d 100644
--- a/device.cc
+++ b/device.cc
@@ -384,6 +384,7 @@
   if (!connection_.get()) {
     connection_ = new Connection(interface_index_,
                                  link_name_,
+                                 technology_,
                                  manager_->device_info());
   }
 }
diff --git a/mock_connection.cc b/mock_connection.cc
index 6715994..4648fa4 100644
--- a/mock_connection.cc
+++ b/mock_connection.cc
@@ -9,7 +9,7 @@
 namespace shill {
 
 MockConnection::MockConnection(const DeviceInfo *device_info)
-    : Connection(0, std::string(), device_info) {}
+    : Connection(0, std::string(), Technology::kUnknown, device_info) {}
 
 MockConnection::~MockConnection() {}