• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 <pthread.h>
21 #include <unistd.h>
22 
23 #include "net_manager_constants.h"
24 #include "netmgr_ext_log_wrapper.h"
25 #include "netsys_controller.h"
26 #include "securec.h"
27 
28 namespace OHOS {
29 namespace NetManagerStandard {
30 const std::string IFACE_MATCH = "eth\\d";
31 constexpr const char *IFACE_LINK_UP = "up";
32 constexpr const char *IFACE_RUNNING = "running";
33 constexpr int SLEEP_TIME_S = 2;
OnDhcpSuccess(EthernetDhcpCallback::DhcpResult & dhcpResult)34 int32_t EthernetManagement::EhternetDhcpNotifyCallback::OnDhcpSuccess(EthernetDhcpCallback::DhcpResult &dhcpResult)
35 {
36     ethernetManagement_.UpdateDevInterfaceLinkInfo(dhcpResult);
37     return 0;
38 }
39 
OnInterfaceAddressUpdated(const std::string &,const std::string &,int,int)40 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceAddressUpdated(const std::string &,
41                                                                                  const std::string &, int, int)
42 {
43     return 0;
44 }
45 
OnInterfaceAddressRemoved(const std::string &,const std::string &,int,int)46 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceAddressRemoved(const std::string &,
47                                                                                  const std::string &, int, int)
48 {
49     return 0;
50 }
51 
OnInterfaceAdded(const std::string & iface)52 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceAdded(const std::string &iface)
53 {
54     std::regex re(IFACE_MATCH);
55     if (std::regex_search(iface, re)) {
56         ethernetManagement_.DevInterfaceAdd(iface);
57         if (NetsysController::GetInstance().SetInterfaceUp(iface) != ERR_NONE) {
58             NETMGR_EXT_LOG_E("Iface[%{public}s] added set up fail!", iface.c_str());
59         }
60     }
61     return 0;
62 }
63 
OnInterfaceRemoved(const std::string & iface)64 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceRemoved(const std::string &iface)
65 {
66     std::regex re(IFACE_MATCH);
67     if (std::regex_search(iface, re)) {
68         ethernetManagement_.DevInterfaceRemove(iface);
69         if (NetsysController::GetInstance().SetInterfaceDown(iface) != ERR_NONE) {
70             NETMGR_EXT_LOG_E("Iface[%{public}s] added set down fail!", iface.c_str());
71         }
72     }
73     return 0;
74 }
75 
OnInterfaceChanged(const std::string &,bool)76 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceChanged(const std::string &, bool)
77 {
78     return 0;
79 }
80 
OnInterfaceLinkStateChanged(const std::string & ifName,bool up)81 int32_t EthernetManagement::DevInterfaceStateCallback::OnInterfaceLinkStateChanged(const std::string &ifName, bool up)
82 {
83     NETMGR_EXT_LOG_I("DevInterfaceStateCallback::OnInterfaceLinkStateChanged iface[%{public}s] up[%{public}d]",
84                      ifName.c_str(), up);
85     std::regex re(IFACE_MATCH);
86     if (std::regex_search(ifName, re)) {
87         ethernetManagement_.UpdateInterfaceState(ifName, up);
88     }
89     return 0;
90 }
91 
OnRouteChanged(bool,const std::string &,const std::string &,const std::string &)92 int32_t EthernetManagement::DevInterfaceStateCallback::OnRouteChanged(bool, const std::string &, const std::string &,
93                                                                       const std::string &)
94 {
95     return 0;
96 }
97 
OnDhcpSuccess(NetsysControllerCallback::DhcpResult & dhcpResult)98 int32_t EthernetManagement::DevInterfaceStateCallback::OnDhcpSuccess(NetsysControllerCallback::DhcpResult &dhcpResult)
99 {
100     return 0;
101 }
102 
OnBandwidthReachedLimit(const std::string & limitName,const std::string & iface)103 int32_t EthernetManagement::DevInterfaceStateCallback::OnBandwidthReachedLimit(const std::string &limitName,
104                                                                                const std::string &iface)
105 {
106     return 0;
107 }
108 
EthernetManagement()109 EthernetManagement::EthernetManagement()
110 {
111     ethDhcpController_ = std::make_unique<EthernetDhcpController>();
112     ethDhcpNotifyCallback_ = new (std::nothrow) EhternetDhcpNotifyCallback(*this);
113     if (ethDhcpNotifyCallback_ != nullptr) {
114         ethDhcpController_->RegisterDhcpCallback(ethDhcpNotifyCallback_);
115     }
116 
117     ethDevInterfaceStateCallback_ = new (std::nothrow) DevInterfaceStateCallback(*this);
118     if (ethDevInterfaceStateCallback_ != nullptr) {
119         NetsysController::GetInstance().RegisterCallback(ethDevInterfaceStateCallback_);
120     }
121 
122     ethConfiguration_ = std::make_unique<EthernetConfiguration>();
123     ethConfiguration_->ReadSystemConfiguration(devCaps_, devCfgs_);
124     ethLanManageMent_ = std::make_unique<EthernetLanManagement>();
125 }
126 
127 EthernetManagement::~EthernetManagement() = default;
128 
UpdateInterfaceState(const std::string & dev,bool up)129 void EthernetManagement::UpdateInterfaceState(const std::string &dev, bool up)
130 {
131     NETMGR_EXT_LOG_D("EthernetManagement UpdateInterfaceState dev[%{public}s] up[%{public}d]", dev.c_str(), up);
132     std::unique_lock<std::mutex> lock(mutex_);
133     auto fit = devs_.find(dev);
134     if (fit == devs_.end()) {
135         return;
136     }
137     sptr<DevInterfaceState> devState = fit->second;
138     if (devState == nullptr) {
139         NETMGR_EXT_LOG_E("devState is nullptr");
140         return;
141     }
142     devState->SetLinkUp(up);
143     IPSetMode mode = devState->GetIPSetMode();
144     bool dhcpReqState = devState->GetDhcpReqState();
145     NETMGR_EXT_LOG_D("EthernetManagement UpdateInterfaceState mode[%{public}d] dhcpReqState[%{public}d]",
146                      static_cast<int32_t>(mode), dhcpReqState);
147     if (up) {
148         if (!devState->IsLanIface()) {
149             devState->RemoteUpdateNetSupplierInfo();
150         }
151         if ((mode == DHCP || mode == LAN_DHCP) && !dhcpReqState) {
152             StartDhcpClient(dev, devState);
153         } else {
154             if (devState->IsLanIface()) {
155                 ethLanManageMent_->UpdateLanLinkInfo(devState);
156             } else {
157                 devState->RemoteUpdateNetLinkInfo();
158             }
159         }
160     } else {
161         if ((mode == DHCP || mode == LAN_DHCP) && dhcpReqState) {
162             StopDhcpClient(dev, devState);
163         }
164         if (devState->IsLanIface()) {
165             ethLanManageMent_->ReleaseLanNetLink(devState);
166         } else {
167             devState->RemoteUpdateNetSupplierInfo();
168         }
169         netLinkConfigs_[dev] = nullptr;
170     }
171 }
172 
UpdateDevInterfaceCfg(const std::string & iface,sptr<InterfaceConfiguration> cfg)173 int32_t EthernetManagement::UpdateDevInterfaceCfg(const std::string &iface, sptr<InterfaceConfiguration> cfg)
174 {
175     if (cfg == nullptr) {
176         NETMGR_EXT_LOG_E("cfg is nullptr");
177         return NETMANAGER_EXT_ERR_LOCAL_PTR_NULL;
178     }
179     std::unique_lock<std::mutex> lock(mutex_);
180     auto fit = devs_.find(iface);
181     if (fit == devs_.end() || fit->second == nullptr) {
182         NETMGR_EXT_LOG_E("The iface[%{public}s] device or device information does not exist", iface.c_str());
183         return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
184     }
185     if (!fit->second->GetLinkUp()) {
186         NETMGR_EXT_LOG_E("The iface[%{public}s] device is unlink", iface.c_str());
187         return ETHERNET_ERR_DEVICE_NOT_LINK;
188     }
189     if (!ModeInputCheck(fit->second->GetIfcfg()->mode_, cfg->mode_)) {
190         NETMGR_EXT_LOG_E("The iface[%{public}s] device can not exchange between WAN and LAN", iface.c_str());
191         return NETMANAGER_ERR_INVALID_PARAMETER;
192     }
193     if (!ethConfiguration_->WriteUserConfiguration(iface, cfg)) {
194         NETMGR_EXT_LOG_E("EthernetManagement write user configurations error!");
195         return ETHERNET_ERR_USER_CONIFGURATION_WRITE_FAIL;
196     }
197     if (fit->second->GetIfcfg()->mode_ != cfg->mode_) {
198         if (cfg->mode_ == DHCP || cfg->mode_ == LAN_DHCP) {
199             StartDhcpClient(iface, fit->second);
200         } else {
201             StopDhcpClient(iface, fit->second);
202             netLinkConfigs_[iface] = nullptr;
203         }
204     } else if (cfg->mode_ == DHCP) {
205         fit->second->UpdateNetHttpProxy(cfg->httpProxy_);
206     }
207     if (fit->second->IsLanIface()) {
208         ethLanManageMent_->GetOldLinkInfo(fit->second);
209         fit->second->SetLancfg(cfg);
210         ethLanManageMent_->UpdateLanLinkInfo(fit->second);
211     } else {
212         fit->second->SetIfcfg(cfg);
213     }
214     devCfgs_[iface] = cfg;
215     return NETMANAGER_EXT_SUCCESS;
216 }
217 
UpdateDevInterfaceLinkInfo(EthernetDhcpCallback::DhcpResult & dhcpResult)218 int32_t EthernetManagement::UpdateDevInterfaceLinkInfo(EthernetDhcpCallback::DhcpResult &dhcpResult)
219 {
220     NETMGR_EXT_LOG_D("EthernetManagement::UpdateDevInterfaceLinkInfo");
221     std::lock_guard<std::mutex> locker(mutex_);
222     auto fit = devs_.find(dhcpResult.iface);
223     if (fit == devs_.end() || fit->second == nullptr) {
224         NETMGR_EXT_LOG_E("The iface[%{public}s] device or device information does not exist", dhcpResult.iface.c_str());
225         return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
226     }
227     if (!fit->second->GetLinkUp()) {
228         NETMGR_EXT_LOG_E("The iface[%{public}s] The device is not turned on", dhcpResult.iface.c_str());
229         return ETHERNET_ERR_DEVICE_NOT_LINK;
230     }
231 
232     IPSetMode mode = fit->second->GetIPSetMode();
233     if (mode == IPSetMode::STATIC || mode == IPSetMode::LAN_STATIC) {
234         NETMGR_EXT_LOG_E("The iface[%{public}s] set mode is STATIC now", dhcpResult.iface.c_str());
235         return ETHERNET_ERR_DEVICE_NOT_LINK;
236     }
237 
238     auto &config = netLinkConfigs_[dhcpResult.iface];
239     if (config == nullptr) {
240         config = new (std::nothrow) StaticConfiguration();
241         if (config == nullptr) {
242             NETMGR_EXT_LOG_E("Iface:%{public}s's link info config is nullptr", dhcpResult.iface.c_str());
243         }
244     }
245 
246     if (!ethConfiguration_->ConvertToConfiguration(dhcpResult, config)) {
247         NETMGR_EXT_LOG_E("EthernetManagement dhcp convert to configurations error!");
248         return ETHERNET_ERR_CONVERT_CONFIGURATINO_FAIL;
249     }
250     if (fit->second->IsLanIface()) {
251         ethLanManageMent_->GetOldLinkInfo(fit->second);
252         fit->second->UpdateLanLinkInfo(config);
253         ethLanManageMent_->UpdateLanLinkInfo(fit->second);
254     } else {
255         fit->second->UpdateLinkInfo(config);
256         fit->second->RemoteUpdateNetLinkInfo();
257     }
258     return NETMANAGER_EXT_SUCCESS;
259 }
260 
GetDevInterfaceCfg(const std::string & iface,sptr<InterfaceConfiguration> & ifaceConfig)261 int32_t EthernetManagement::GetDevInterfaceCfg(const std::string &iface, sptr<InterfaceConfiguration> &ifaceConfig)
262 {
263     std::unique_lock<std::mutex> lock(mutex_);
264     auto fit = devs_.find(iface);
265     if (fit == devs_.end() || fit->second == nullptr) {
266         NETMGR_EXT_LOG_E("The iface[%{public}s] device does not exist", iface.c_str());
267         return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
268     }
269     if (!fit->second->GetLinkUp()) {
270         ifaceConfig = fit->second->GetIfcfg();
271         return NETMANAGER_EXT_SUCCESS;
272     }
273     auto temp = ethConfiguration_->MakeInterfaceConfiguration(fit->second->GetIfcfg(), fit->second->GetLinkInfo());
274     if (temp == nullptr) {
275         return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
276     }
277     *ifaceConfig = *temp;
278     return NETMANAGER_EXT_SUCCESS;
279 }
280 
IsIfaceActive(const std::string & iface,int32_t & activeStatus)281 int32_t EthernetManagement::IsIfaceActive(const std::string &iface, int32_t &activeStatus)
282 {
283     std::unique_lock<std::mutex> lock(mutex_);
284     auto fit = devs_.find(iface);
285     if (fit == devs_.end() || fit->second == nullptr) {
286         NETMGR_EXT_LOG_E("The iface[%{public}s] device does not exist", iface.c_str());
287         return ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST;
288     }
289     activeStatus = static_cast<int32_t>(fit->second->GetLinkUp());
290     return NETMANAGER_EXT_SUCCESS;
291 }
292 
GetAllActiveIfaces(std::vector<std::string> & activeIfaces)293 int32_t EthernetManagement::GetAllActiveIfaces(std::vector<std::string> &activeIfaces)
294 {
295     std::unique_lock<std::mutex> lock(mutex_);
296     for (auto it = devs_.begin(); it != devs_.end(); ++it) {
297         if (it->second->GetLinkUp()) {
298             activeIfaces.push_back(it->first);
299         }
300     }
301     return NETMANAGER_EXT_SUCCESS;
302 }
303 
ResetFactory()304 int32_t EthernetManagement::ResetFactory()
305 {
306     if (!ethConfiguration_->ClearAllUserConfiguration()) {
307         NETMGR_EXT_LOG_E("Failed to ResetFactory!");
308         return ETHERNET_ERR_USER_CONIFGURATION_CLEAR_FAIL;
309     }
310     NETMGR_EXT_LOG_I("Success to ResetFactory!");
311     return NETMANAGER_EXT_SUCCESS;
312 }
313 
Init()314 void EthernetManagement::Init()
315 {
316     std::regex re(IFACE_MATCH);
317     std::vector<std::string> ifaces = NetsysController::GetInstance().InterfaceGetList();
318     if (ifaces.empty()) {
319         NETMGR_EXT_LOG_E("EthernetManagement link list is empty");
320         return;
321     }
322     NETMGR_EXT_LOG_D("EthernetManagement devs size[%{public}zd]", ifaces.size());
323     if (!ethConfiguration_->ReadUserConfiguration(devCfgs_)) {
324         NETMGR_EXT_LOG_E("EthernetManagement read user configurations error! ");
325         return;
326     }
327     for (const auto &devName : ifaces) {
328         NETMGR_EXT_LOG_D("EthernetManagement devName[%{public}s]", devName.c_str());
329         if (!std::regex_search(devName, re)) {
330             continue;
331         }
332         DevInterfaceAdd(devName);
333     }
334     std::thread t(&EthernetManagement::StartSetDevUpThd, shared_from_this());
335     std::string threadName = "SetDevUpThd";
336     pthread_setname_np(t.native_handle(), threadName.c_str());
337     t.detach();
338     NETMGR_EXT_LOG_D("EthernetManagement devs_ size[%{public}zd", devs_.size());
339 }
340 
StartSetDevUpThd()341 void EthernetManagement::StartSetDevUpThd()
342 {
343     NETMGR_EXT_LOG_D("EthernetManagement StartSetDevUpThd in.");
344     for (auto &dev : devs_) {
345         std::string devName = dev.first;
346         if (IsIfaceLinkUp(devName)) {
347             continue;
348         }
349         while (true) {
350             if (NetsysController::GetInstance().SetInterfaceUp(devName) != ERR_NONE) {
351                 sleep(SLEEP_TIME_S);
352                 continue;
353             }
354             break;
355         }
356     }
357 }
358 
IsIfaceLinkUp(const std::string & iface)359 bool EthernetManagement::IsIfaceLinkUp(const std::string &iface)
360 {
361     OHOS::nmd::InterfaceConfigurationParcel config;
362     config.ifName = iface;
363     if (NetsysController::GetInstance().GetInterfaceConfig(config) != ERR_NONE) {
364         return false;
365     }
366     if (std::find(config.flags.begin(), config.flags.end(), IFACE_LINK_UP) == config.flags.end() ||
367         std::find(config.flags.begin(), config.flags.end(), IFACE_RUNNING) == config.flags.end()) {
368         return false;
369     }
370     UpdateInterfaceState(iface, true);
371     return true;
372 }
373 
StartDhcpClient(const std::string & dev,sptr<DevInterfaceState> & devState)374 void EthernetManagement::StartDhcpClient(const std::string &dev, sptr<DevInterfaceState> &devState)
375 {
376     NETMGR_EXT_LOG_D("EthernetManagement StartDhcpClient[%{public}s]", dev.c_str());
377     ethDhcpController_->StartClient(dev, true);
378     devState->SetDhcpReqState(true);
379 }
380 
StopDhcpClient(const std::string & dev,sptr<DevInterfaceState> & devState)381 void EthernetManagement::StopDhcpClient(const std::string &dev, sptr<DevInterfaceState> &devState)
382 {
383     NETMGR_EXT_LOG_D("EthernetManagement StopDhcpClient[%{public}s]", dev.c_str());
384     ethDhcpController_->StopClient(dev, true);
385     devState->SetDhcpReqState(false);
386 }
387 
DevInterfaceAdd(const std::string & devName)388 void EthernetManagement::DevInterfaceAdd(const std::string &devName)
389 {
390     NETMGR_EXT_LOG_D("Interface name:[%{public}s] add.", devName.c_str());
391     std::unique_lock<std::mutex> lock(mutex_);
392     auto fitDev = devs_.find(devName);
393     if (fitDev != devs_.end()) {
394         NETMGR_EXT_LOG_E("Interface name:[%{public}s] has added.", devName.c_str());
395         return;
396     }
397     sptr<DevInterfaceState> devState = new (std::nothrow) DevInterfaceState();
398     if (devState == nullptr) {
399         NETMGR_EXT_LOG_E("devState is nullptr");
400         return;
401     }
402     ethConfiguration_->ReadSystemConfiguration(devCaps_, devCfgs_);
403     devs_.insert(std::make_pair(devName, devState));
404     devState->SetDevName(devName);
405     auto fitCfg = devCfgs_.find(devName);
406     if (fitCfg != devCfgs_.end()) {
407         if (fitCfg->second->mode_ == LAN_STATIC || fitCfg->second->mode_ == LAN_DHCP) {
408             NETMGR_EXT_LOG_D("Lan Interface name:[%{public}s] add, mode [%{public}d]",
409                              devName.c_str(), fitCfg->second->mode_);
410             devState->SetLancfg(fitCfg->second);
411             ethLanManageMent_->UpdateLanLinkInfo(devState);
412             return;
413         }
414         devState->RemoteRegisterNetSupplier();
415         devState->SetIfcfg(fitCfg->second);
416     } else {
417         sptr<InterfaceConfiguration> ifCfg = new (std::nothrow) InterfaceConfiguration();
418         if (ifCfg == nullptr) {
419             NETMGR_EXT_LOG_E("ifCfg is nullptr");
420             return;
421         }
422         ifCfg->mode_ = DHCP;
423         devState->RemoteRegisterNetSupplier();
424         devState->SetIfcfg(ifCfg);
425     }
426     auto fitCap = devCaps_.find(devName);
427     if (fitCap != devCaps_.end()) {
428         devState->SetNetCaps(fitCap->second);
429     }
430 }
431 
DevInterfaceRemove(const std::string & devName)432 void EthernetManagement::DevInterfaceRemove(const std::string &devName)
433 {
434     NETMGR_EXT_LOG_D("Interface name:[%{public}s] remove.", devName.c_str());
435     std::unique_lock<std::mutex> lock(mutex_);
436     auto fitDev = devs_.find(devName);
437     if (fitDev != devs_.end()) {
438         if (fitDev->second != nullptr) {
439             fitDev->second->RemoteUnregisterNetSupplier();
440         }
441         devs_.erase(fitDev);
442     }
443 }
444 
GetDumpInfo(std::string & info)445 void EthernetManagement::GetDumpInfo(std::string &info)
446 {
447     std::for_each(devs_.begin(), devs_.end(), [&info](const auto &dev) { dev.second->GetDumpInfo(info); });
448 }
449 
ModeInputCheck(IPSetMode origin,IPSetMode input)450 bool EthernetManagement::ModeInputCheck(IPSetMode origin, IPSetMode input)
451 {
452     if (origin == STATIC || origin == DHCP) {
453         if (input == LAN_STATIC || input == LAN_DHCP) {
454             return false;
455         }
456     } else if (origin == LAN_STATIC || origin == LAN_DHCP) {
457         if (input == STATIC || input == DHCP) {
458             return false;
459         }
460     }
461     return true;
462 }
463 } // namespace NetManagerStandard
464 } // namespace OHOS
465