shill: vpn: Claim interface from DeviceInfo

Maintain a list in the VPNProvider of all services created by it.
When DeviceInfo alerts it of a new tunnel interface, VPNProvider
will find a service->driver() to accept this interface.  If not
found, delete the interface (cleaning up after crash).  Also,
in OpenVPNDriver, create a tunnel device and hold enough state
to be able to claim it later.

BUG=chromium-os:26841,chromium-os:27156,chromium-os:27158
TEST=New unit tests.  Manual: Ensure tunnel devices get cleaned up on a
real system.

Change-Id: Iaaa44dc26830a2e8bf5dfea00d165ab8c034e6e9
Reviewed-on: https://gerrit.chromium.org/gerrit/17191
Reviewed-by: Darin Petkov <petkov@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/openvpn_driver.h b/openvpn_driver.h
index 9a07652..57d2272 100644
--- a/openvpn_driver.h
+++ b/openvpn_driver.h
@@ -17,21 +17,28 @@
 namespace shill {
 
 class ControlInterface;
+class DeviceInfo;
 class Error;
 class RPCTask;
+class DeviceStub;
 
 class OpenVPNDriver : public VPNDriver {
  public:
-  OpenVPNDriver(ControlInterface *control, const KeyValueStore &args);
+  OpenVPNDriver(ControlInterface *control,
+                DeviceInfo *device_info,
+                const KeyValueStore &args);
   virtual ~OpenVPNDriver();
 
   // Inherited from VPNDriver.
+  virtual bool ClaimInterface(const std::string &link_name,
+                              int interface_index);
   virtual void Connect(Error *error);
 
  private:
   friend class OpenVPNDriverTest;
   FRIEND_TEST(OpenVPNDriverTest, AppendFlag);
   FRIEND_TEST(OpenVPNDriverTest, AppendValueOption);
+  FRIEND_TEST(OpenVPNDriverTest, ClaimInterface);
   FRIEND_TEST(OpenVPNDriverTest, InitOptions);
   FRIEND_TEST(OpenVPNDriverTest, InitOptionsNoHost);
 
@@ -45,8 +52,11 @@
                   std::vector<std::string> *options);
 
   ControlInterface *control_;
+  DeviceInfo *device_info_;
   KeyValueStore args_;
   scoped_ptr<RPCTask> rpc_task_;
+  std::string tunnel_interface_;
+  int interface_index_;
 
   DISALLOW_COPY_AND_ASSIGN(OpenVPNDriver);
 };