blob: 6ae3bfb88c0f201b03a47e9bb44f73f43d277cfc [file] [log] [blame]
Ratan Gupta6811f822017-04-14 16:34:56 +05301#include "config.h"
Ratan Gupta34f96d62017-06-15 09:16:22 +05302#include "config_parser.hpp"
Ratan Gupta3681a502017-06-17 19:20:04 +05303#include "util.hpp"
Ratan Gupta6811f822017-04-14 16:34:56 +05304#include "network_manager.hpp"
Michael Tritz29f2fd62017-05-22 15:27:26 -05005#include "network_config.hpp"
Ratan Gupta5978dd12017-07-25 13:47:13 +05306#include "ipaddress.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 Gupta6811f822017-04-14 16:34:56 +053028using namespace phosphor::logging;
Ratan Guptaef85eb92017-06-15 08:57:54 +053029using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta6811f822017-04-14 16:34:56 +053030
Ratan Gupta255d5142017-08-10 09:02:08 +053031Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath,
32 const std::string& path):
Ratan Gupta29b0e432017-05-25 12:51:40 +053033 details::VLANCreateIface(bus, objPath, true),
34 bus(bus),
35 objectPath(objPath)
Ratan Gupta6811f822017-04-14 16:34:56 +053036{
Ratan Gupta255d5142017-08-10 09:02:08 +053037 fs::path confDir(path);
38 setConfDir(confDir);
Ratan Guptaef85eb92017-06-15 08:57:54 +053039}
40
41void Manager::setConfDir(const fs::path& dir)
42{
43 confDir = dir;
Ratan Gupta255d5142017-08-10 09:02:08 +053044
45 if (!fs::exists(confDir))
46 {
47 if (!fs::create_directories(confDir))
48 {
49 log<level::ERR>("Unable to create the network conf dir",
50 entry("DIR=%s", confDir.c_str()));
51 elog<InternalFailure>();
52 }
53 }
54
Ratan Gupta29b0e432017-05-25 12:51:40 +053055}
56
57void Manager::createInterfaces()
58{
Ratan Guptaef85eb92017-06-15 08:57:54 +053059 //clear all the interfaces first
60 interfaces.clear();
Ratan Gupta29b0e432017-05-25 12:51:40 +053061
Ratan Gupta82549cc2017-04-21 08:45:23 +053062 auto interfaceInfoList = getInterfaceAddrs();
Ratan Gupta6811f822017-04-14 16:34:56 +053063
Ratan Gupta738a67f2017-04-21 10:38:05 +053064 for (const auto& intfInfo : interfaceInfoList)
Ratan Gupta6811f822017-04-14 16:34:56 +053065 {
Ratan Gupta29b0e432017-05-25 12:51:40 +053066 fs::path objPath = objectPath;
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053067 auto index = intfInfo.first.find(".");
68
69 // interface can be of vlan type or normal ethernet interface.
70 // vlan interface looks like "interface.vlanid",so here by looking
71 // at the interface name we decide that we need
72 // to create the vlaninterface or normal physical interface.
73 if (index != std::string::npos)
74 {
75 //it is vlan interface
76 auto interface = intfInfo.first.substr(0, index);
77 auto vlanid = intfInfo.first.substr(index + 1);
78 uint32_t vlanInt = std::stoul(vlanid);
79
80 interfaces[interface]->loadVLAN(vlanInt);
81 return;
82 }
83 // normal ethernet inetrface
Ratan Gupta29b0e432017-05-25 12:51:40 +053084 objPath /= intfInfo.first;
Ratan Gupta6811f822017-04-14 16:34:56 +053085
Ratan Gupta34f96d62017-06-15 09:16:22 +053086 auto dhcp = getDHCPValue(intfInfo.first);
87
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053088 auto intf = std::make_shared<phosphor::network::EthernetInterface>(
89 bus,
90 objPath.string(),
91 dhcp,
92 *this);
93
94
95 intf->createIPAddressObjects();
96
Ratan Gupta6811f822017-04-14 16:34:56 +053097 this->interfaces.emplace(std::make_pair(
Ratan Gupta92bc2fe2017-07-26 22:40:21 +053098 intfInfo.first, std::move(intf)));
Ratan Gupta29b0e432017-05-25 12:51:40 +053099
Ratan Gupta6811f822017-04-14 16:34:56 +0530100 }
Ratan Gupta87c13982017-06-15 09:27:27 +0530101
Ratan Gupta6811f822017-04-14 16:34:56 +0530102}
103
Ratan Guptaef85eb92017-06-15 08:57:54 +0530104void Manager::createChildObjects()
105{
106 // creates the ethernet interface dbus object.
107 createInterfaces();
108 // create the system conf object.
109 fs::path objPath = objectPath;
110 objPath /= "config";
111 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
112 bus, objPath.string(), *this);
Ratan Guptad16f88c2017-07-11 17:47:57 +0530113 // create the dhcp conf object.
114 objPath /= "dhcp";
115 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
116 bus, objPath.string(), *this);
Ratan Guptaef85eb92017-06-15 08:57:54 +0530117
118}
119
Ratan Gupta584df832017-07-31 16:21:54 +0530120void Manager::vLAN(IntfName interfaceName, uint32_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +0530121{
Ratan Gupta2b106532017-07-25 16:05:02 +0530122 interfaces[interfaceName]->createVLAN(id);
Ratan Gupta6811f822017-04-14 16:34:56 +0530123}
124
Michael Tritz29f2fd62017-05-22 15:27:26 -0500125void Manager::reset()
126{
127 const std::string networkConfig = "/etc/systemd/network/";
128 bool filesExist, interfacesMapped = false;
129
130 if(fs::is_directory(networkConfig))
131 {
132 for(auto& file : fs::directory_iterator(networkConfig))
133 {
134 std::string filename = file.path().filename().c_str();
135
136 if(filename.substr(filename.find_last_of(".") + 1) == "network")
137 {
138 fs::remove(file.path());
139 filesExist = true;
140 }
141 }
142
143 if(!filesExist)
144 {
145 log<level::INFO>("No existing network configuration was found.");
146 }
147
148 for (auto& intf : interfaces)
149 {
150 std::string filename = networkConfig + "00-bmc-" + intf.first +
151 ".network";
152
153 bmc::writeDHCPDefault(filename, intf.first);
154 interfacesMapped = true;
155 }
156
157 if(interfacesMapped)
158 {
159 log<level::INFO>("Network configuration reset to DHCP.");
160 }
161 else
162 {
163 log<level::ERR>("No network interfaces are mapped.");
164 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
165 }
166 }
167 else
168 {
169 log<level::ERR>("Network configuration directory not found!");
170 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
171 }
172
173 return;
174}
175
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530176// Need to merge the below function with the code which writes the
177// config file during factory reset.
178//TODO openbmc/openbmc#1751
179void Manager::writeToConfigurationFile()
180{
181 // write all the static ip address in the systemd-network conf file
182
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530183 for (const auto& intf : interfaces)
184 {
Ratan Gupta2b106532017-07-25 16:05:02 +0530185 intf.second->writeConfigurationFile();
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530186
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530187 }
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530188}
189
Ratan Gupta34f96d62017-06-15 09:16:22 +0530190bool Manager::getDHCPValue(const std::string& intf)
191{
192 bool dhcp = false;
193 // Get the interface mode value from systemd conf
194 using namespace std::string_literals;
195 fs::path confPath = confDir;
196 std::string fileName = "00-bmc-"s + intf + ".network"s;
197 confPath /= fileName;
198
199 try
200 {
201 config::Parser parser(confPath.string());
202 auto values = parser.getValues("Network","DHCP");
203 // There will be only single value for DHCP key.
204 if (values[0] == "true")
205 {
206 dhcp = true;
207 }
208 }
209 catch (InternalFailure& e)
210 {
Ratan Guptadea3ead2017-08-02 18:09:25 +0530211 log<level::INFO>("Exception occured during getting of DHCP value");
Ratan Gupta34f96d62017-06-15 09:16:22 +0530212 }
213 return dhcp;
214}
215
Ratan Gupta6811f822017-04-14 16:34:56 +0530216}//namespace network
217}//namespace phosphor