shill: Assign "Default" status to the best connection

Set the highest-ranked connection to be the "Default".
As a result, the highest priority default route will
move with the highest-ranked connection in the service
list.

Bonus changes:
 * Service now formally holds a reference to the Connection
   object, so call a "SetConnection" method instead of a
   Create/Destroy of the HTTPProxy.
 * Actually start the routing table service, and do a couple
   minor fixes due to how the kernel actually accepts metric
   changes.

BUG=chromium-os:7607,chromium-os:23993
TEST=New Unit Test + Manual (watch routes while inserting
USB-Ethernet on a machine connected to WiFi)

Change-Id: Iddf1ed766238d9e8adc97bb54fc12b527f86239f
Reviewed-on: https://gerrit.chromium.org/gerrit/12685
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/manager.cc b/manager.cc
index 5d07df0..fe5c36b 100644
--- a/manager.cc
+++ b/manager.cc
@@ -21,6 +21,7 @@
 #include <chromeos/dbus/service_constants.h>
 
 #include "shill/adaptor_interfaces.h"
+#include "shill/connection.h"
 #include "shill/control_interface.h"
 #include "shill/dbus_adaptor.h"
 #include "shill/default_profile.h"
@@ -392,6 +393,7 @@
   vector<ServiceRefPtr>::iterator it;
   for (it = services_.begin(); it != services_.end(); ++it) {
     if (to_forget->UniqueName() == (*it)->UniqueName()) {
+      DCHECK(!(*it)->connection());
       services_.erase(it);
       SortServices();
       return;
@@ -449,6 +451,12 @@
 }
 
 void Manager::SortServices() {
+  VLOG(4) << "In " << __func__;
+  ConnectionRefPtr default_connection;
+  if (!services_.empty()) {
+    // Keep track of the connection that was last considered default.
+    default_connection = services_[0]->connection();
+  }
   sort(services_.begin(), services_.end(), ServiceSorter(technology_order_));
 
   vector<string> service_paths;
@@ -466,6 +474,16 @@
                                ConnectedTechnologies(&error));
   adaptor_->EmitStringChanged(flimflam::kDefaultTechnologyProperty,
                               DefaultTechnology(&error));
+
+  if (!services_.empty()) {
+    if (default_connection.get() &&
+        (services_[0]->connection().get() != default_connection.get())) {
+      default_connection->SetIsDefault(false);
+    }
+    if (services_[0]->connection().get()) {
+      services_[0]->connection()->SetIsDefault(true);
+    }
+  }
 }
 
 string Manager::CalculateState(Error */*error*/) {