1// 2// Copyright (C) 2015 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "shill/dhcp/dhcpv6_config.h" 18 19#include <base/files/file_util.h> 20#include <base/strings/stringprintf.h> 21#if defined(__ANDROID__) 22#include <dbus/service_constants.h> 23#else 24#include <chromeos/dbus/service_constants.h> 25#endif // __ANDROID__ 26 27#include "shill/dhcp/dhcp_provider.h" 28#include "shill/logging.h" 29#include "shill/net/ip_address.h" 30 31using std::string; 32using std::vector; 33 34namespace shill { 35 36namespace Logging { 37static auto kModuleLogScope = ScopeLogger::kDHCP; 38static string ObjectID(DHCPv6Config* d) { 39 if (d == nullptr) 40 return "(DHCPv6_config)"; 41 else 42 return d->device_name(); 43} 44} 45 46// static 47const char DHCPv6Config::kDHCPCDPathFormatPID[] = 48 "var/run/dhcpcd/dhcpcd-%s-6.pid"; 49 50const char DHCPv6Config::kConfigurationKeyDelegatedPrefix[] = 51 "DHCPv6DelegatedPrefix"; 52const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLength[] = 53 "DHCPv6DelegatedPrefixLength"; 54const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLeaseTime[] = 55 "DHCPv6DelegatedPrefixLeaseTime"; 56const char DHCPv6Config::kConfigurationKeyDNS[] = "DHCPv6NameServers"; 57const char DHCPv6Config::kConfigurationKeyDomainSearch[] = "DHCPv6DomainSearch"; 58const char DHCPv6Config::kConfigurationKeyIPAddress[] = "DHCPv6Address"; 59const char DHCPv6Config::kConfigurationKeyIPAddressLeaseTime[] = 60 "DHCPv6AddressLeaseTime"; 61const char DHCPv6Config::kConfigurationKeyServerIdentifier[] = 62 "DHCPv6ServerIdentifier"; 63 64const char DHCPv6Config::kReasonBound[] = "BOUND6"; 65const char DHCPv6Config::kReasonFail[] = "FAIL6"; 66const char DHCPv6Config::kReasonRebind[] = "REBIND6"; 67const char DHCPv6Config::kReasonReboot[] = "REBOOT6"; 68const char DHCPv6Config::kReasonRenew[] = "RENEW6"; 69 70const char DHCPv6Config::kType[] = "dhcp6"; 71 72DHCPv6Config::DHCPv6Config(ControlInterface* control_interface, 73 EventDispatcher* dispatcher, 74 DHCPProvider* provider, 75 const string& device_name, 76 const string& lease_file_suffix) 77 : DHCPConfig(control_interface, 78 dispatcher, 79 provider, 80 device_name, 81 kType, 82 lease_file_suffix) { 83 SLOG(this, 2) << __func__ << ": " << device_name; 84} 85 86DHCPv6Config::~DHCPv6Config() { 87 SLOG(this, 2) << __func__ << ": " << device_name(); 88} 89 90void DHCPv6Config::ProcessEventSignal(const string& reason, 91 const KeyValueStore& configuration) { 92 LOG(INFO) << "Event reason: " << reason; 93 if (reason == kReasonFail) { 94 LOG(ERROR) << "Received failure event from DHCPv6 client."; 95 NotifyFailure(); 96 return; 97 } else if (reason != kReasonBound && 98 reason != kReasonRebind && 99 reason != kReasonReboot && 100 reason != kReasonRenew) { 101 LOG(WARNING) << "Event ignored."; 102 return; 103 } 104 105 CHECK(ParseConfiguration(configuration)); 106 107 // This needs to be set before calling UpdateProperties() below since 108 // those functions may indirectly call other methods like ReleaseIP that 109 // depend on or change this value. 110 set_is_lease_active(true); 111 112 DHCPConfig::UpdateProperties(properties_, true); 113} 114 115void DHCPv6Config::ProcessStatusChangeSignal(const string& status) { 116 SLOG(this, 2) << __func__ << ": " << status; 117 // TODO(zqiu): metric reporting for status. 118} 119 120void DHCPv6Config::CleanupClientState() { 121 DHCPConfig::CleanupClientState(); 122 123 // Delete lease file if it is ephemeral. 124 if (IsEphemeralLease()) { 125 base::DeleteFile(root().Append( 126 base::StringPrintf(DHCPProvider::kDHCPCDPathFormatLease6, 127 device_name().c_str())), false); 128 } 129 base::DeleteFile(root().Append( 130 base::StringPrintf(kDHCPCDPathFormatPID, device_name().c_str())), false); 131 132 // Reset configuration data. 133 properties_ = IPConfig::Properties(); 134} 135 136vector<string> DHCPv6Config::GetFlags() { 137 // Get default flags first. 138 vector<string> flags = DHCPConfig::GetFlags(); 139 140 flags.push_back("-6"); // IPv6 only. 141 flags.push_back("-a"); // Request ia_na and ia_pd. 142 return flags; 143} 144 145bool DHCPv6Config::ParseConfiguration(const KeyValueStore& configuration) { 146 SLOG(nullptr, 2) << __func__; 147 properties_.method = kTypeDHCP6; 148 properties_.address_family = IPAddress::kFamilyIPv6; 149 for (const auto it : configuration.properties()) { 150 const string& key = it.first; 151 const brillo::Any& value = it.second; 152 SLOG(nullptr, 2) << "Processing key: " << key; 153 if (key == kConfigurationKeyIPAddress) { 154 properties_.address = value.Get<string>(); 155 } else if (key == kConfigurationKeyDNS) { 156 properties_.dns_servers = value.Get<vector<string>>(); 157 } else if (key == kConfigurationKeyDomainSearch) { 158 properties_.domain_search = value.Get<vector<string>>(); 159 } else if (key == kConfigurationKeyIPAddressLeaseTime || 160 key == kConfigurationKeyDelegatedPrefixLeaseTime) { 161 UpdateLeaseTime(value.Get<uint32_t>()); 162 } else if (key == kConfigurationKeyDelegatedPrefix) { 163 properties_.delegated_prefix = value.Get<string>(); 164 } else if (key == kConfigurationKeyDelegatedPrefixLength) { 165 properties_.delegated_prefix_length = value.Get<uint32_t>(); 166 } else { 167 SLOG(nullptr, 2) << "Key ignored."; 168 } 169 } 170 return true; 171} 172 173void DHCPv6Config::UpdateLeaseTime(uint32_t lease_time) { 174 // IP address and delegated prefix are provided as separate lease. Use 175 // the shorter time of the two lease as the lease time. 176 if (properties_.lease_duration_seconds == 0 || 177 lease_time < properties_.lease_duration_seconds) { 178 properties_.lease_duration_seconds = lease_time; 179 } 180} 181 182} // namespace shill 183