shill: deviceinfo: Mark all loopback devices up

We largely ignore loopback interfaces, but mark the link up.

BUG=chromium-os:29334
TEST=New unit test plus test on machine by setting lo down and starting shill

Change-Id: I46b7eb21280ff88ed935b940273901f334b78c4e
Reviewed-on: https://gerrit.chromium.org/gerrit/20023
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index 366f74f..a424a56 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -59,6 +59,8 @@
 // static
 const char DeviceInfo::kInterfaceType[] = "/sys/class/net/%s/type";
 // static
+const char DeviceInfo::kLoopbackDeviceName[] = "lo";
+// static
 const char *DeviceInfo::kModemDrivers[] = {
     "gobi",
     "QCUSBNet2k",
@@ -175,6 +177,11 @@
   if (!file_util::ReadSymbolicLink(driver_file, &driver_path)) {
     VLOG(2) << StringPrintf("%s: device %s has no device symlink",
                             __func__, iface_name.c_str());
+    if (iface_name == kLoopbackDeviceName) {
+      VLOG(2) << StringPrintf("%s: device %s is a loopback device",
+                              __func__, iface_name.c_str());
+      return Technology::kLoopback;
+    }
     FilePath tun_flags_file(StringPrintf(kInterfaceTunFlags,
                                          iface_name.c_str()));
     string tun_flags_string;
@@ -187,7 +194,7 @@
                               __func__, iface_name.c_str());
       return Technology::kTunnel;
     }
-     return Technology::kUnknown;
+    return Technology::kUnknown;
   }
 
   string driver_name(driver_path.BaseName().value());
@@ -284,6 +291,13 @@
           }
         }
         return;
+      case Technology::kLoopback:
+        // Loopback devices are largely ignored, but we should make sure the
+        // link is enabled.
+        VLOG(2) << "Bringing up loopback device " << link_name << " at index "
+                << dev_index;
+        rtnl_handler_->SetInterfaceFlags(dev_index, IFF_UP, IFF_UP);
+        return;
       default:
         device = new DeviceStub(control_interface_, dispatcher_, metrics_,
                                 manager_, link_name, address, dev_index,