shill: Set IPv6 privacy flags on discovered interfaces

Set the IPv6 "use_tempaddr" flag on newly discovered interfaces.
This allows the globally scoped IPv6 address to be disassociated
from the MAC address and reduce the ability for the host to
be tracked.  Although this parameter can be set on the interface
using /etc/sysctl.conf, the evaluation of this file does not
happen early enough to catch the first interfaces brought up
by shill.  Therefore we need to do write out these settings
at device-discovery time for shill.

BUG=chromium-os:16085
TEST=Manual -- observe IP address list, ensure netstat output on
client connected peer shows anonymized address.  Reran unit tests.

Change-Id: I6091ef9853f6be572e493cd4f964404944c93a44
Reviewed-on: http://gerrit.chromium.org/gerrit/6699
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index d147ae9..76877f6 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -17,6 +17,7 @@
 #include <string>
 
 #include <base/callback_old.h>
+#include <base/file_util.h>
 #include <base/logging.h>
 #include <base/memory/scoped_ptr.h>
 #include <base/stl_util-inl.h>
@@ -40,9 +41,9 @@
 namespace shill {
 
 // static
-const char *DeviceInfo::kInterfaceUevent= "/sys/class/net/%s/uevent";
+const char DeviceInfo::kInterfaceUevent[] = "/sys/class/net/%s/uevent";
 // static
-const char *DeviceInfo::kInterfaceDriver= "/sys/class/net/%s/device/driver";
+const char DeviceInfo::kInterfaceDriver[] = "/sys/class/net/%s/device/driver";
 // static
 const char *DeviceInfo::kModemDrivers[] = {
     "gobi",
@@ -50,6 +51,9 @@
     "GobiNet",
     NULL
 };
+// static
+const char DeviceInfo::kInterfaceIPv6Privacy[] =
+    "/proc/sys/net/ipv6/conf/%s/use_tempaddr";
 
 
 DeviceInfo::DeviceInfo(ControlInterface *control_interface,
@@ -182,10 +186,12 @@
                 << " ignored.";
         return;
       case Device::kEthernet:
+        EnableDeviceIPv6Privacy(link_name);
         device = new Ethernet(control_interface_, dispatcher_, manager_,
                               link_name, address, dev_index);
         break;
       case Device::kWifi:
+        EnableDeviceIPv6Privacy(link_name);
         device = new WiFi(control_interface_, dispatcher_, manager_,
                           link_name, address, dev_index);
         break;
@@ -262,4 +268,10 @@
   }
 }
 
+void DeviceInfo::EnableDeviceIPv6Privacy(const string &iface_name) {
+  FilePath priv_file(StringPrintf(kInterfaceIPv6Privacy, iface_name.c_str()));
+  LOG_IF(ERROR, file_util::WriteFile(priv_file, "2", 1))
+      << "Write failed for use_tempaddr: " << priv_file.value();
+}
+
 }  // namespace shill