Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 1 | // 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 | |
| 15 | using std::string; |
| 16 | using std::vector; |
| 17 | |
| 18 | namespace shill { |
| 19 | |
| 20 | namespace Logging { |
| 21 | static auto kModuleLogScope = ScopeLogger::kDHCP; |
Paul Stewart | 0bfabaa | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 22 | static string ObjectID(DHCPv6Config* d) { |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 23 | if (d == nullptr) |
| 24 | return "(DHCPv6_config)"; |
| 25 | else |
| 26 | return d->device_name(); |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | // static |
| 31 | const char DHCPv6Config::kDHCPCDPathFormatPID[] = |
| 32 | "var/run/dhcpcd/dhcpcd-%s-6.pid"; |
| 33 | |
| 34 | const char DHCPv6Config::kConfigurationKeyDelegatedPrefix[] = |
| 35 | "DHCPv6DelegatedPrefix"; |
| 36 | const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLength[] = |
| 37 | "DHCPv6DelegatedPrefixLength"; |
| 38 | const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLeaseTime[] = |
| 39 | "DHCPv6DelegatedPrefixLeaseTime"; |
| 40 | const char DHCPv6Config::kConfigurationKeyDNS[] = "DHCPv6NameServers"; |
| 41 | const char DHCPv6Config::kConfigurationKeyDomainSearch[] = "DHCPv6DomainSearch"; |
| 42 | const char DHCPv6Config::kConfigurationKeyIPAddress[] = "DHCPv6Address"; |
| 43 | const char DHCPv6Config::kConfigurationKeyIPAddressLeaseTime[] = |
Peter Qiu | a11633e | 2015-06-23 11:23:46 -0700 | [diff] [blame] | 44 | "DHCPv6AddressLeaseTime"; |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 45 | const char DHCPv6Config::kConfigurationKeyServerIdentifier[] = |
| 46 | "DHCPv6ServerIdentifier"; |
| 47 | |
| 48 | const char DHCPv6Config::kReasonBound[] = "BOUND6"; |
| 49 | const char DHCPv6Config::kReasonFail[] = "FAIL6"; |
| 50 | const char DHCPv6Config::kReasonRebind[] = "REBIND6"; |
| 51 | const char DHCPv6Config::kReasonReboot[] = "REBOOT6"; |
| 52 | const char DHCPv6Config::kReasonRenew[] = "RENEW6"; |
| 53 | |
| 54 | const char DHCPv6Config::kType[] = "dhcp6"; |
| 55 | |
Paul Stewart | 0bfabaa | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 56 | DHCPv6Config::DHCPv6Config(ControlInterface* control_interface, |
| 57 | EventDispatcher* dispatcher, |
| 58 | DHCPProvider* provider, |
| 59 | const string& device_name, |
Peter Qiu | 8ee1c83 | 2015-08-11 20:59:01 -0700 | [diff] [blame] | 60 | const string& lease_file_suffix) |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 61 | : DHCPConfig(control_interface, |
| 62 | dispatcher, |
| 63 | provider, |
| 64 | device_name, |
| 65 | kType, |
Peter Qiu | 8ee1c83 | 2015-08-11 20:59:01 -0700 | [diff] [blame] | 66 | lease_file_suffix) { |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 67 | SLOG(this, 2) << __func__ << ": " << device_name; |
| 68 | } |
| 69 | |
| 70 | DHCPv6Config::~DHCPv6Config() { |
| 71 | SLOG(this, 2) << __func__ << ": " << device_name(); |
| 72 | } |
| 73 | |
Paul Stewart | 0bfabaa | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 74 | void DHCPv6Config::ProcessEventSignal(const string& reason, |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 75 | const KeyValueStore& configuration) { |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 76 | 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 Stewart | 0bfabaa | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 99 | void DHCPv6Config::ProcessStatusChangeSignal(const string& status) { |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 100 | SLOG(this, 2) << __func__ << ": " << status; |
| 101 | // TODO(zqiu): metric reporting for status. |
| 102 | } |
| 103 | |
| 104 | void 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 | |
| 120 | vector<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 Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 129 | bool DHCPv6Config::ParseConfiguration(const KeyValueStore& configuration) { |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 130 | SLOG(nullptr, 2) << __func__; |
| 131 | properties_.method = kTypeDHCP6; |
| 132 | properties_.address_family = IPAddress::kFamilyIPv6; |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 133 | for (const auto it : configuration.properties()) { |
| 134 | const string& key = it.first; |
| 135 | const chromeos::Any& value = it.second; |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 136 | SLOG(nullptr, 2) << "Processing key: " << key; |
| 137 | if (key == kConfigurationKeyIPAddress) { |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 138 | properties_.address = value.Get<string>(); |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 139 | } else if (key == kConfigurationKeyDNS) { |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 140 | properties_.dns_servers = value.Get<vector<string>>(); |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 141 | } else if (key == kConfigurationKeyDomainSearch) { |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 142 | properties_.domain_search = value.Get<vector<string>>(); |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 143 | } else if (key == kConfigurationKeyIPAddressLeaseTime || |
| 144 | key == kConfigurationKeyDelegatedPrefixLeaseTime) { |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 145 | UpdateLeaseTime(value.Get<uint32_t>()); |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 146 | } else if (key == kConfigurationKeyDelegatedPrefix) { |
Peter Qiu | 445883d | 2015-07-30 15:21:01 -0700 | [diff] [blame] | 147 | properties_.delegated_prefix = value.Get<string>(); |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 148 | } else if (key == kConfigurationKeyDelegatedPrefixLength) { |
Peter Qiu | 7adad98 | 2015-07-24 10:24:54 -0700 | [diff] [blame] | 149 | properties_.delegated_prefix_length = value.Get<uint32_t>(); |
Peter Qiu | b255a76 | 2015-06-10 10:09:12 -0700 | [diff] [blame] | 150 | } else { |
| 151 | SLOG(nullptr, 2) << "Key ignored."; |
| 152 | } |
| 153 | } |
| 154 | return true; |
| 155 | } |
| 156 | |
| 157 | void 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 |