shill: Add IP Address tracking to DeviceInfo

Subscribe to IP Address messages in DeviceInfo, and create a
per-device list of assigned IP Addresses.  Provide a method
to flush all globally scoped addresses from a device.

As a result, we can now flush assigned IP addresses when a
Connection is terminated.  There is also some incidental cleanup
in RTNLHandler to remove some vestiges of hand-baked RTNL
message encoding.

BUG=chromium-os:19744
TEST=Run new unit tests.  Test using ethernet on a netbook to make sure
addresses are added and removed correctly.

Change-Id: I63fd09088e71c43cb1f11a89a8ef15e11074976c
Reviewed-on: http://gerrit.chromium.org/gerrit/7180
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/connection_unittest.cc b/connection_unittest.cc
index 3b47af1..3111db7 100644
--- a/connection_unittest.cc
+++ b/connection_unittest.cc
@@ -2,18 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <arpa/inet.h>
+#include <linux/rtnetlink.h>
+
+#include <vector>
+
+#include <base/memory/scoped_ptr.h>
 #include <gtest/gtest.h>
 #include <gmock/gmock.h>
 
 #include "shill/connection.h"
-#include "shill/ip_address.h"
 #include "shill/ipconfig.h"
 #include "shill/mock_control.h"
+#include "shill/mock_device_info.h"
 #include "shill/mock_resolver.h"
 #include "shill/mock_routing_table.h"
 #include "shill/mock_rtnl_handler.h"
 #include "shill/routing_table_entry.h"
 
+using std::vector;
 using testing::_;
 using testing::NiceMock;
 using testing::Return;
@@ -29,6 +36,7 @@
 const int kTestDeviceInterfaceIndex1 = 321;
 const char kIPAddress0[] = "192.168.1.1";
 const char kGatewayAddress0[] = "192.168.1.254";
+const char kBroadcastAddress0[] = "192.168.1.255";
 const char kNameServer0[] = "8.8.8.8";
 const char kNameServer1[] = "8.8.9.9";
 const char kSearchDomain0[] = "chromium.org";
@@ -38,8 +46,14 @@
 class ConnectionTest : public Test {
  public:
   ConnectionTest()
-      : connection_(
-            new Connection(kTestDeviceInterfaceIndex0, kTestDeviceName0)),
+      : device_info_(new StrictMock<MockDeviceInfo>(
+            &control_,
+            static_cast<EventDispatcher*>(NULL),
+            static_cast<Manager*>(NULL))),
+        connection_(new Connection(
+            kTestDeviceInterfaceIndex0,
+            kTestDeviceName0,
+            device_info_.get())),
         ipconfig_(new IPConfig(&control_, kTestDeviceName0)) {}
 
   virtual void SetUp() {
@@ -50,6 +64,7 @@
     IPConfig::Properties properties;
     properties.address = kIPAddress0;
     properties.gateway = kGatewayAddress0;
+    properties.broadcast_address = kBroadcastAddress0;
     properties.dns_servers.push_back(kNameServer0);
     properties.dns_servers.push_back(kNameServer1);
     properties.domain_search.push_back(kSearchDomain0);
@@ -58,7 +73,12 @@
     ipconfig_->UpdateProperties(properties, true);
   }
 
+  virtual void TearDown() {
+    EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex0));
+  }
+
  protected:
+  scoped_ptr<StrictMock<MockDeviceInfo> > device_info_;
   ConnectionRefPtr connection_;
   MockControl control_;
   IPConfigRefPtr ipconfig_;
@@ -75,7 +95,7 @@
 
 TEST_F(ConnectionTest, AddConfig) {
   EXPECT_CALL(rtnl_handler_,
-              AddInterfaceAddress(kTestDeviceInterfaceIndex0, _));
+              AddInterfaceAddress(kTestDeviceInterfaceIndex0, _, _));
   EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
                                              ipconfig_,
                                              Connection::kNonDefaultMetric));
@@ -99,12 +119,12 @@
 TEST_F(ConnectionTest, AddConfigReverse) {
   EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
                                                Connection::kDefaultMetric));
-  std::vector<std::string> empty_list;
+  vector<std::string> empty_list;
   EXPECT_CALL(resolver_, SetDNSFromLists(empty_list, empty_list));
   connection_->SetDefault(true);
 
   EXPECT_CALL(rtnl_handler_,
-              AddInterfaceAddress(kTestDeviceInterfaceIndex0, _));
+              AddInterfaceAddress(kTestDeviceInterfaceIndex0, _, _));
   EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
                                              ipconfig_,
                                              Connection::kDefaultMetric));
@@ -115,9 +135,11 @@
 
 TEST_F(ConnectionTest, Destructor) {
   EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex1));
+  EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex1));
   {
     ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
-                                               kTestDeviceName1));
+                                               kTestDeviceName1,
+                                               device_info_.get()));
     connection->resolver_ = &resolver_;
     connection->routing_table_ = &routing_table_;
     connection->rtnl_handler_ = &rtnl_handler_;