blob: d212ec2f8d685593ff6bd490c2a133c67a4f38ca [file] [log] [blame]
Peter Qiub255a762015-06-10 10:09:12 -07001// Copyright 2015 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/dhcp/dhcpv6_config.h"
6
7#include <base/files/file_util.h>
8#include <base/strings/stringprintf.h>
9#include <chromeos/dbus/service_constants.h>
10
11#include "shill/dhcp/dhcp_provider.h"
12#include "shill/logging.h"
13#include "shill/net/ip_address.h"
14
15using std::string;
16using std::vector;
17
18namespace shill {
19
20namespace Logging {
21static auto kModuleLogScope = ScopeLogger::kDHCP;
Paul Stewart0bfabaa2015-06-16 13:13:10 -070022static string ObjectID(DHCPv6Config* d) {
Peter Qiub255a762015-06-10 10:09:12 -070023 if (d == nullptr)
24 return "(DHCPv6_config)";
25 else
26 return d->device_name();
27}
28}
29
30// static
31const char DHCPv6Config::kDHCPCDPathFormatPID[] =
32 "var/run/dhcpcd/dhcpcd-%s-6.pid";
33
34const char DHCPv6Config::kConfigurationKeyDelegatedPrefix[] =
35 "DHCPv6DelegatedPrefix";
36const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLength[] =
37 "DHCPv6DelegatedPrefixLength";
38const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLeaseTime[] =
39 "DHCPv6DelegatedPrefixLeaseTime";
40const char DHCPv6Config::kConfigurationKeyDNS[] = "DHCPv6NameServers";
41const char DHCPv6Config::kConfigurationKeyDomainSearch[] = "DHCPv6DomainSearch";
42const char DHCPv6Config::kConfigurationKeyIPAddress[] = "DHCPv6Address";
43const char DHCPv6Config::kConfigurationKeyIPAddressLeaseTime[] =
Peter Qiua11633e2015-06-23 11:23:46 -070044 "DHCPv6AddressLeaseTime";
Peter Qiub255a762015-06-10 10:09:12 -070045const char DHCPv6Config::kConfigurationKeyServerIdentifier[] =
46 "DHCPv6ServerIdentifier";
47
48const char DHCPv6Config::kReasonBound[] = "BOUND6";
49const char DHCPv6Config::kReasonFail[] = "FAIL6";
50const char DHCPv6Config::kReasonRebind[] = "REBIND6";
51const char DHCPv6Config::kReasonReboot[] = "REBOOT6";
52const char DHCPv6Config::kReasonRenew[] = "RENEW6";
53
54const char DHCPv6Config::kType[] = "dhcp6";
55
Paul Stewart0bfabaa2015-06-16 13:13:10 -070056DHCPv6Config::DHCPv6Config(ControlInterface* control_interface,
57 EventDispatcher* dispatcher,
58 DHCPProvider* provider,
59 const string& device_name,
Peter Qiu8ee1c832015-08-11 20:59:01 -070060 const string& lease_file_suffix)
Peter Qiub255a762015-06-10 10:09:12 -070061 : DHCPConfig(control_interface,
62 dispatcher,
63 provider,
64 device_name,
65 kType,
Peter Qiu8ee1c832015-08-11 20:59:01 -070066 lease_file_suffix) {
Peter Qiub255a762015-06-10 10:09:12 -070067 SLOG(this, 2) << __func__ << ": " << device_name;
68}
69
70DHCPv6Config::~DHCPv6Config() {
71 SLOG(this, 2) << __func__ << ": " << device_name();
72}
73
Paul Stewart0bfabaa2015-06-16 13:13:10 -070074void DHCPv6Config::ProcessEventSignal(const string& reason,
Peter Qiu7adad982015-07-24 10:24:54 -070075 const KeyValueStore& configuration) {
Peter Qiub255a762015-06-10 10:09:12 -070076 LOG(INFO) << "Event reason: " << reason;
77 if (reason == kReasonFail) {
78 LOG(ERROR) << "Received failure event from DHCPv6 client.";
79 NotifyFailure();
80 return;
81 } else if (reason != kReasonBound &&
82 reason != kReasonRebind &&
83 reason != kReasonReboot &&
84 reason != kReasonRenew) {
85 LOG(WARNING) << "Event ignored.";
86 return;
87 }
88
89 CHECK(ParseConfiguration(configuration));
90
91 // This needs to be set before calling UpdateProperties() below since
92 // those functions may indirectly call other methods like ReleaseIP that
93 // depend on or change this value.
94 set_is_lease_active(true);
95
96 DHCPConfig::UpdateProperties(properties_, true);
97}
98
Paul Stewart0bfabaa2015-06-16 13:13:10 -070099void DHCPv6Config::ProcessStatusChangeSignal(const string& status) {
Peter Qiub255a762015-06-10 10:09:12 -0700100 SLOG(this, 2) << __func__ << ": " << status;
101 // TODO(zqiu): metric reporting for status.
102}
103
104void DHCPv6Config::CleanupClientState() {
105 DHCPConfig::CleanupClientState();
106
107 // Delete lease file if it is ephemeral.
108 if (IsEphemeralLease()) {
109 base::DeleteFile(root().Append(
110 base::StringPrintf(DHCPProvider::kDHCPCDPathFormatLease6,
111 device_name().c_str())), false);
112 }
113 base::DeleteFile(root().Append(
114 base::StringPrintf(kDHCPCDPathFormatPID, device_name().c_str())), false);
115
116 // Reset configuration data.
117 properties_ = IPConfig::Properties();
118}
119
120vector<string> DHCPv6Config::GetFlags() {
121 // Get default flags first.
122 vector<string> flags = DHCPConfig::GetFlags();
123
124 flags.push_back("-6"); // IPv6 only.
125 flags.push_back("-a"); // Request ia_na and ia_pd options.
126 return flags;
127}
128
Peter Qiu7adad982015-07-24 10:24:54 -0700129bool DHCPv6Config::ParseConfiguration(const KeyValueStore& configuration) {
Peter Qiub255a762015-06-10 10:09:12 -0700130 SLOG(nullptr, 2) << __func__;
131 properties_.method = kTypeDHCP6;
132 properties_.address_family = IPAddress::kFamilyIPv6;
Peter Qiu7adad982015-07-24 10:24:54 -0700133 for (const auto it : configuration.properties()) {
134 const string& key = it.first;
135 const chromeos::Any& value = it.second;
Peter Qiub255a762015-06-10 10:09:12 -0700136 SLOG(nullptr, 2) << "Processing key: " << key;
137 if (key == kConfigurationKeyIPAddress) {
Peter Qiu7adad982015-07-24 10:24:54 -0700138 properties_.address = value.Get<string>();
Peter Qiub255a762015-06-10 10:09:12 -0700139 } else if (key == kConfigurationKeyDNS) {
Peter Qiu7adad982015-07-24 10:24:54 -0700140 properties_.dns_servers = value.Get<vector<string>>();
Peter Qiub255a762015-06-10 10:09:12 -0700141 } else if (key == kConfigurationKeyDomainSearch) {
Peter Qiu7adad982015-07-24 10:24:54 -0700142 properties_.domain_search = value.Get<vector<string>>();
Peter Qiub255a762015-06-10 10:09:12 -0700143 } else if (key == kConfigurationKeyIPAddressLeaseTime ||
144 key == kConfigurationKeyDelegatedPrefixLeaseTime) {
Peter Qiu7adad982015-07-24 10:24:54 -0700145 UpdateLeaseTime(value.Get<uint32_t>());
Peter Qiub255a762015-06-10 10:09:12 -0700146 } else if (key == kConfigurationKeyDelegatedPrefix) {
Peter Qiu445883d2015-07-30 15:21:01 -0700147 properties_.delegated_prefix = value.Get<string>();
Peter Qiub255a762015-06-10 10:09:12 -0700148 } else if (key == kConfigurationKeyDelegatedPrefixLength) {
Peter Qiu7adad982015-07-24 10:24:54 -0700149 properties_.delegated_prefix_length = value.Get<uint32_t>();
Peter Qiub255a762015-06-10 10:09:12 -0700150 } else {
151 SLOG(nullptr, 2) << "Key ignored.";
152 }
153 }
154 return true;
155}
156
157void DHCPv6Config::UpdateLeaseTime(uint32_t lease_time) {
158 // IP address and delegated prefix are provided as separate lease. Use
159 // the shorter time of the two lease as the lease time.
160 if (properties_.lease_duration_seconds == 0 ||
161 lease_time < properties_.lease_duration_seconds) {
162 properties_.lease_duration_seconds = lease_time;
163 }
164}
165
166} // namespace shill