blob: e9a62ed55fe42783f30c448afa25dbe338fcc591 [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 Gupta44ae86e2017-05-15 21:52:14 +05306#include "xyz/openbmc_project/Common/error.hpp"
Ratan Gupta6811f822017-04-14 16:34:56 +05307
8#include <phosphor-logging/log.hpp>
Ratan Gupta44ae86e2017-05-15 21:52:14 +05309#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta6811f822017-04-14 16:34:56 +053010
11#include <algorithm>
Ratan Gupta738a67f2017-04-21 10:38:05 +053012#include <bitset>
Ratan Gupta738a67f2017-04-21 10:38:05 +053013#include <map>
Ratan Gupta4f1c18b2017-05-25 12:59:35 +053014#include <fstream>
Ratan Gupta738a67f2017-04-21 10:38:05 +053015
Ratan Gupta6811f822017-04-14 16:34:56 +053016#include <arpa/inet.h>
17#include <dirent.h>
18#include <net/if.h>
19
Michael Tritz29f2fd62017-05-22 15:27:26 -050020#include <string>
Ratan Gupta6811f822017-04-14 16:34:56 +053021
22namespace phosphor
23{
24namespace network
25{
Ratan Gupta82549cc2017-04-21 08:45:23 +053026
Ratan Gupta6811f822017-04-14 16:34:56 +053027using namespace phosphor::logging;
Ratan Guptaef85eb92017-06-15 08:57:54 +053028using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta6811f822017-04-14 16:34:56 +053029
30Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath):
Ratan Gupta29b0e432017-05-25 12:51:40 +053031 details::VLANCreateIface(bus, objPath, true),
32 bus(bus),
33 objectPath(objPath)
Ratan Gupta6811f822017-04-14 16:34:56 +053034{
Ratan Guptaef85eb92017-06-15 08:57:54 +053035 confDir = NETWORK_CONF_DIR;
36}
37
38void Manager::setConfDir(const fs::path& dir)
39{
40 confDir = dir;
Ratan Gupta29b0e432017-05-25 12:51:40 +053041}
42
43void Manager::createInterfaces()
44{
Ratan Guptaef85eb92017-06-15 08:57:54 +053045 //clear all the interfaces first
46 interfaces.clear();
Ratan Gupta29b0e432017-05-25 12:51:40 +053047
Ratan Gupta82549cc2017-04-21 08:45:23 +053048 auto interfaceInfoList = getInterfaceAddrs();
Ratan Gupta6811f822017-04-14 16:34:56 +053049
Ratan Gupta738a67f2017-04-21 10:38:05 +053050 for (const auto& intfInfo : interfaceInfoList)
Ratan Gupta6811f822017-04-14 16:34:56 +053051 {
Ratan Gupta29b0e432017-05-25 12:51:40 +053052 fs::path objPath = objectPath;
53 objPath /= intfInfo.first;
Ratan Gupta6811f822017-04-14 16:34:56 +053054
Ratan Gupta34f96d62017-06-15 09:16:22 +053055 auto dhcp = getDHCPValue(intfInfo.first);
56
Ratan Gupta6811f822017-04-14 16:34:56 +053057 this->interfaces.emplace(std::make_pair(
Ratan Gupta738a67f2017-04-21 10:38:05 +053058 intfInfo.first,
59 std::make_unique<
60 phosphor::network::EthernetInterface>
61 (bus,
Ratan Gupta29b0e432017-05-25 12:51:40 +053062 objPath.string(),
Ratan Gupta34f96d62017-06-15 09:16:22 +053063 dhcp,
Ratan Gupta4f1c18b2017-05-25 12:59:35 +053064 *this)));
Ratan Gupta29b0e432017-05-25 12:51:40 +053065
Ratan Gupta6811f822017-04-14 16:34:56 +053066 }
Ratan Gupta87c13982017-06-15 09:27:27 +053067
Ratan Gupta6811f822017-04-14 16:34:56 +053068}
69
Ratan Guptaef85eb92017-06-15 08:57:54 +053070void Manager::createChildObjects()
71{
72 // creates the ethernet interface dbus object.
73 createInterfaces();
74 // create the system conf object.
75 fs::path objPath = objectPath;
76 objPath /= "config";
77 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
78 bus, objPath.string(), *this);
Ratan Guptad16f88c2017-07-11 17:47:57 +053079 // create the dhcp conf object.
80 objPath /= "dhcp";
81 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
82 bus, objPath.string(), *this);
Ratan Guptaef85eb92017-06-15 08:57:54 +053083
84}
85
Ratan Gupta82549cc2017-04-21 08:45:23 +053086void Manager::vLAN(IntfName interfaceName, uint16_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +053087{
88}
89
Michael Tritz29f2fd62017-05-22 15:27:26 -050090void Manager::reset()
91{
92 const std::string networkConfig = "/etc/systemd/network/";
93 bool filesExist, interfacesMapped = false;
94
95 if(fs::is_directory(networkConfig))
96 {
97 for(auto& file : fs::directory_iterator(networkConfig))
98 {
99 std::string filename = file.path().filename().c_str();
100
101 if(filename.substr(filename.find_last_of(".") + 1) == "network")
102 {
103 fs::remove(file.path());
104 filesExist = true;
105 }
106 }
107
108 if(!filesExist)
109 {
110 log<level::INFO>("No existing network configuration was found.");
111 }
112
113 for (auto& intf : interfaces)
114 {
115 std::string filename = networkConfig + "00-bmc-" + intf.first +
116 ".network";
117
118 bmc::writeDHCPDefault(filename, intf.first);
119 interfacesMapped = true;
120 }
121
122 if(interfacesMapped)
123 {
124 log<level::INFO>("Network configuration reset to DHCP.");
125 }
126 else
127 {
128 log<level::ERR>("No network interfaces are mapped.");
129 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
130 }
131 }
132 else
133 {
134 log<level::ERR>("Network configuration directory not found!");
135 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
136 }
137
138 return;
139}
140
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530141// Need to merge the below function with the code which writes the
142// config file during factory reset.
143//TODO openbmc/openbmc#1751
144void Manager::writeToConfigurationFile()
145{
146 // write all the static ip address in the systemd-network conf file
147
148 using namespace std::string_literals;
149 using AddressOrigin =
150 sdbusplus::xyz::openbmc_project::Network::server::IP::AddressOrigin;
151 namespace fs = std::experimental::filesystem;
152
153 for (const auto& intf : interfaces)
154 {
155
Ratan Guptaef85eb92017-06-15 08:57:54 +0530156 fs::path confPath = confDir;
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530157 std::string fileName = "00-bmc-"s + intf.first + ".network"s;
158 confPath /= fileName;
159 std::fstream stream;
160 stream.open(confPath.c_str(), std::fstream::out);
161
162 // Write the device
163 stream << "[" << "Match" << "]\n";
164 stream << "Name=" << intf.first << "\n";
165
166 auto addrs = intf.second->getAddresses();
167
168 // write the network section
169 stream << "[" << "Network" << "]\n";
Ratan Gupta34f96d62017-06-15 09:16:22 +0530170 // DHCP
171 if (intf.second->dHCPEnabled() == true)
172 {
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530173 // write the dhcp section if interface is
174 // configured as dhcp.
175 writeDHCPSection(stream);
Ratan Gupta34f96d62017-06-15 09:16:22 +0530176 stream.close();
177 continue;
178 }
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530179
Ratan Gupta34f96d62017-06-15 09:16:22 +0530180 // Static
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530181 for (const auto& addr : addrs)
182 {
183 if (addr.second->origin() == AddressOrigin::Static)
184 {
185 std::string address = addr.second->address() + "/" + std::to_string(
186 addr.second->prefixLength());
187
188 stream << "Address=" << address << "\n";
Ratan Guptaef85eb92017-06-15 08:57:54 +0530189 if (addr.second->gateway() != "0.0.0.0" &&
190 addr.second->gateway() != "")
191 {
192 stream << "Gateway=" << addr.second->gateway() << "\n";
193 }
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530194
195 }
196 }
Ratan Guptaef85eb92017-06-15 08:57:54 +0530197 stream << "Gateway=" << systemConf->defaultGateway() << "\n";
198 // write the route section
Ratan Guptafc2c7242017-05-29 08:46:06 +0530199 stream << "[" << "Route" << "]\n";
200 for(const auto& addr : addrs)
201 {
202 if (addr.second->origin() == AddressOrigin::Static)
203 {
204 int addressFamily = addr.second->type() == IP::Protocol::IPv4 ? AF_INET : AF_INET6;
205 std::string destination = getNetworkID(
206 addressFamily,
207 addr.second->address(),
208 addr.second->prefixLength());
209
Ratan Guptaef85eb92017-06-15 08:57:54 +0530210 if (addr.second->gateway() != "0.0.0.0" &&
211 addr.second->gateway() != "" &&
212 destination != "0.0.0.0" &&
213 destination != "")
Ratan Guptafc2c7242017-05-29 08:46:06 +0530214 {
215
216 stream << "Gateway=" << addr.second->gateway() << "\n";
217 stream << "Destination=" << destination << "\n";
218 }
219
220 }
221 }
222
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530223 stream.close();
224 }
Ratan Gupta068a8cf2017-07-11 19:18:29 +0530225 restartSystemdUnit("systemd-networkd.service");
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530226}
227
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530228void Manager::writeDHCPSection(std::fstream& stream)
229{
230 using namespace std::string_literals;
231 stream << "DHCP=true\n";
232 // write the dhcp section
233 stream << "[DHCP]\n";
234
235 // Hardcoding the client identifier to mac, to address below issue
236 // https://github.com/openbmc/openbmc/issues/1280
237 stream << "ClientIdentifier=mac\n";
238
239 auto value = dhcpConf->dNSEnabled() ? "true"s : "false"s;
240 stream << "UseDNS="s + value + "\n";
241
242 value = dhcpConf->nTPEnabled() ? "true"s : "false"s;
243 stream << "UseNTP="s + value + "\n";
244
245 value = dhcpConf->hostNameEnabled() ? "true"s : "false"s;
246 stream << "UseHostname="s + value + "\n";
247}
248
Ratan Gupta34f96d62017-06-15 09:16:22 +0530249bool Manager::getDHCPValue(const std::string& intf)
250{
251 bool dhcp = false;
252 // Get the interface mode value from systemd conf
253 using namespace std::string_literals;
254 fs::path confPath = confDir;
255 std::string fileName = "00-bmc-"s + intf + ".network"s;
256 confPath /= fileName;
257
258 try
259 {
260 config::Parser parser(confPath.string());
261 auto values = parser.getValues("Network","DHCP");
262 // There will be only single value for DHCP key.
263 if (values[0] == "true")
264 {
265 dhcp = true;
266 }
267 }
268 catch (InternalFailure& e)
269 {
270 commit<InternalFailure>();
271 }
272 return dhcp;
273}
274
Ratan Gupta6811f822017-04-14 16:34:56 +0530275}//namespace network
276}//namespace phosphor