blob: 9617ff7af262e97c885f89dd69e6935a3cb24fee [file] [log] [blame]
Ratan Gupta6811f822017-04-14 16:34:56 +05301#include "network_manager.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07002
3#include "config.h"
Ratan Gupta5978dd12017-07-25 13:47:13 +05304#include "ipaddress.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07005#include "network_config.hpp"
Ratan Guptae05083a2017-09-16 07:12:11 +05306#include "timer.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07007#include "util.hpp"
Ratan Gupta738a67f2017-04-21 10:38:05 +05308
Ratan Gupta6811f822017-04-14 16:34:56 +05309#include <arpa/inet.h>
10#include <dirent.h>
11#include <net/if.h>
12
Patrick Venture189d44e2018-07-09 12:30:59 -070013#include <algorithm>
14#include <bitset>
15#include <fstream>
16#include <map>
17#include <phosphor-logging/elog-errors.hpp>
18#include <phosphor-logging/log.hpp>
Michael Tritz29f2fd62017-05-22 15:27:26 -050019#include <string>
Patrick Venture189d44e2018-07-09 12:30:59 -070020#include <xyz/openbmc_project/Common/error.hpp>
Ratan Gupta6811f822017-04-14 16:34:56 +053021
22namespace phosphor
23{
24namespace network
25{
Ratan Gupta82549cc2017-04-21 08:45:23 +053026
Ratan Gupta16f12882017-09-22 18:26:11 +053027extern std::unique_ptr<phosphor::network::Timer> refreshObjectTimer;
28extern std::unique_ptr<phosphor::network::Timer> restartTimer;
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
Ratan Guptab610caf2017-09-19 09:33:51 +053042bool Manager::createDefaultNetworkFiles(bool force)
43{
44 auto isCreated = false;
45 try
46 {
47 // Directory would have created before with
48 // setConfDir function.
49 if (force)
50 {
51 // Factory Reset case
52 // we need to forcefully write the files
53 // so delete the existing ones.
54 if (fs::is_directory(confDir))
55 {
56 for (const auto& file : fs::directory_iterator(confDir))
57 {
58 fs::remove(file.path());
59 }
60 }
61 }
62
63 auto interfaceStrList = getInterfaces();
64 for (const auto& interface : interfaceStrList)
65 {
Michael Tritz08c34f42017-10-16 14:59:09 -050066 // if the interface has '.' in the name, it means that this is a
67 // VLAN - don't create the network file.
68 if (interface.find(".") != std::string::npos)
69 {
70 continue;
71 }
72
Ratan Guptab610caf2017-09-19 09:33:51 +053073 auto fileName = systemd::config::networkFilePrefix + interface +
74 systemd::config::networkFileSuffix;
75
76 fs::path filePath = confDir;
77 filePath /= fileName;
78
79 // create the interface specific network file
80 // if not exist or we forcefully wants to write
81 // the network file.
82
83 if (force || !fs::is_regular_file(filePath.string()))
84 {
85 bmc::writeDHCPDefault(filePath.string(), interface);
86 log<level::INFO>("Created the default network file.",
87 entry("INTERFACE=%s", interface.c_str()));
88 isCreated = true;
89 }
90 }
91 }
92 catch (std::exception& e)
93 {
94 log<level::ERR>("Unable to create the default network file");
95 }
96 return isCreated;
97}
98
Ratan Guptaef85eb92017-06-15 08:57:54 +053099void Manager::setConfDir(const fs::path& dir)
100{
101 confDir = dir;
Ratan Gupta255d5142017-08-10 09:02:08 +0530102
103 if (!fs::exists(confDir))
104 {
105 if (!fs::create_directories(confDir))
106 {
107 log<level::ERR>("Unable to create the network conf dir",
108 entry("DIR=%s", confDir.c_str()));
109 elog<InternalFailure>();
110 }
111 }
112
Ratan Gupta29b0e432017-05-25 12:51:40 +0530113}
114
115void Manager::createInterfaces()
116{
Ratan Guptaef85eb92017-06-15 08:57:54 +0530117 //clear all the interfaces first
118 interfaces.clear();
Ratan Gupta29b0e432017-05-25 12:51:40 +0530119
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530120 auto interfaceStrList = getInterfaces();
Ratan Gupta6811f822017-04-14 16:34:56 +0530121
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530122 for (auto& interface : interfaceStrList)
Ratan Gupta6811f822017-04-14 16:34:56 +0530123 {
Ratan Gupta29b0e432017-05-25 12:51:40 +0530124 fs::path objPath = objectPath;
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530125 auto index = interface.find(".");
Ratan Gupta92bc2fe2017-07-26 22:40:21 +0530126
127 // interface can be of vlan type or normal ethernet interface.
128 // vlan interface looks like "interface.vlanid",so here by looking
129 // at the interface name we decide that we need
130 // to create the vlaninterface or normal physical interface.
131 if (index != std::string::npos)
132 {
133 //it is vlan interface
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530134 auto interfaceName = interface.substr(0, index);
135 auto vlanid = interface.substr(index + 1);
Ratan Gupta92bc2fe2017-07-26 22:40:21 +0530136 uint32_t vlanInt = std::stoul(vlanid);
137
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530138 interfaces[interfaceName]->loadVLAN(vlanInt);
Ratan Gupta6e8df632017-08-13 09:41:58 +0530139 continue;
Ratan Gupta92bc2fe2017-07-26 22:40:21 +0530140 }
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530141 // normal ethernet interface
142 objPath /= interface;
Ratan Gupta6811f822017-04-14 16:34:56 +0530143
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530144 auto dhcp = getDHCPValue(confDir, interface);
Ratan Gupta34f96d62017-06-15 09:16:22 +0530145
Ratan Gupta92bc2fe2017-07-26 22:40:21 +0530146 auto intf = std::make_shared<phosphor::network::EthernetInterface>(
147 bus,
148 objPath.string(),
149 dhcp,
150 *this);
151
152
153 intf->createIPAddressObjects();
154
Ratan Gupta6811f822017-04-14 16:34:56 +0530155 this->interfaces.emplace(std::make_pair(
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530156 std::move(interface), std::move(intf)));
Ratan Gupta29b0e432017-05-25 12:51:40 +0530157
Ratan Gupta6811f822017-04-14 16:34:56 +0530158 }
Ratan Gupta87c13982017-06-15 09:27:27 +0530159
Ratan Gupta6811f822017-04-14 16:34:56 +0530160}
161
Ratan Guptaef85eb92017-06-15 08:57:54 +0530162void Manager::createChildObjects()
163{
164 // creates the ethernet interface dbus object.
165 createInterfaces();
Ratan Guptae05083a2017-09-16 07:12:11 +0530166
167 systemConf.reset(nullptr);
168 dhcpConf.reset(nullptr);
169
Ratan Guptaef85eb92017-06-15 08:57:54 +0530170 fs::path objPath = objectPath;
171 objPath /= "config";
Ratan Guptae05083a2017-09-16 07:12:11 +0530172
173 // create the system conf object.
Ratan Guptaef85eb92017-06-15 08:57:54 +0530174 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
175 bus, objPath.string(), *this);
Ratan Guptad16f88c2017-07-11 17:47:57 +0530176 // create the dhcp conf object.
177 objPath /= "dhcp";
178 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
179 bus, objPath.string(), *this);
Ratan Guptaef85eb92017-06-15 08:57:54 +0530180
181}
182
Ratan Gupta584df832017-07-31 16:21:54 +0530183void Manager::vLAN(IntfName interfaceName, uint32_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +0530184{
Ratan Gupta2b106532017-07-25 16:05:02 +0530185 interfaces[interfaceName]->createVLAN(id);
Ratan Gupta6811f822017-04-14 16:34:56 +0530186}
187
Michael Tritz29f2fd62017-05-22 15:27:26 -0500188void Manager::reset()
189{
Ratan Guptab610caf2017-09-19 09:33:51 +0530190 if(!createDefaultNetworkFiles(true))
Michael Tritz29f2fd62017-05-22 15:27:26 -0500191 {
Ratan Guptab610caf2017-09-19 09:33:51 +0530192 log<level::ERR>("Network Factory Reset failed.");
193 return;
194 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
Michael Tritz29f2fd62017-05-22 15:27:26 -0500195 }
196
Ratan Guptab610caf2017-09-19 09:33:51 +0530197 log<level::INFO>("Network Factory Reset done.");
Michael Tritz29f2fd62017-05-22 15:27:26 -0500198}
199
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530200// Need to merge the below function with the code which writes the
201// config file during factory reset.
202//TODO openbmc/openbmc#1751
203void Manager::writeToConfigurationFile()
204{
205 // write all the static ip address in the systemd-network conf file
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530206 for (const auto& intf : interfaces)
207 {
Ratan Gupta2b106532017-07-25 16:05:02 +0530208 intf.second->writeConfigurationFile();
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530209
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530210 }
Ratan Gupta16f12882017-09-22 18:26:11 +0530211 restartTimers();
Ratan Guptae05083a2017-09-16 07:12:11 +0530212}
213
Ratan Gupta16f12882017-09-22 18:26:11 +0530214void Manager::restartTimers()
Ratan Guptae05083a2017-09-16 07:12:11 +0530215{
216 using namespace std::chrono;
Ratan Gupta16f12882017-09-22 18:26:11 +0530217 if (refreshObjectTimer && restartTimer)
Ratan Guptae05083a2017-09-16 07:12:11 +0530218 {
Ratan Gupta16f12882017-09-22 18:26:11 +0530219 // start the restart timer.
220 auto restartTime = duration_cast<microseconds>(
221 phosphor::network::restartTimeout);
222 restartTimer->startTimer(restartTime);
223
224 // start the refresh timer.
225 auto refreshTime = duration_cast<microseconds>(
226 phosphor::network::refreshTimeout);
227 refreshObjectTimer->startTimer(refreshTime);
Ratan Guptae05083a2017-09-16 07:12:11 +0530228 }
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530229}
230
Ratan Gupta6811f822017-04-14 16:34:56 +0530231}//namespace network
232}//namespace phosphor