blob: e1bfa4170de3dfc6f1a8828bcafd7703a005b1f7 [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
66 interfaces[intfInfo.first]->setAddressList(intfInfo.second);
Ratan Gupta6811f822017-04-14 16:34:56 +053067 }
68}
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);
79
80}
81
Ratan Gupta82549cc2017-04-21 08:45:23 +053082void Manager::vLAN(IntfName interfaceName, uint16_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +053083{
84}
85
Michael Tritz29f2fd62017-05-22 15:27:26 -050086void Manager::reset()
87{
88 const std::string networkConfig = "/etc/systemd/network/";
89 bool filesExist, interfacesMapped = false;
90
91 if(fs::is_directory(networkConfig))
92 {
93 for(auto& file : fs::directory_iterator(networkConfig))
94 {
95 std::string filename = file.path().filename().c_str();
96
97 if(filename.substr(filename.find_last_of(".") + 1) == "network")
98 {
99 fs::remove(file.path());
100 filesExist = true;
101 }
102 }
103
104 if(!filesExist)
105 {
106 log<level::INFO>("No existing network configuration was found.");
107 }
108
109 for (auto& intf : interfaces)
110 {
111 std::string filename = networkConfig + "00-bmc-" + intf.first +
112 ".network";
113
114 bmc::writeDHCPDefault(filename, intf.first);
115 interfacesMapped = true;
116 }
117
118 if(interfacesMapped)
119 {
120 log<level::INFO>("Network configuration reset to DHCP.");
121 }
122 else
123 {
124 log<level::ERR>("No network interfaces are mapped.");
125 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
126 }
127 }
128 else
129 {
130 log<level::ERR>("Network configuration directory not found!");
131 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
132 }
133
134 return;
135}
136
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530137// Need to merge the below function with the code which writes the
138// config file during factory reset.
139//TODO openbmc/openbmc#1751
140void Manager::writeToConfigurationFile()
141{
142 // write all the static ip address in the systemd-network conf file
143
144 using namespace std::string_literals;
145 using AddressOrigin =
146 sdbusplus::xyz::openbmc_project::Network::server::IP::AddressOrigin;
147 namespace fs = std::experimental::filesystem;
148
149 for (const auto& intf : interfaces)
150 {
151
Ratan Guptaef85eb92017-06-15 08:57:54 +0530152 fs::path confPath = confDir;
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530153 std::string fileName = "00-bmc-"s + intf.first + ".network"s;
154 confPath /= fileName;
155 std::fstream stream;
156 stream.open(confPath.c_str(), std::fstream::out);
157
158 // Write the device
159 stream << "[" << "Match" << "]\n";
160 stream << "Name=" << intf.first << "\n";
161
162 auto addrs = intf.second->getAddresses();
163
164 // write the network section
165 stream << "[" << "Network" << "]\n";
Ratan Gupta34f96d62017-06-15 09:16:22 +0530166 // DHCP
167 if (intf.second->dHCPEnabled() == true)
168 {
169 stream << "DHCP=true\n";
170 // write the dhcp section
171 stream << "[DHCP]\n";
172 stream << "ClientIdentifier=mac\n";
173 stream.close();
174 continue;
175 }
176 // Static
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530177 for (const auto& addr : addrs)
178 {
179 if (addr.second->origin() == AddressOrigin::Static)
180 {
181 std::string address = addr.second->address() + "/" + std::to_string(
182 addr.second->prefixLength());
183
184 stream << "Address=" << address << "\n";
Ratan Guptaef85eb92017-06-15 08:57:54 +0530185 if (addr.second->gateway() != "0.0.0.0" &&
186 addr.second->gateway() != "")
187 {
188 stream << "Gateway=" << addr.second->gateway() << "\n";
189 }
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530190
191 }
192 }
Ratan Guptaef85eb92017-06-15 08:57:54 +0530193 stream << "Gateway=" << systemConf->defaultGateway() << "\n";
194 // write the route section
Ratan Guptafc2c7242017-05-29 08:46:06 +0530195 stream << "[" << "Route" << "]\n";
196 for(const auto& addr : addrs)
197 {
198 if (addr.second->origin() == AddressOrigin::Static)
199 {
200 int addressFamily = addr.second->type() == IP::Protocol::IPv4 ? AF_INET : AF_INET6;
201 std::string destination = getNetworkID(
202 addressFamily,
203 addr.second->address(),
204 addr.second->prefixLength());
205
Ratan Guptaef85eb92017-06-15 08:57:54 +0530206 if (addr.second->gateway() != "0.0.0.0" &&
207 addr.second->gateway() != "" &&
208 destination != "0.0.0.0" &&
209 destination != "")
Ratan Guptafc2c7242017-05-29 08:46:06 +0530210 {
211
212 stream << "Gateway=" << addr.second->gateway() << "\n";
213 stream << "Destination=" << destination << "\n";
214 }
215
216 }
217 }
218
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530219 stream.close();
220 }
221 restartSystemdNetworkd();
222}
223
224void Manager::restartSystemdNetworkd()
225{
226 constexpr auto systemdNetworkdService = "systemd-networkd.service";
227
228 auto method = bus.new_method_call(
229 SYSTEMD_BUSNAME,
230 SYSTEMD_PATH,
231 SYSTEMD_INTERFACE,
232 "RestartUnit");
233
234 method.append(systemdNetworkdService,
235 "replace");
236
237 bus.call_noreply(method);
238}
239
Ratan Gupta34f96d62017-06-15 09:16:22 +0530240bool Manager::getDHCPValue(const std::string& intf)
241{
242 bool dhcp = false;
243 // Get the interface mode value from systemd conf
244 using namespace std::string_literals;
245 fs::path confPath = confDir;
246 std::string fileName = "00-bmc-"s + intf + ".network"s;
247 confPath /= fileName;
248
249 try
250 {
251 config::Parser parser(confPath.string());
252 auto values = parser.getValues("Network","DHCP");
253 // There will be only single value for DHCP key.
254 if (values[0] == "true")
255 {
256 dhcp = true;
257 }
258 }
259 catch (InternalFailure& e)
260 {
261 commit<InternalFailure>();
262 }
263 return dhcp;
264}
265
Ratan Gupta6811f822017-04-14 16:34:56 +0530266}//namespace network
267}//namespace phosphor