blob: cdbaf45761af91ed7e42b15197111f617f49b265 [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
Ratan Gupta255d5142017-08-10 09:02:08 +053030Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath,
31 const std::string& path):
Ratan Gupta29b0e432017-05-25 12:51:40 +053032 details::VLANCreateIface(bus, objPath, true),
33 bus(bus),
34 objectPath(objPath)
Ratan Gupta6811f822017-04-14 16:34:56 +053035{
Ratan Gupta255d5142017-08-10 09:02:08 +053036 fs::path confDir(path);
37 setConfDir(confDir);
Ratan Guptaef85eb92017-06-15 08:57:54 +053038}
39
40void Manager::setConfDir(const fs::path& dir)
41{
42 confDir = dir;
Ratan Gupta255d5142017-08-10 09:02:08 +053043
44 if (!fs::exists(confDir))
45 {
46 if (!fs::create_directories(confDir))
47 {
48 log<level::ERR>("Unable to create the network conf dir",
49 entry("DIR=%s", confDir.c_str()));
50 elog<InternalFailure>();
51 }
52 }
53
Ratan Gupta29b0e432017-05-25 12:51:40 +053054}
55
56void Manager::createInterfaces()
57{
Ratan Guptaef85eb92017-06-15 08:57:54 +053058 //clear all the interfaces first
59 interfaces.clear();
Ratan Gupta29b0e432017-05-25 12:51:40 +053060
Ratan Gupta82549cc2017-04-21 08:45:23 +053061 auto interfaceInfoList = getInterfaceAddrs();
Ratan Gupta6811f822017-04-14 16:34:56 +053062
Ratan Gupta738a67f2017-04-21 10:38:05 +053063 for (const auto& intfInfo : interfaceInfoList)
Ratan Gupta6811f822017-04-14 16:34:56 +053064 {
Ratan Gupta29b0e432017-05-25 12:51:40 +053065 fs::path objPath = objectPath;
66 objPath /= intfInfo.first;
Ratan Gupta6811f822017-04-14 16:34:56 +053067
Ratan Gupta34f96d62017-06-15 09:16:22 +053068 auto dhcp = getDHCPValue(intfInfo.first);
69
Ratan Gupta6811f822017-04-14 16:34:56 +053070 this->interfaces.emplace(std::make_pair(
Ratan Gupta738a67f2017-04-21 10:38:05 +053071 intfInfo.first,
72 std::make_unique<
73 phosphor::network::EthernetInterface>
74 (bus,
Ratan Gupta29b0e432017-05-25 12:51:40 +053075 objPath.string(),
Ratan Gupta34f96d62017-06-15 09:16:22 +053076 dhcp,
Ratan Gupta4f1c18b2017-05-25 12:59:35 +053077 *this)));
Ratan Gupta29b0e432017-05-25 12:51:40 +053078
Ratan Gupta6811f822017-04-14 16:34:56 +053079 }
Ratan Gupta87c13982017-06-15 09:27:27 +053080
Ratan Gupta6811f822017-04-14 16:34:56 +053081}
82
Ratan Guptaef85eb92017-06-15 08:57:54 +053083void Manager::createChildObjects()
84{
85 // creates the ethernet interface dbus object.
86 createInterfaces();
87 // create the system conf object.
88 fs::path objPath = objectPath;
89 objPath /= "config";
90 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
91 bus, objPath.string(), *this);
Ratan Guptad16f88c2017-07-11 17:47:57 +053092 // create the dhcp conf object.
93 objPath /= "dhcp";
94 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
95 bus, objPath.string(), *this);
Ratan Guptaef85eb92017-06-15 08:57:54 +053096
97}
98
Ratan Gupta584df832017-07-31 16:21:54 +053099void Manager::vLAN(IntfName interfaceName, uint32_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +0530100{
101}
102
Michael Tritz29f2fd62017-05-22 15:27:26 -0500103void Manager::reset()
104{
105 const std::string networkConfig = "/etc/systemd/network/";
106 bool filesExist, interfacesMapped = false;
107
108 if(fs::is_directory(networkConfig))
109 {
110 for(auto& file : fs::directory_iterator(networkConfig))
111 {
112 std::string filename = file.path().filename().c_str();
113
114 if(filename.substr(filename.find_last_of(".") + 1) == "network")
115 {
116 fs::remove(file.path());
117 filesExist = true;
118 }
119 }
120
121 if(!filesExist)
122 {
123 log<level::INFO>("No existing network configuration was found.");
124 }
125
126 for (auto& intf : interfaces)
127 {
128 std::string filename = networkConfig + "00-bmc-" + intf.first +
129 ".network";
130
131 bmc::writeDHCPDefault(filename, intf.first);
132 interfacesMapped = true;
133 }
134
135 if(interfacesMapped)
136 {
137 log<level::INFO>("Network configuration reset to DHCP.");
138 }
139 else
140 {
141 log<level::ERR>("No network interfaces are mapped.");
142 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
143 }
144 }
145 else
146 {
147 log<level::ERR>("Network configuration directory not found!");
148 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
149 }
150
151 return;
152}
153
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530154// Need to merge the below function with the code which writes the
155// config file during factory reset.
156//TODO openbmc/openbmc#1751
157void Manager::writeToConfigurationFile()
158{
159 // write all the static ip address in the systemd-network conf file
160
161 using namespace std::string_literals;
162 using AddressOrigin =
163 sdbusplus::xyz::openbmc_project::Network::server::IP::AddressOrigin;
164 namespace fs = std::experimental::filesystem;
165
166 for (const auto& intf : interfaces)
167 {
168
Ratan Guptaef85eb92017-06-15 08:57:54 +0530169 fs::path confPath = confDir;
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530170 std::string fileName = "00-bmc-"s + intf.first + ".network"s;
171 confPath /= fileName;
172 std::fstream stream;
173 stream.open(confPath.c_str(), std::fstream::out);
174
175 // Write the device
176 stream << "[" << "Match" << "]\n";
177 stream << "Name=" << intf.first << "\n";
178
179 auto addrs = intf.second->getAddresses();
180
181 // write the network section
182 stream << "[" << "Network" << "]\n";
Ratan Gupta34f96d62017-06-15 09:16:22 +0530183 // DHCP
184 if (intf.second->dHCPEnabled() == true)
185 {
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530186 // write the dhcp section if interface is
187 // configured as dhcp.
188 writeDHCPSection(stream);
Ratan Gupta34f96d62017-06-15 09:16:22 +0530189 stream.close();
190 continue;
191 }
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530192
Ratan Gupta34f96d62017-06-15 09:16:22 +0530193 // Static
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530194 for (const auto& addr : addrs)
195 {
196 if (addr.second->origin() == AddressOrigin::Static)
197 {
198 std::string address = addr.second->address() + "/" + std::to_string(
199 addr.second->prefixLength());
200
201 stream << "Address=" << address << "\n";
Ratan Guptaef85eb92017-06-15 08:57:54 +0530202 if (addr.second->gateway() != "0.0.0.0" &&
203 addr.second->gateway() != "")
204 {
205 stream << "Gateway=" << addr.second->gateway() << "\n";
206 }
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530207
208 }
209 }
Ratan Guptaef85eb92017-06-15 08:57:54 +0530210 stream << "Gateway=" << systemConf->defaultGateway() << "\n";
211 // write the route section
Ratan Guptafc2c7242017-05-29 08:46:06 +0530212 stream << "[" << "Route" << "]\n";
213 for(const auto& addr : addrs)
214 {
215 if (addr.second->origin() == AddressOrigin::Static)
216 {
217 int addressFamily = addr.second->type() == IP::Protocol::IPv4 ? AF_INET : AF_INET6;
218 std::string destination = getNetworkID(
219 addressFamily,
220 addr.second->address(),
221 addr.second->prefixLength());
222
Ratan Guptaef85eb92017-06-15 08:57:54 +0530223 if (addr.second->gateway() != "0.0.0.0" &&
224 addr.second->gateway() != "" &&
225 destination != "0.0.0.0" &&
226 destination != "")
Ratan Guptafc2c7242017-05-29 08:46:06 +0530227 {
228
229 stream << "Gateway=" << addr.second->gateway() << "\n";
230 stream << "Destination=" << destination << "\n";
231 }
232
233 }
234 }
235
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530236 stream.close();
237 }
Ratan Gupta068a8cf2017-07-11 19:18:29 +0530238 restartSystemdUnit("systemd-networkd.service");
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530239}
240
Ratan Gupta70c7e5b2017-07-12 11:41:55 +0530241void Manager::writeDHCPSection(std::fstream& stream)
242{
243 using namespace std::string_literals;
244 stream << "DHCP=true\n";
245 // write the dhcp section
246 stream << "[DHCP]\n";
247
248 // Hardcoding the client identifier to mac, to address below issue
249 // https://github.com/openbmc/openbmc/issues/1280
250 stream << "ClientIdentifier=mac\n";
251
252 auto value = dhcpConf->dNSEnabled() ? "true"s : "false"s;
253 stream << "UseDNS="s + value + "\n";
254
255 value = dhcpConf->nTPEnabled() ? "true"s : "false"s;
256 stream << "UseNTP="s + value + "\n";
257
258 value = dhcpConf->hostNameEnabled() ? "true"s : "false"s;
259 stream << "UseHostname="s + value + "\n";
260}
261
Ratan Gupta34f96d62017-06-15 09:16:22 +0530262bool Manager::getDHCPValue(const std::string& intf)
263{
264 bool dhcp = false;
265 // Get the interface mode value from systemd conf
266 using namespace std::string_literals;
267 fs::path confPath = confDir;
268 std::string fileName = "00-bmc-"s + intf + ".network"s;
269 confPath /= fileName;
270
271 try
272 {
273 config::Parser parser(confPath.string());
274 auto values = parser.getValues("Network","DHCP");
275 // There will be only single value for DHCP key.
276 if (values[0] == "true")
277 {
278 dhcp = true;
279 }
280 }
281 catch (InternalFailure& e)
282 {
Ratan Guptadea3ead2017-08-02 18:09:25 +0530283 log<level::INFO>("Exception occured during getting of DHCP value");
Ratan Gupta34f96d62017-06-15 09:16:22 +0530284 }
285 return dhcp;
286}
287
Ratan Gupta6811f822017-04-14 16:34:56 +0530288}//namespace network
289}//namespace phosphor