• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 using std::string;
32 using std::vector;
33 
34 namespace shill {
35 
36 namespace Logging {
37 static auto kModuleLogScope = ScopeLogger::kDHCP;
ObjectID(DHCPv6Config * d)38 static string ObjectID(DHCPv6Config* d) {
39   if (d == nullptr)
40     return "(DHCPv6_config)";
41   else
42     return d->device_name();
43 }
44 }
45 
46 // static
47 const char DHCPv6Config::kDHCPCDPathFormatPID[] =
48     "var/run/dhcpcd/dhcpcd-%s-6.pid";
49 
50 const char DHCPv6Config::kConfigurationKeyDelegatedPrefix[] =
51     "DHCPv6DelegatedPrefix";
52 const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLength[] =
53     "DHCPv6DelegatedPrefixLength";
54 const char DHCPv6Config::kConfigurationKeyDelegatedPrefixLeaseTime[] =
55     "DHCPv6DelegatedPrefixLeaseTime";
56 const char DHCPv6Config::kConfigurationKeyDNS[] = "DHCPv6NameServers";
57 const char DHCPv6Config::kConfigurationKeyDomainSearch[] = "DHCPv6DomainSearch";
58 const char DHCPv6Config::kConfigurationKeyIPAddress[] = "DHCPv6Address";
59 const char DHCPv6Config::kConfigurationKeyIPAddressLeaseTime[] =
60     "DHCPv6AddressLeaseTime";
61 const char DHCPv6Config::kConfigurationKeyServerIdentifier[] =
62     "DHCPv6ServerIdentifier";
63 
64 const char DHCPv6Config::kReasonBound[] = "BOUND6";
65 const char DHCPv6Config::kReasonFail[] = "FAIL6";
66 const char DHCPv6Config::kReasonRebind[] = "REBIND6";
67 const char DHCPv6Config::kReasonReboot[] = "REBOOT6";
68 const char DHCPv6Config::kReasonRenew[] = "RENEW6";
69 
70 const char DHCPv6Config::kType[] = "dhcp6";
71 
DHCPv6Config(ControlInterface * control_interface,EventDispatcher * dispatcher,DHCPProvider * provider,const string & device_name,const string & lease_file_suffix)72 DHCPv6Config::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 
~DHCPv6Config()86 DHCPv6Config::~DHCPv6Config() {
87   SLOG(this, 2) << __func__ << ": " << device_name();
88 }
89 
ProcessEventSignal(const string & reason,const KeyValueStore & configuration)90 void 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 
ProcessStatusChangeSignal(const string & status)115 void DHCPv6Config::ProcessStatusChangeSignal(const string& status) {
116   SLOG(this, 2) << __func__ << ": " << status;
117   // TODO(zqiu): metric reporting for status.
118 }
119 
CleanupClientState()120 void 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 
GetFlags()136 vector<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 
ParseConfiguration(const KeyValueStore & configuration)145 bool 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 
UpdateLeaseTime(uint32_t lease_time)173 void 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