connection.cc revision 7cfca0467e47aa91b485c485b92befb33a1fd61f
1// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "shill/connection.h" 6 7#include <arpa/inet.h> 8#include <linux/rtnetlink.h> 9 10#include "shill/device_info.h" 11#include "shill/resolver.h" 12#include "shill/routing_table.h" 13#include "shill/rtnl_handler.h" 14 15using std::string; 16 17namespace shill { 18 19// static 20const uint32 Connection::kDefaultMetric = 1; 21// static 22const uint32 Connection::kNonDefaultMetricBase = 10; 23 24Connection::Connection(int interface_index, 25 const std::string& interface_name, 26 const DeviceInfo *device_info) 27 : is_default_(false), 28 interface_index_(interface_index), 29 interface_name_(interface_name), 30 device_info_(device_info), 31 resolver_(Resolver::GetInstance()), 32 routing_table_(RoutingTable::GetInstance()), 33 rtnl_handler_(RTNLHandler::GetInstance()) { 34 VLOG(2) << __func__; 35} 36 37Connection::~Connection() { 38 VLOG(2) << __func__; 39 40 routing_table_->FlushRoutes(interface_index_); 41 device_info_->FlushAddresses(interface_index_); 42} 43 44void Connection::UpdateFromIPConfig(const IPConfigRefPtr &config) { 45 VLOG(2) << __func__; 46 47 const IPConfig::Properties &properties = config->properties(); 48 IPAddress local(properties.address_family); 49 if (!local.SetAddressFromString(properties.address)) { 50 LOG(ERROR) << "Local address " << properties.address << " is invalid"; 51 return; 52 } 53 local.set_prefix(properties.subnet_cidr); 54 55 IPAddress broadcast(properties.address_family); 56 if (!broadcast.SetAddressFromString(properties.broadcast_address)) { 57 LOG(ERROR) << "Broadcast address " << properties.broadcast_address 58 << " is invalid"; 59 return; 60 } 61 62 rtnl_handler_->AddInterfaceAddress(interface_index_, local, broadcast); 63 64 routing_table_->SetDefaultRoute(interface_index_, config, 65 GetMetric(is_default_)); 66 67 // Save a copy of the last non-null DNS config 68 if (!config->properties().dns_servers.empty()) { 69 dns_servers_ = config->properties().dns_servers; 70 dns_domain_search_ = config->properties().domain_search; 71 } 72 73 if (is_default_) { 74 resolver_->SetDNSFromIPConfig(config); 75 } 76} 77 78void Connection::SetDefault(bool is_default) { 79 VLOG(2) << __func__; 80 if (is_default == is_default_) { 81 return; 82 } 83 84 routing_table_->SetDefaultMetric(interface_index_, GetMetric(is_default)); 85 86 if (is_default) { 87 resolver_->SetDNSFromLists(dns_servers_, dns_domain_search_); 88 } 89 90 is_default_ = is_default; 91} 92 93uint32 Connection::GetMetric(bool is_default) { 94 // If this is not the default route, assign a metric based on the interface 95 // index. This way all non-default routes (even to the same gateway IP) end 96 // up with unique metrics so they do not collide. 97 return is_default ? kDefaultMetric : kNonDefaultMetricBase + interface_index_; 98} 99 100} // namespace shill 101