shill: Add connection to device
Also in the process, do a few bits like setting up a run path in
the manager so it can initialize the resolver output path.
BUG=chromium-os:19095
TEST=Ran unit tests (for regression), tested that DNS and routes applied
for Ethernet on real system.
Change-Id: If505200643efa6c3152f6e61db3b91a04e739c18
Reviewed-on: http://gerrit.chromium.org/gerrit/6087
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/connection.cc b/connection.cc
index 5ca7d86..d788020 100644
--- a/connection.cc
+++ b/connection.cc
@@ -35,6 +35,10 @@
void Connection::UpdateFromIPConfig(const IPConfigRefPtr &config) {
VLOG(2) << __func__;
+
+ // TODO(pstew): Create a centralized resource (perhaps in DeviceInfo?) to
+ // keep apply and keep track of addresses associated with an interface.
+ // Use this instead of directly setting the address over RTNL.
rtnl_handler_->AddInterfaceAddress(interface_index_, *config);
uint32 metric = is_default_ ? kDefaultMetric : kNonDefaultMetric;
diff --git a/device.cc b/device.cc
index 04d0a3c..851c922 100644
--- a/device.cc
+++ b/device.cc
@@ -15,6 +15,7 @@
#include <base/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
+#include "shill/connection.h"
#include "shill/control_interface.h"
#include "shill/device_dbus_adaptor.h"
#include "shill/dhcp_config.h"
@@ -167,11 +168,15 @@
void Device::DestroyIPConfig() {
if (ipconfig_.get()) {
+ // TODO(pstew): Instead we should do this in DestroyConnection(), which
+ // should have a facility at its disposal that returns all addresses
+ // assigned to the interface.
RTNLHandler::GetInstance()->RemoveInterfaceAddress(interface_index_,
*ipconfig_);
ipconfig_->ReleaseIP();
ipconfig_ = NULL;
}
+ DestroyConnection();
}
bool Device::AcquireDHCPConfig() {
@@ -192,15 +197,29 @@
void Device::IPConfigUpdatedCallback(const IPConfigRefPtr &ipconfig,
bool success) {
- // TODO(petkov): Use DeviceInfo to configure IP, etc. -- maybe through
- // ConfigIP? Also, maybe allow forwarding the callback to interested listeners
- // (e.g., the Manager).
+ VLOG(2) << __func__ << " " << " success: " << success;
if (success) {
- RTNLHandler::GetInstance()->AddInterfaceAddress(interface_index_,
- *ipconfig);
+ CreateConnection();
+ connection_->UpdateFromIPConfig(ipconfig);
+ } else {
+ // TODO(pstew): This logic gets more complex when multiple IPConfig types
+ // are run in parallel (e.g. DHCP and DHCP6)
+ DestroyConnection();
}
}
+void Device::CreateConnection() {
+ VLOG(2) << __func__;
+ if (!connection_.get()) {
+ connection_ = new Connection(interface_index_, link_name_);
+ }
+}
+
+void Device::DestroyConnection() {
+ VLOG(2) << __func__;
+ connection_ = NULL;
+}
+
string Device::SerializeIPConfigsForStorage() {
return StringPrintf("%s:%s",
ipconfig_->GetStorageIdentifier().c_str(),
diff --git a/device.h b/device.h
index 6998f39..27fee74 100644
--- a/device.h
+++ b/device.h
@@ -66,6 +66,7 @@
const std::string &link_name() const { return link_name_; }
int interface_index() const { return interface_index_; }
+ const ConnectionRefPtr &connection() const { return connection_; }
const std::string &FriendlyName() const;
@@ -97,6 +98,12 @@
// request was successfully sent.
bool AcquireDHCPConfig();
+ // Maintain connection state (Routes, IP Addresses and DNS) in the OS.
+ void CreateConnection();
+
+ // Remove connection state
+ void DestroyConnection();
+
void HelpRegisterDerivedStrings(const std::string &name,
Strings(Device::*get)(void),
bool(Device::*set)(const Strings&));
@@ -117,6 +124,7 @@
EventDispatcher *dispatcher_;
Manager *manager_;
IPConfigRefPtr ipconfig_;
+ ConnectionRefPtr connection_;
private:
friend class DeviceAdaptorInterface;
diff --git a/manager.cc b/manager.cc
index 9395269..43e9bf1 100644
--- a/manager.cc
+++ b/manager.cc
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include <base/file_util.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <chromeos/dbus/service_constants.h>
@@ -24,6 +25,7 @@
#include "shill/error.h"
#include "shill/profile.h"
#include "shill/property_accessor.h"
+#include "shill/resolver.h"
#include "shill/shill_event.h"
#include "shill/service.h"
@@ -31,10 +33,15 @@
using std::vector;
namespace shill {
+
+// static
+const char Manager::kDefaultRunDirectory[] = "/var/run/shill";
+
Manager::Manager(ControlInterface *control_interface,
EventDispatcher *dispatcher,
GLib *glib)
- : adaptor_(control_interface->CreateManagerAdaptor(this)),
+ : run_path_(FilePath(kDefaultRunDirectory)),
+ adaptor_(control_interface->CreateManagerAdaptor(this)),
device_info_(control_interface, dispatcher, this),
modem_info_(control_interface, dispatcher, this, glib),
running_(false),
@@ -96,6 +103,9 @@
void Manager::Start() {
LOG(INFO) << "Manager started.";
+
+ CHECK(file_util::CreateDirectory(run_path_));
+ Resolver::GetInstance()->set_path(run_path_.Append("resolv.conf"));
running_ = true;
adaptor_->UpdateRunning();
device_info_.Start();
diff --git a/manager.h b/manager.h
index 154e51c..5f6f925 100644
--- a/manager.h
+++ b/manager.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include <base/file_path.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <chromeos/dbus/service_constants.h>
@@ -70,6 +71,8 @@
private:
friend class ManagerAdaptorInterface;
+ static const char kDefaultRunDirectory[];
+
std::string CalculateState();
std::vector<std::string> AvailableTechnologies();
std::vector<std::string> ConnectedTechnologies();
@@ -87,6 +90,7 @@
Strings(Manager::*get)(void),
bool(Manager::*set)(const Strings&));
+ FilePath run_path_;
scoped_ptr<ManagerAdaptorInterface> adaptor_;
DeviceInfo device_info_;
ModemInfo modem_info_;
diff --git a/resolver.cc b/resolver.cc
index bb7105b..d0d4d7a 100644
--- a/resolver.cc
+++ b/resolver.cc
@@ -31,6 +31,8 @@
}
bool Resolver::SetDNSFromIPConfig(const IPConfigRefPtr &ipconfig) {
+ VLOG(2) << __func__;
+
CHECK(!path_.empty());
const IPConfig::Properties &props = ipconfig->properties();
@@ -40,7 +42,10 @@
bool Resolver::SetDNSFromLists(const std::vector<std::string> &dns_servers,
const std::vector<std::string> &domain_search) {
+ VLOG(2) << __func__;
+
if (dns_servers.empty() && domain_search.empty()) {
+ VLOG(2) << "DNS list is empty";
return ClearDNS();
}
@@ -59,12 +64,16 @@
lines.push_back("");
string contents = JoinString(lines, '\n');
+
+ VLOG(2) << "Writing DNS out to " << path_.value();
int count = file_util::WriteFile(path_, contents.c_str(), contents.size());
return count == static_cast<int>(contents.size());
}
bool Resolver::ClearDNS() {
+ VLOG(2) << __func__;
+
CHECK(!path_.empty());
return file_util::Delete(path_, false);
diff --git a/routing_table.cc b/routing_table.cc
index dc78f4b..25b9b8f 100644
--- a/routing_table.cc
+++ b/routing_table.cc
@@ -285,7 +285,7 @@
RTNLMessage msg(
RTNLMessage::kMessageTypeRoute,
mode,
- flags,
+ NLM_F_REQUEST | flags,
0,
0,
0,
diff --git a/routing_table_unittest.cc b/routing_table_unittest.cc
index 39e7d1b..066c411 100644
--- a/routing_table_unittest.cc
+++ b/routing_table_unittest.cc
@@ -95,7 +95,7 @@
return
msg.type() == RTNLMessage::kMessageTypeRoute &&
msg.family() == entry.gateway.family() &&
- msg.flags() == flags &&
+ msg.flags() == (NLM_F_REQUEST | flags) &&
status.table == RT_TABLE_MAIN &&
status.protocol == RTPROT_BOOT &&
status.scope == entry.scope &&