1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ethernet_management.h"
17
18 #include <regex>
19 #include <thread>
20 #include <unistd.h>
21
22 #include "net_manager_constants.h"
23 #include "netmgr_ext_log_wrapper.h"
24 #include "netsys_controller.h"
25 #include "securec.h"
26
27 namespace OHOS {
28 namespace NetManagerStandard {
29 const std::string IFACE_MATCH = "eth\\d";
30 constexpr int SLEEP_TIME_S = 2;
OnDhcpSuccess(EthernetDhcpCallback::DhcpResult & dhcpResult)31 int32_t EthernetManagement::EhternetDhcpNotifyCallback::OnDhcpSuccess(EthernetDhcpCallback::DhcpResult &dhcpResult)
32 {
33 ethernetManagement_.UpdateDevInterfaceLinkInfo(dhcpResult);
34 return 0;
35 }
36
OnInterfaceAddressUpdated(const std::string &,const std::string &,int,int)37 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceAddressUpdated(const std::string &,
38 const std::string &, int, int)
39 {
40 return 0;
41 }
42
OnInterfaceAddressRemoved(const std::string &,const std::string &,int,int)43 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceAddressRemoved(const std::string &,
44 const std::string &, int, int)
45 {
46 return 0;
47 }
48
OnInterfaceAdded(const std::string & iface)49 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceAdded(const std::string &iface)
50 {
51 std::regex re(IFACE_MATCH);
52 if (std::regex_search(iface, re)) {
53 ethernetManagement_.DevInterfaceAdd(iface);
54 if (NetsysController::GetInstance().SetInterfaceUp(iface) != ERR_NONE) {
55 NETMGR_EXT_LOG_E("Iface[%{public}s] added set up fail!", iface.c_str());
56 }
57 }
58 return 0;
59 }
60
OnInterfaceRemoved(const std::string & iface)61 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceRemoved(const std::string &iface)
62 {
63 std::regex re(IFACE_MATCH);
64 if (std::regex_search(iface, re)) {
65 ethernetManagement_.DevInterfaceRemove(iface);
66 if (NetsysController::GetInstance().SetInterfaceDown(iface) != ERR_NONE) {
67 NETMGR_EXT_LOG_E("Iface[%{public}s] added set down fail!", iface.c_str());
68 }
69 }
70 return 0;
71 }
72
OnInterfaceChanged(const std::string &,bool)73 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceChanged(const std::string &, bool)
74 {
75 return 0;
76 }
77
OnInterfaceLinkStateChanged(const std::string & ifName,bool up)78 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceLinkStateChanged(const std::string &ifName, bool up)
79 {
80 NETMGR_EXT_LOG_I("DevInterfaceStateCallback::OnInterfaceLinkStateChanged iface[%{public}s] up[%{public}d]",
81 ifName.c_str(), up);
82 std::regex re(IFACE_MATCH);
83 if (std::regex_search(ifName, re)) {
84 ethernetManagement_.UpdateInterfaceState(ifName, up);
85 }
86 return 0;
87 }
88
OnRouteChanged(bool,const std::string &,const std::string &,const std::string &)89 int32_t EthernetManagement::DevInterfaceStateCallback::OnRouteChanged(bool, const std::string &, const std::string &,
90 const std::string &)
91 {
92 return 0;
93 }
94
OnDhcpSuccess(NetsysControllerCallback::DhcpResult & dhcpResult)95 int32_t EthernetManagement::DevInterfaceStateCallback::OnDhcpSuccess(NetsysControllerCallback::DhcpResult &dhcpResult)
96 {
97 return 0;
98 }
99
OnBandwidthReachedLimit(const std::string & limitName,const std::string & iface)100 int32_t EthernetManagement::DevInterfaceStateCallback::OnBandwidthReachedLimit(const std::string &limitName,
101 const std::string &iface)
102 {
103 return 0;
104 }
105
EthernetManagement()106 EthernetManagement::EthernetManagement()
107 {
108 ethDhcpController_ = std::make_unique<EthernetDhcpController>();
109 ethDhcpNotifyCallback_ = new (std::nothrow) EhternetDhcpNotifyCallback(*this);
110 if (ethDhcpNotifyCallback_ != nullptr) {
111 ethDhcpController_->RegisterDhcpCallback(ethDhcpNotifyCallback_);
112 }
113
114 ethDevInterfaceStateCallback_ = new (std::nothrow) DevInterfaceStateCallback(*this);
115 if (ethDevInterfaceStateCallback_ != nullptr) {
116 NetsysController::GetInstance().RegisterCallback(ethDevInterfaceStateCallback_);
117 }
118
119 ethConfiguration_ = std::make_unique<EthernetConfiguration>();
120 ethConfiguration_->ReadSysteamConfiguration(devCaps_, devCfgs_);
121 }
122
123 EthernetManagement::~EthernetManagement() = default;
124
UpdateInterfaceState(const std::string & dev,bool up)125 void EthernetManagement::UpdateInterfaceState(const std::string &dev, bool up)
126 {
127 NETMGR_EXT_LOG_D("EthernetManagement UpdateInterfaceState dev[%{public}s] up[%{public}d]", dev.c_str(), up);
128 std::unique_lock<std::mutex> lock(mutex_);
129 auto fit = devs_.find(dev);
130 if (fit == devs_.end()) {
131 return;
132 }
133 sptr<DevInterfaceState> devState = fit->second;
134 if (devState == nullptr) {
135 NETMGR_EXT_LOG_E("devState is nullptr");
136 return;
137 }
138 devState->SetLinkUp(up);
139 IPSetMode mode = devState->GetIPSetMode();
140 bool dhcpReqState = devState->GetDhcpReqState();
141 NETMGR_EXT_LOG_D("EthernetManagement UpdateInterfaceState mode[%{public}d] dhcpReqState[%{public}d]",
142 static_cast<int32_t>(mode), dhcpReqState);
143 if (up) {
144 devState->RemoteUpdateNetSupplierInfo();
145 if (mode == DHCP && !dhcpReqState) {
146 StartDhcpClient(dev, devState);
147 } else {
148 devState->RemoteUpdateNetLinkInfo();
149 }
150 } else {
151 if (mode == DHCP && dhcpReqState) {
152 StopDhcpClient(dev, devState);
153 }
154 devState->RemoteUpdateNetSupplierInfo();
155 }
156 }
157
UpdateDevInterfaceCfg(const std::string & iface,sptr<InterfaceConfiguration> cfg)158 int32_t EthernetManagement::UpdateDevInterfaceCfg(const std::string &iface, sptr<InterfaceConfiguration> cfg)
159 {
160 if (cfg == nullptr) {
161 NETMGR_EXT_LOG_E("cfg is nullptr");
162 return ETHERNET_ERR_DEVICE_CONFIGURATION_INVALID;
163 }
164 std::unique_lock<std::mutex> lock(mutex_);
165 auto fit = devs_.find(iface);
166 if (fit == devs_.end() || fit->second == nullptr) {
167 NETMGR_EXT_LOG_E("The iface[%{public}s] device or device information does not exist", iface.c_str());
168 return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
169 }
170 if (!fit->second->GetLinkUp()) {
171 NETMGR_EXT_LOG_E("The iface[%{public}s] device is unlink", iface.c_str());
172 return ETHERNET_ERR_DEVICE_NOT_LINK;
173 }
174 if (!ethConfiguration_->WriteUserConfiguration(iface, cfg)) {
175 NETMGR_EXT_LOG_E("EthernetManagement write user configurations error!");
176 return ETHERNET_ERR_USER_CONIFGURATION_WRITE_FAIL;
177 }
178 if (fit->second->GetIfcfg()->mode_ != cfg->mode_) {
179 if (cfg->mode_ == DHCP) {
180 StartDhcpClient(iface, fit->second);
181 } else {
182 StopDhcpClient(iface, fit->second);
183 }
184 }
185 fit->second->SetIfcfg(cfg);
186 return NETMANAGER_EXT_SUCCESS;
187 }
188
UpdateDevInterfaceLinkInfo(EthernetDhcpCallback::DhcpResult & dhcpResult)189 int32_t EthernetManagement::UpdateDevInterfaceLinkInfo(EthernetDhcpCallback::DhcpResult &dhcpResult)
190 {
191 NETMGR_EXT_LOG_D("EthernetManagement::UpdateDevInterfaceLinkInfo");
192 auto fit = devs_.find(dhcpResult.iface);
193 if (fit == devs_.end() || fit->second == nullptr) {
194 NETMGR_EXT_LOG_E("The iface[%{public}s] device or device information does not exist", dhcpResult.iface.c_str());
195 return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
196 }
197 if (!fit->second->GetLinkUp()) {
198 NETMGR_EXT_LOG_E("The iface[%{public}s] The device is not turned on", dhcpResult.iface.c_str());
199 return ETHERNET_ERR_DEVICE_NOT_LINK;
200 }
201 sptr<StaticConfiguration> config = new (std::nothrow) StaticConfiguration();
202 if (config == nullptr) {
203 NETMGR_EXT_LOG_E("config is nullptr");
204 return ETHERNET_ERR_EMPTY_CONFIGURATION;
205 }
206
207 if (!ethConfiguration_->ConvertToConfiguration(dhcpResult, config)) {
208 NETMGR_EXT_LOG_E("EthernetManagement dhcp convert to configurations error!");
209 return ETHERNET_ERR_CONVERT_CONFIGURATINO_FAIL;
210 }
211 fit->second->UpdateLinkInfo(config->ipAddr_, config->netMask_, config->gateway_, config->route_,
212 config->dnsServers_.front(), config->dnsServers_.back());
213 fit->second->RemoteUpdateNetLinkInfo();
214 return NETMANAGER_EXT_SUCCESS;
215 }
216
GetDevInterfaceCfg(const std::string & iface,sptr<InterfaceConfiguration> & ifaceConfig)217 int32_t EthernetManagement::GetDevInterfaceCfg(const std::string &iface, sptr<InterfaceConfiguration> &ifaceConfig)
218 {
219 std::unique_lock<std::mutex> lock(mutex_);
220 auto fit = devs_.find(iface);
221 if (fit == devs_.end() || fit->second == nullptr) {
222 NETMGR_EXT_LOG_E("The iface[%{public}s] device does not exist", iface.c_str());
223 return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
224 }
225 if (!fit->second->GetLinkUp()) {
226 ifaceConfig = fit->second->GetIfcfg();
227 return NETMANAGER_EXT_SUCCESS;
228 }
229 auto temp = ethConfiguration_->MakeInterfaceConfiguration(fit->second->GetIfcfg(), fit->second->GetLinkInfo());
230 *ifaceConfig = *temp;
231 return NETMANAGER_EXT_SUCCESS;
232 }
233
IsIfaceActive(const std::string & iface,int32_t & activeStatus)234 int32_t EthernetManagement::IsIfaceActive(const std::string &iface, int32_t &activeStatus)
235 {
236 std::unique_lock<std::mutex> lock(mutex_);
237 auto fit = devs_.find(iface);
238 if (fit == devs_.end() || fit->second == nullptr) {
239 NETMGR_EXT_LOG_E("The iface[%{public}s] device does not exist", iface.c_str());
240 return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
241 }
242 activeStatus = static_cast<int32_t>(fit->second->GetLinkUp());
243 return NETMANAGER_EXT_SUCCESS;
244 }
245
GetAllActiveIfaces(std::vector<std::string> & activeIfaces)246 int32_t EthernetManagement::GetAllActiveIfaces(std::vector<std::string> &activeIfaces)
247 {
248 std::unique_lock<std::mutex> lock(mutex_);
249 for (auto it = devs_.begin(); it != devs_.end(); ++it) {
250 if (it->second->GetLinkUp()) {
251 activeIfaces.push_back(it->first);
252 }
253 }
254 return NETMANAGER_EXT_SUCCESS;
255 }
256
ResetFactory()257 int32_t EthernetManagement::ResetFactory()
258 {
259 if (!ethConfiguration_->ClearAllUserConfiguration()) {
260 NETMGR_EXT_LOG_E("Failed to ResetFactory!");
261 return ETHERNET_ERR_USER_CONIFGURATION_CLEAR_FAIL;
262 }
263 NETMGR_EXT_LOG_I("Success to ResetFactory!");
264 return NETMANAGER_EXT_SUCCESS;
265 }
266
Init()267 void EthernetManagement::Init()
268 {
269 std::regex re(IFACE_MATCH);
270 std::vector<std::string> ifaces = NetsysController::GetInstance().InterfaceGetList();
271 if (ifaces.empty()) {
272 NETMGR_EXT_LOG_E("EthernetManagement link list is empty");
273 return;
274 }
275 NETMGR_EXT_LOG_D("EthernetManagement devs size[%{public}zd]", ifaces.size());
276 if (!ethConfiguration_->ReadUserConfiguration(devCfgs_)) {
277 NETMGR_EXT_LOG_E("EthernetManagement read user configurations error! ");
278 return;
279 }
280 for (const auto &devName : ifaces) {
281 NETMGR_EXT_LOG_D("EthernetManagement devName[%{public}s]", devName.c_str());
282 if (!std::regex_search(devName, re)) {
283 continue;
284 }
285 DevInterfaceAdd(devName);
286 }
287 std::thread t(&EthernetManagement::StartSetDevUpThd, this);
288 t.detach();
289 NETMGR_EXT_LOG_D("EthernetManagement devs_ size[%{public}zd", devs_.size());
290 }
291
StartSetDevUpThd()292 void EthernetManagement::StartSetDevUpThd()
293 {
294 NETMGR_EXT_LOG_D("EthernetManagement StartSetDevUpThd in.");
295 for (auto &dev : devs_) {
296 std::string devName = dev.first;
297 while (true) {
298 if (NetsysController::GetInstance().SetInterfaceUp(devName) != ERR_NONE) {
299 sleep(SLEEP_TIME_S);
300 continue;
301 }
302 break;
303 }
304 }
305 }
306
StartDhcpClient(const std::string & dev,sptr<DevInterfaceState> & devState)307 void EthernetManagement::StartDhcpClient(const std::string &dev, sptr<DevInterfaceState> &devState)
308 {
309 NETMGR_EXT_LOG_D("EthernetManagement StartDhcpClient[%{public}s]", dev.c_str());
310 ethDhcpController_->StartDhcpClient(dev, false);
311 devState->SetDhcpReqState(true);
312 }
313
StopDhcpClient(const std::string & dev,sptr<DevInterfaceState> & devState)314 void EthernetManagement::StopDhcpClient(const std::string &dev, sptr<DevInterfaceState> &devState)
315 {
316 NETMGR_EXT_LOG_D("EthernetManagement StopDhcpClient[%{public}s]", dev.c_str());
317 ethDhcpController_->StopDhcpClient(dev, false);
318 devState->SetDhcpReqState(false);
319 }
320
DevInterfaceAdd(const std::string & devName)321 void EthernetManagement::DevInterfaceAdd(const std::string &devName)
322 {
323 NETMGR_EXT_LOG_D("Interface name:[%{public}s] add.", devName.c_str());
324 std::unique_lock<std::mutex> lock(mutex_);
325 auto fitDev = devs_.find(devName);
326 if (fitDev != devs_.end()) {
327 NETMGR_EXT_LOG_D("Interface name:[%{public}s] has added.", devName.c_str());
328 return;
329 }
330 sptr<DevInterfaceState> devState = new (std::nothrow) DevInterfaceState();
331 if (devState == nullptr) {
332 NETMGR_EXT_LOG_E("devState is nullptr");
333 return;
334 }
335 devs_.insert(std::make_pair(devName, devState));
336 devState->SetDevName(devName);
337 devState->RemoteRegisterNetSupplier();
338 auto fitCfg = devCfgs_.find(devName);
339 if (fitCfg != devCfgs_.end()) {
340 devState->SetIfcfg(fitCfg->second);
341 } else {
342 sptr<InterfaceConfiguration> ifCfg = new (std::nothrow) InterfaceConfiguration();
343 if (ifCfg == nullptr) {
344 NETMGR_EXT_LOG_E("ifCfg is nullptr");
345 return;
346 }
347 ifCfg->mode_ = DHCP;
348 devState->SetIfcfg(ifCfg);
349 }
350 auto fitCap = devCaps_.find(devName);
351 if (fitCap != devCaps_.end()) {
352 devState->SetNetCaps(fitCap->second);
353 }
354 }
355
DevInterfaceRemove(const std::string & devName)356 void EthernetManagement::DevInterfaceRemove(const std::string &devName)
357 {
358 NETMGR_EXT_LOG_D("Interface name:[%{public}s] remove.", devName.c_str());
359 std::unique_lock<std::mutex> lock(mutex_);
360 auto fitDev = devs_.find(devName);
361 if (fitDev != devs_.end()) {
362 devs_.erase(fitDev);
363 }
364 }
365
GetDumpInfo(std::string & info)366 void EthernetManagement::GetDumpInfo(std::string &info)
367 {
368 std::for_each(devs_.begin(), devs_.end(), [&info](const auto &dev) { dev.second->GetDumpInfo(info); });
369 }
370 } // namespace NetManagerStandard
371 } // namespace OHOS
372