blob: 460654d32da5267792011d88fbc9f19efae864c6 [file] [log] [blame]
Paul Stewartdd60e452011-08-08 11:38:36 -07001// 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
Paul Stewart9a908082011-08-31 12:18:48 -07007#include <arpa/inet.h>
8#include <linux/rtnetlink.h>
9
10#include "shill/device_info.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070011#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
Paul Stewart7cfca042011-12-08 14:18:17 -080022const uint32 Connection::kNonDefaultMetricBase = 10;
Paul Stewartdd60e452011-08-08 11:38:36 -070023
Paul Stewart9a908082011-08-31 12:18:48 -070024Connection::Connection(int interface_index,
25 const std::string& interface_name,
26 const DeviceInfo *device_info)
Paul Stewartdd60e452011-08-08 11:38:36 -070027 : is_default_(false),
28 interface_index_(interface_index),
29 interface_name_(interface_name),
Paul Stewart9a908082011-08-31 12:18:48 -070030 device_info_(device_info),
Paul Stewartdd60e452011-08-08 11:38:36 -070031 resolver_(Resolver::GetInstance()),
32 routing_table_(RoutingTable::GetInstance()),
33 rtnl_handler_(RTNLHandler::GetInstance()) {
34 VLOG(2) << __func__;
35}
36
37Connection::~Connection() {
Paul Stewartdd60e452011-08-08 11:38:36 -070038 VLOG(2) << __func__;
Paul Stewart9a908082011-08-31 12:18:48 -070039
40 routing_table_->FlushRoutes(interface_index_);
41 device_info_->FlushAddresses(interface_index_);
Paul Stewartdd60e452011-08-08 11:38:36 -070042}
43
44void Connection::UpdateFromIPConfig(const IPConfigRefPtr &config) {
45 VLOG(2) << __func__;
Paul Stewarte6132022011-08-16 09:11:02 -070046
Paul Stewart9a908082011-08-31 12:18:48 -070047 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);
Paul Stewartdd60e452011-08-08 11:38:36 -070063
Paul Stewart7cfca042011-12-08 14:18:17 -080064 routing_table_->SetDefaultRoute(interface_index_, config,
65 GetMetric(is_default_));
Paul Stewartdd60e452011-08-08 11:38:36 -070066
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
Paul Stewartc1dec4d2011-12-08 15:25:28 -080078void Connection::SetIsDefault(bool is_default) {
Paul Stewartdd60e452011-08-08 11:38:36 -070079 VLOG(2) << __func__;
80 if (is_default == is_default_) {
81 return;
82 }
83
Paul Stewart7cfca042011-12-08 14:18:17 -080084 routing_table_->SetDefaultMetric(interface_index_, GetMetric(is_default));
Paul Stewartdd60e452011-08-08 11:38:36 -070085
86 if (is_default) {
87 resolver_->SetDNSFromLists(dns_servers_, dns_domain_search_);
88 }
89
90 is_default_ = is_default;
91}
92
Paul Stewart7cfca042011-12-08 14:18:17 -080093uint32 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
Paul Stewartdd60e452011-08-08 11:38:36 -0700100} // namespace shill