blob: 4525e34c431fe90b93e2c0c652154c8147ac2eb2 [file] [log] [blame]
Ratan Gupta6811f822017-04-14 16:34:56 +05301#include "config.h"
Ratan Gupta3681a502017-06-17 19:20:04 +05302#include "util.hpp"
Ratan Gupta6811f822017-04-14 16:34:56 +05303#include "network_manager.hpp"
Michael Tritz29f2fd62017-05-22 15:27:26 -05004#include "network_config.hpp"
Ratan Gupta5978dd12017-07-25 13:47:13 +05305#include "ipaddress.hpp"
Ratan Guptae05083a2017-09-16 07:12:11 +05306#include "timer.hpp"
Ratan Gupta44ae86e2017-05-15 21:52:14 +05307#include "xyz/openbmc_project/Common/error.hpp"
Ratan Gupta6811f822017-04-14 16:34:56 +05308
9#include <phosphor-logging/log.hpp>
Ratan Gupta44ae86e2017-05-15 21:52:14 +053010#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta6811f822017-04-14 16:34:56 +053011
12#include <algorithm>
Ratan Gupta738a67f2017-04-21 10:38:05 +053013#include <bitset>
Ratan Gupta738a67f2017-04-21 10:38:05 +053014#include <map>
Ratan Gupta4f1c18b2017-05-25 12:59:35 +053015#include <fstream>
Ratan Gupta738a67f2017-04-21 10:38:05 +053016
Ratan Gupta6811f822017-04-14 16:34:56 +053017#include <arpa/inet.h>
18#include <dirent.h>
19#include <net/if.h>
20
Michael Tritz29f2fd62017-05-22 15:27:26 -050021#include <string>
Ratan Gupta6811f822017-04-14 16:34:56 +053022
23namespace phosphor
24{
25namespace network
26{
Ratan Gupta82549cc2017-04-21 08:45:23 +053027
Ratan Guptae05083a2017-09-16 07:12:11 +053028extern std::unique_ptr<phosphor::network::Timer> refreshTimer;
Ratan Gupta6811f822017-04-14 16:34:56 +053029using namespace phosphor::logging;
Ratan Guptaef85eb92017-06-15 08:57:54 +053030using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta6811f822017-04-14 16:34:56 +053031
Ratan Gupta255d5142017-08-10 09:02:08 +053032Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath,
33 const std::string& path):
Ratan Gupta29b0e432017-05-25 12:51:40 +053034 details::VLANCreateIface(bus, objPath, true),
35 bus(bus),
36 objectPath(objPath)
Ratan Gupta6811f822017-04-14 16:34:56 +053037{
Ratan Gupta255d5142017-08-10 09:02:08 +053038 fs::path confDir(path);
39 setConfDir(confDir);
Ratan Guptaef85eb92017-06-15 08:57:54 +053040}
41
42void Manager::setConfDir(const fs::path& dir)
43{
44 confDir = dir;
Ratan Gupta255d5142017-08-10 09:02:08 +053045
46 if (!fs::exists(confDir))
47 {
48 if (!fs::create_directories(confDir))
49 {
50 log<level::ERR>("Unable to create the network conf dir",
51 entry("DIR=%s", confDir.c_str()));
52 elog<InternalFailure>();
53 }
54 }
55
Ratan Gupta29b0e432017-05-25 12:51:40 +053056}
57
58void Manager::createInterfaces()
59{
Ratan Guptaef85eb92017-06-15 08:57:54 +053060 //clear all the interfaces first
61 interfaces.clear();
Ratan Gupta29b0e432017-05-25 12:51:40 +053062
Ratan Guptafd4b0f02017-09-16 06:01:24 +053063 auto interfaceStrList = getInterfaces();
Ratan Gupta6811f822017-04-14 16:34:56 +053064
Ratan Guptafd4b0f02017-09-16 06:01:24 +053065 for (auto& interface : interfaceStrList)
Ratan Gupta6811f822017-04-14 16:34:56 +053066 {
Ratan Gupta29b0e432017-05-25 12:51:40 +053067 fs::path objPath = objectPath;
Ratan Guptafd4b0f02017-09-16 06:01:24 +053068 auto index = interface.find(".");
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053069
70 // interface can be of vlan type or normal ethernet interface.
71 // vlan interface looks like "interface.vlanid",so here by looking
72 // at the interface name we decide that we need
73 // to create the vlaninterface or normal physical interface.
74 if (index != std::string::npos)
75 {
76 //it is vlan interface
Ratan Guptafd4b0f02017-09-16 06:01:24 +053077 auto interfaceName = interface.substr(0, index);
78 auto vlanid = interface.substr(index + 1);
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053079 uint32_t vlanInt = std::stoul(vlanid);
80
Ratan Guptafd4b0f02017-09-16 06:01:24 +053081 interfaces[interfaceName]->loadVLAN(vlanInt);
Ratan Gupta6e8df632017-08-13 09:41:58 +053082 continue;
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053083 }
Ratan Guptafd4b0f02017-09-16 06:01:24 +053084 // normal ethernet interface
85 objPath /= interface;
Ratan Gupta6811f822017-04-14 16:34:56 +053086
Ratan Guptafd4b0f02017-09-16 06:01:24 +053087 auto dhcp = getDHCPValue(confDir, interface);
Ratan Gupta34f96d62017-06-15 09:16:22 +053088
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053089 auto intf = std::make_shared<phosphor::network::EthernetInterface>(
90 bus,
91 objPath.string(),
92 dhcp,
93 *this);
94
95
96 intf->createIPAddressObjects();
97
Ratan Gupta6811f822017-04-14 16:34:56 +053098 this->interfaces.emplace(std::make_pair(
Ratan Guptafd4b0f02017-09-16 06:01:24 +053099 std::move(interface), std::move(intf)));
Ratan Gupta29b0e432017-05-25 12:51:40 +0530100
Ratan Gupta6811f822017-04-14 16:34:56 +0530101 }
Ratan Gupta87c13982017-06-15 09:27:27 +0530102
Ratan Gupta6811f822017-04-14 16:34:56 +0530103}
104
Ratan Guptaef85eb92017-06-15 08:57:54 +0530105void Manager::createChildObjects()
106{
107 // creates the ethernet interface dbus object.
108 createInterfaces();
Ratan Guptae05083a2017-09-16 07:12:11 +0530109
110 systemConf.reset(nullptr);
111 dhcpConf.reset(nullptr);
112
Ratan Guptaef85eb92017-06-15 08:57:54 +0530113 fs::path objPath = objectPath;
114 objPath /= "config";
Ratan Guptae05083a2017-09-16 07:12:11 +0530115
116 // create the system conf object.
Ratan Guptaef85eb92017-06-15 08:57:54 +0530117 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
118 bus, objPath.string(), *this);
Ratan Guptad16f88c2017-07-11 17:47:57 +0530119 // create the dhcp conf object.
120 objPath /= "dhcp";
121 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
122 bus, objPath.string(), *this);
Ratan Guptaef85eb92017-06-15 08:57:54 +0530123
124}
125
Ratan Gupta584df832017-07-31 16:21:54 +0530126void Manager::vLAN(IntfName interfaceName, uint32_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +0530127{
Ratan Gupta2b106532017-07-25 16:05:02 +0530128 interfaces[interfaceName]->createVLAN(id);
Ratan Gupta6811f822017-04-14 16:34:56 +0530129}
130
Michael Tritz29f2fd62017-05-22 15:27:26 -0500131void Manager::reset()
132{
Ratan Gupta1bc8ed32017-07-25 22:34:19 +0530133 const std::string networkConfig = confDir.string();
134 bool interfacesMapped = false;
Michael Tritz29f2fd62017-05-22 15:27:26 -0500135
136 if(fs::is_directory(networkConfig))
137 {
138 for(auto& file : fs::directory_iterator(networkConfig))
139 {
Ratan Gupta1bc8ed32017-07-25 22:34:19 +0530140 fs::remove(file.path());
Michael Tritz29f2fd62017-05-22 15:27:26 -0500141 }
142
143 for (auto& intf : interfaces)
144 {
Ratan Gupta4f67dac2017-08-28 22:18:21 +0530145 auto fileName = systemd::config::networkFilePrefix + intf.first +
146 systemd::config::networkFileSuffix;
Michael Tritz29f2fd62017-05-22 15:27:26 -0500147
Ratan Gupta4f67dac2017-08-28 22:18:21 +0530148 fs::path filePath = networkConfig;
149 filePath /= fileName;
150
151 bmc::writeDHCPDefault(filePath.string(), intf.first);
Michael Tritz29f2fd62017-05-22 15:27:26 -0500152 interfacesMapped = true;
153 }
154
155 if(interfacesMapped)
156 {
157 log<level::INFO>("Network configuration reset to DHCP.");
158 }
159 else
160 {
161 log<level::ERR>("No network interfaces are mapped.");
Michael Tritzd8cd8ed2017-08-31 15:05:18 -0500162 elog<InternalFailure>();
Michael Tritz29f2fd62017-05-22 15:27:26 -0500163 }
164 }
165 else
166 {
167 log<level::ERR>("Network configuration directory not found!");
Michael Tritzd8cd8ed2017-08-31 15:05:18 -0500168 elog<InternalFailure>();
Michael Tritz29f2fd62017-05-22 15:27:26 -0500169 }
170
171 return;
172}
173
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530174// Need to merge the below function with the code which writes the
175// config file during factory reset.
176//TODO openbmc/openbmc#1751
177void Manager::writeToConfigurationFile()
178{
179 // write all the static ip address in the systemd-network conf file
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530180 for (const auto& intf : interfaces)
181 {
Ratan Gupta2b106532017-07-25 16:05:02 +0530182 intf.second->writeConfigurationFile();
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530183
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530184 }
Ratan Guptae05083a2017-09-16 07:12:11 +0530185 restartNetwork();
186}
187
188void Manager::restartNetwork()
189{
190 using namespace std::chrono;
191
192 if (refreshTimer && !refreshTimer->isExpired())
193 {
194 auto time = duration_cast<microseconds>(
195 phosphor::network::networkChangeTimeout);
196 refreshTimer->startTimer(time);
197 }
198 restartSystemdUnit("systemd-networkd.service");
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530199}
200
Ratan Gupta6811f822017-04-14 16:34:56 +0530201}//namespace network
202}//namespace phosphor