shill: vpn: Create a VPN device for L2TP/IPSec and apply IP configuration.

Also, implement a new DeviceInfo API for retrieving the interface
index based on the interface name.

BUG=chromium-os:18496,chromium-os:29912
TEST=unit tests

Change-Id: I7d9e667d2c63baa96ed2b01dfa580de7d361b5f3
Reviewed-on: https://gerrit.chromium.org/gerrit/20931
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index d153ade..21e1d6b 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -339,6 +339,8 @@
     ByteString b(msg.GetAttribute(IFLA_IFNAME));
     string link_name(reinterpret_cast<const char*>(b.GetConstData()));
     SLOG(Device, 2) << "add link index "  << dev_index << " name " << link_name;
+    infos_[dev_index].name = link_name;
+    indices_[link_name] = dev_index;
 
     if (!link_name.empty()) {
       if (ContainsKey(black_list_, link_name)) {
@@ -435,6 +437,11 @@
   return info ? info->device : NULL;
 }
 
+int DeviceInfo::GetIndex(const string &interface_name) const {
+  map<string, int>::const_iterator it = indices_.find(interface_name);
+  return it == indices_.end() ? -1 : it->second;
+}
+
 bool DeviceInfo::GetMACAddress(int interface_index, ByteString *address) const {
   const Info *info = GetInfo(interface_index);
   if (!info) {
@@ -527,6 +534,7 @@
     if (iter->second.device.get()) {
       manager_->DeregisterDevice(iter->second.device);
     }
+    indices_.erase(iter->second.name);
     infos_.erase(iter);
   } else {
     SLOG(Device, 2) << __func__ << ": Unknown device index: "