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/device_info.cc b/device_info.cc
index 75f4734..31d6c39 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -265,7 +265,13 @@
// Tunnel devices are managed by the VPN code.
VLOG(2) << "Tunnel link " << link_name << " at index " << dev_index
<< " -- notifying VPNProvider.";
- // TODO(pstew): Notify VPNProvider once that method exists.
+ if (manager_->vpn_provider()->OnDeviceInfoAvailable(link_name,
+ dev_index)) {
+ // VPN does not know anything about this tunnel, it is probably
+ // left over from a previous instance and should not exist.
+ VLOG(2) << "Tunnel link is unused. Deleting.";
+ DeleteInterface(dev_index);
+ }
return;
default:
device = new DeviceStub(control_interface_, dispatcher_, metrics_,
@@ -342,7 +348,7 @@
return true;
}
-bool DeviceInfo::CreateTunnelInterface(string *interface_name) {
+bool DeviceInfo::CreateTunnelInterface(string *interface_name) const {
int fd = HANDLE_EINTR(open(kTunDeviceName, O_RDWR));
if (fd < 0) {
PLOG(ERROR) << "failed to open " << kTunDeviceName;
@@ -368,7 +374,7 @@
return true;
}
-bool DeviceInfo::DeleteInterface(int interface_index) {
+bool DeviceInfo::DeleteInterface(int interface_index) const {
return rtnl_handler_->RemoveInterface(interface_index);
}