blob: 98d957313c47abbc064abf2f39fb594cae0aa95b [file] [log] [blame]
Ratan Gupta7a7f0122018-03-07 12:31:05 +05301#include <chrono>
Tom Josepha30c8d32018-03-22 02:15:03 +05302#include <fstream>
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05003#include <stdio.h>
4#include <string.h>
5#include <stdint.h>
Hariharasubramanian R83951912016-01-20 07:06:36 -06006#include <arpa/inet.h>
tomjose26e17732016-03-03 08:52:51 -06007#include <string>
Ratan Guptacc6cdbf2017-09-01 23:06:25 +05308#include <experimental/filesystem>
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05009
Tom Josepha30c8d32018-03-22 02:15:03 +053010#include "app/channel.hpp"
Patrick Williams37af7332016-09-02 21:21:42 -050011#include "host-ipmid/ipmid-api.h"
Patrick Williams53a360e2016-08-12 22:01:02 -050012#include "ipmid.hpp"
Ratan Gupta7a7f0122018-03-07 12:31:05 +053013#include "timer.hpp"
Ratan Guptab8e99552017-07-27 07:07:48 +053014#include "transporthandler.hpp"
15#include "utils.hpp"
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080016#include "net.hpp"
Ratan Guptab8e99552017-07-27 07:07:48 +053017
18#include <phosphor-logging/log.hpp>
19#include <phosphor-logging/elog-errors.hpp>
20#include "xyz/openbmc_project/Common/error.hpp"
Adriana Kobylak5d6481f2015-10-29 21:44:55 -050021
Hariharasubramanian R83951912016-01-20 07:06:36 -060022#define SYSTEMD_NETWORKD_DBUS 1
23
24#ifdef SYSTEMD_NETWORKD_DBUS
25#include <systemd/sd-bus.h>
Sergey Solomineb9b8142016-08-23 09:07:28 -050026#include <mapper.h>
Hariharasubramanian R83951912016-01-20 07:06:36 -060027#endif
28
Ratan Gupta7a7f0122018-03-07 12:31:05 +053029extern std::unique_ptr<phosphor::ipmi::Timer> networkTimer;
Ratan Gupta1247e0b2018-03-07 10:47:25 +053030
Adriana Kobylake08fbc62016-02-09 16:17:23 -060031const int SIZE_MAC = 18; //xx:xx:xx:xx:xx:xx
Ratan Gupta1247e0b2018-03-07 10:47:25 +053032constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
Adriana Kobylake08fbc62016-02-09 16:17:23 -060033
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080034std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;
Hariharasubramanian R83951912016-01-20 07:06:36 -060035
Ratan Guptab8e99552017-07-27 07:07:48 +053036using namespace phosphor::logging;
37using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta7a7f0122018-03-07 12:31:05 +053038
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053039namespace fs = std::experimental::filesystem;
Hariharasubramanian R83951912016-01-20 07:06:36 -060040
Adriana Kobylak5d6481f2015-10-29 21:44:55 -050041void register_netfn_transport_functions() __attribute__((constructor));
42
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080043struct ChannelConfig_t* getChannelConfig(int channel)
44{
45 auto item = channelConfig.find(channel);
46 if (item == channelConfig.end())
47 {
48 channelConfig[channel] = std::make_unique<struct ChannelConfig_t>();
49 }
50
51 return channelConfig[channel].get();
52}
53
Ratan Guptab8e99552017-07-27 07:07:48 +053054// Helper Function to get IP Address/NetMask/Gateway/MAC Address from Network Manager or
Nan Li3d0df912016-10-18 19:51:41 +080055// Cache based on Set-In-Progress State
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080056ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data, int channel)
tomjose26e17732016-03-03 08:52:51 -060057{
tomjose26e17732016-03-03 08:52:51 -060058 ipmi_ret_t rc = IPMI_CC_OK;
Ratan Guptab8e99552017-07-27 07:07:48 +053059 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
Ratan Gupta533d03b2017-07-30 10:39:22 +053060
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080061 auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
62 // if ethdevice is an empty string they weren't expecting this channel.
63 if (ethdevice.empty())
64 {
65 // TODO: return error from getNetworkData()
66 return IPMI_CC_INVALID_FIELD_REQUEST;
67 }
68 auto ethIP = ethdevice + "/" + ipmi::network::IP_TYPE;
69 auto channelConf = getChannelConfig(channel);
70
Ratan Guptab8e99552017-07-27 07:07:48 +053071 try
tomjose26e17732016-03-03 08:52:51 -060072 {
Ratan Guptab8e99552017-07-27 07:07:48 +053073 switch (lan_param)
tomjose26e17732016-03-03 08:52:51 -060074 {
Ratan Guptab8e99552017-07-27 07:07:48 +053075 case LAN_PARM_IP:
76 {
77 std::string ipaddress;
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080078 if (channelConf->lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +053079 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053080 try
81 {
Ratan Guptadd646202017-11-21 17:46:59 +053082 auto ipObjectInfo = ipmi::getIPObject(
83 bus,
84 ipmi::network::IP_INTERFACE,
85 ipmi::network::ROOT,
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080086 ethIP);
Ratan Guptadd646202017-11-21 17:46:59 +053087
88 auto properties = ipmi::getAllDbusProperties(
89 bus,
90 ipObjectInfo.second,
91 ipObjectInfo.first,
92 ipmi::network::IP_INTERFACE);
93
94 ipaddress = properties["Address"].get<std::string>();
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053095 }
Gunnar Millsc9fa69e2018-04-08 16:35:25 -050096 // ignore the exception, as it is a valid condition that
97 // the system is not configured with any IP.
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053098 catch (InternalFailure& e)
99 {
100 // nothing to do.
101 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530102 }
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800103 else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530104 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800105 ipaddress = channelConf->ipaddr;
Ratan Guptab8e99552017-07-27 07:07:48 +0530106 }
107
108 inet_pton(AF_INET, ipaddress.c_str(),
109 reinterpret_cast<void*>(data));
110 }
111 break;
112
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530113 case LAN_PARM_IPSRC:
Ratan Guptab8e99552017-07-27 07:07:48 +0530114 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530115 std::string networkInterfacePath;
116
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800117 if (channelConf->lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +0530118 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530119 try
120 {
121 ipmi::ObjectTree ancestorMap;
122 // if the system is having ip object,then
123 // get the IP object.
124 auto ipObject = ipmi::getDbusObject(
125 bus,
126 ipmi::network::IP_INTERFACE,
127 ipmi::network::ROOT,
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800128 ethIP);
Ratan Guptab8e99552017-07-27 07:07:48 +0530129
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530130 // Get the parent interface of the IP object.
131 try
132 {
133 ipmi::InterfaceList interfaces;
134 interfaces.emplace_back(
135 ipmi::network::ETHERNET_INTERFACE);
Ratan Guptab8e99552017-07-27 07:07:48 +0530136
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530137 ancestorMap = ipmi::getAllAncestors(
138 bus,
139 ipObject.first,
140 std::move(interfaces));
141 }
142 catch (InternalFailure& e)
143 {
144 // if unable to get the parent interface
145 // then commit the error and return.
146 log<level::ERR>("Unable to get the parent interface",
147 entry("PATH=%s", ipObject.first.c_str()),
148 entry("INTERFACE=%s",
149 ipmi::network::ETHERNET_INTERFACE));
150 break;
151
152 }
153 // for an ip object there would be single parent
154 // interface.
155 networkInterfacePath = ancestorMap.begin()->first;
156 }
157 catch (InternalFailure& e)
158 {
159 // if there is no ip configured on the system,then
160 // get the network interface object.
161 auto networkInterfaceObject = ipmi::getDbusObject(
162 bus,
163 ipmi::network::ETHERNET_INTERFACE,
164 ipmi::network::ROOT,
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800165 ethdevice);
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530166
167 networkInterfacePath = networkInterfaceObject.first;
168 }
169
170 auto variant = ipmi::getDbusProperty(
171 bus,
172 ipmi::network::SERVICE,
173 networkInterfacePath,
174 ipmi::network::ETHERNET_INTERFACE,
175 "DHCPEnabled");
176
177 auto dhcpEnabled = variant.get<bool>();
178 // As per IPMI spec 2=>DHCP, 1=STATIC
179 auto ipsrc = dhcpEnabled ? ipmi::network::IPOrigin::DHCP :
180 ipmi::network::IPOrigin::STATIC;
181
182 memcpy(data, &ipsrc, ipmi::network::IPSRC_SIZE_BYTE);
183 }
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800184 else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530185 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800186 memcpy(data, &(channelConf->ipsrc),
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530187 ipmi::network::IPSRC_SIZE_BYTE);
188 }
189 }
190 break;
191
192 case LAN_PARM_SUBNET:
193 {
194 unsigned long mask {};
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800195 if (channelConf->lan_set_in_progress == SET_COMPLETE)
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530196 {
197 try
198 {
Ratan Guptadd646202017-11-21 17:46:59 +0530199 auto ipObjectInfo = ipmi::getIPObject(
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530200 bus,
201 ipmi::network::IP_INTERFACE,
202 ipmi::network::ROOT,
203 ipmi::network::IP_TYPE);
204
205 auto properties = ipmi::getAllDbusProperties(
206 bus,
207 ipObjectInfo.second,
208 ipObjectInfo.first,
209 ipmi::network::IP_INTERFACE);
210
211 auto prefix = properties["PrefixLength"].get<uint8_t>();
212 mask = ipmi::network::MASK_32_BIT;
213 mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
214 }
Gunnar Millsc9fa69e2018-04-08 16:35:25 -0500215 // ignore the exception, as it is a valid condition that
216 // the system is not configured with any IP.
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530217 catch (InternalFailure& e)
218 {
219 // nothing to do
220 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530221 memcpy(data, &mask, ipmi::network::IPV4_ADDRESS_SIZE_BYTE);
222 }
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800223 else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530224 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800225 inet_pton(AF_INET, channelConf->netmask.c_str(),
Ratan Guptab8e99552017-07-27 07:07:48 +0530226 reinterpret_cast<void*>(data));
Ratan Guptab8e99552017-07-27 07:07:48 +0530227 }
228
229 }
230 break;
231
232 case LAN_PARM_GATEWAY:
233 {
234 std::string gateway;
235
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800236 if (channelConf->lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +0530237 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530238 try
239 {
240 auto systemObject = ipmi::getDbusObject(
241 bus,
242 ipmi::network::SYSTEMCONFIG_INTERFACE,
243 ipmi::network::ROOT);
Ratan Guptab8e99552017-07-27 07:07:48 +0530244
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530245 auto systemProperties = ipmi::getAllDbusProperties(
246 bus,
247 systemObject.second,
248 systemObject.first,
249 ipmi::network::SYSTEMCONFIG_INTERFACE);
Ratan Guptab8e99552017-07-27 07:07:48 +0530250
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530251 gateway = systemProperties["DefaultGateway"].get<
252 std::string>();
253 }
Gunnar Millsc9fa69e2018-04-08 16:35:25 -0500254 // ignore the exception, as it is a valid condition that
255 // the system is not configured with any IP.
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530256 catch (InternalFailure& e)
257 {
258 // nothing to do
259 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530260
261 }
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800262 else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530263 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800264 gateway = channelConf->gateway;
Ratan Guptab8e99552017-07-27 07:07:48 +0530265 }
266
267 inet_pton(AF_INET, gateway.c_str(),
268 reinterpret_cast<void*>(data));
Ratan Guptab8e99552017-07-27 07:07:48 +0530269 }
270 break;
271
272 case LAN_PARM_MAC:
273 {
274 std::string macAddress;
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800275 if (channelConf->lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +0530276 {
277 auto macObjectInfo = ipmi::getDbusObject(
278 bus,
279 ipmi::network::MAC_INTERFACE,
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800280 ipmi::network::ROOT,
281 ethdevice);
Ratan Guptab8e99552017-07-27 07:07:48 +0530282
283 auto variant = ipmi::getDbusProperty(
284 bus,
285 macObjectInfo.second,
286 macObjectInfo.first,
287 ipmi::network::MAC_INTERFACE,
288 "MACAddress");
289
290 macAddress = variant.get<std::string>();
291
292 }
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800293 else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530294 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800295 macAddress = channelConf->macAddress;
Ratan Guptab8e99552017-07-27 07:07:48 +0530296 }
297
298 sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
299 (data),
300 (data + 1),
301 (data + 2),
302 (data + 3),
303 (data + 4),
304 (data + 5));
305 }
306 break;
307
Ratan Gupta533d03b2017-07-30 10:39:22 +0530308 case LAN_PARM_VLAN:
309 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530310 uint16_t vlanID {};
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800311 if (channelConf->lan_set_in_progress == SET_COMPLETE)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530312 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530313 try
Ratan Gupta533d03b2017-07-30 10:39:22 +0530314 {
Ratan Guptadd646202017-11-21 17:46:59 +0530315 auto ipObjectInfo = ipmi::getIPObject(
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530316 bus,
317 ipmi::network::IP_INTERFACE,
318 ipmi::network::ROOT,
319 ipmi::network::IP_TYPE);
320
321 vlanID = static_cast<uint16_t>(
322 ipmi::network::getVLAN(ipObjectInfo.first));
323
324 vlanID = htole16(vlanID);
325
326 if (vlanID)
327 {
328 //Enable the 16th bit
329 vlanID |= htole16(ipmi::network::VLAN_ENABLE_MASK);
330 }
331 }
Gunnar Millsc9fa69e2018-04-08 16:35:25 -0500332 // ignore the exception, as it is a valid condition that
333 // the system is not configured with any IP.
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530334 catch (InternalFailure& e)
335 {
336 // nothing to do
Ratan Gupta533d03b2017-07-30 10:39:22 +0530337 }
338
339 memcpy(data, &vlanID, ipmi::network::VLAN_SIZE_BYTE);
340 }
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800341 else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530342 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800343 memcpy(data, &(channelConf->vlanID),
Ratan Gupta533d03b2017-07-30 10:39:22 +0530344 ipmi::network::VLAN_SIZE_BYTE);
345 }
346 }
347 break;
348
Ratan Guptab8e99552017-07-27 07:07:48 +0530349 default:
350 rc = IPMI_CC_PARM_OUT_OF_RANGE;
tomjose26e17732016-03-03 08:52:51 -0600351 }
352 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530353 catch (InternalFailure& e)
tomjose26e17732016-03-03 08:52:51 -0600354 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530355 commit<InternalFailure>();
356 rc = IPMI_CC_UNSPECIFIED_ERROR;
357 return rc;
tomjose26e17732016-03-03 08:52:51 -0600358 }
tomjose26e17732016-03-03 08:52:51 -0600359 return rc;
360}
361
Tom Josepha30c8d32018-03-22 02:15:03 +0530362namespace cipher
363{
364
365std::vector<uint8_t> getCipherList()
366{
367 std::vector<uint8_t> cipherList;
368
369 std::ifstream jsonFile(configFile);
370 if (!jsonFile.is_open())
371 {
372 log<level::ERR>("Channel Cipher suites file not found");
373 elog<InternalFailure>();
374 }
375
376 auto data = Json::parse(jsonFile, nullptr, false);
377 if (data.is_discarded())
378 {
379 log<level::ERR>("Parsing channel cipher suites JSON failed");
380 elog<InternalFailure>();
381 }
382
383 // Byte 1 is reserved
384 cipherList.push_back(0x00);
385
386 for (const auto& record : data)
387 {
388 cipherList.push_back(record.value(cipher, 0));
389 }
390
391 return cipherList;
392}
393
394} //namespace cipher
395
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500396ipmi_ret_t ipmi_transport_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
397 ipmi_request_t request, ipmi_response_t response,
398 ipmi_data_len_t data_len, ipmi_context_t context)
399{
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500400 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800401 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500402 *data_len = 0;
403 return rc;
404}
405
Ratan Guptab8e99552017-07-27 07:07:48 +0530406struct set_lan_t
407{
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500408 uint8_t channel;
409 uint8_t parameter;
410 uint8_t data[8]; // Per IPMI spec, not expecting more than this size
Ratan Guptab8e99552017-07-27 07:07:48 +0530411} __attribute__((packed));
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500412
Ratan Guptab8e99552017-07-27 07:07:48 +0530413ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
414 ipmi_cmd_t cmd,
415 ipmi_request_t request,
416 ipmi_response_t response,
417 ipmi_data_len_t data_len,
418 ipmi_context_t context)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500419{
420 ipmi_ret_t rc = IPMI_CC_OK;
421 *data_len = 0;
Nan Li3d0df912016-10-18 19:51:41 +0800422
Ratan Gupta7a7f0122018-03-07 12:31:05 +0530423 using namespace std::chrono_literals;
424
425 // time to wait before applying the network changes.
426 constexpr auto networkTimeout = 10000000us; // 10 sec
427
Ratan Guptab8e99552017-07-27 07:07:48 +0530428 char ipaddr[INET_ADDRSTRLEN];
429 char netmask[INET_ADDRSTRLEN];
430 char gateway[INET_ADDRSTRLEN];
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500431
Ratan Guptab8e99552017-07-27 07:07:48 +0530432 auto reqptr = reinterpret_cast<const set_lan_t*>(request);
433 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500434
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800435 // channel number is the lower nibble
436 int channel = reqptr->channel & CHANNEL_MASK;
437 auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
438 if (ethdevice.empty())
439 {
440 return IPMI_CC_INVALID_FIELD_REQUEST;
441 }
442 auto channelConf = getChannelConfig(channel);
443
Ratan Guptab8e99552017-07-27 07:07:48 +0530444 switch (reqptr->parameter)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500445 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530446 case LAN_PARM_IP:
Hariharasubramanian R83951912016-01-20 07:06:36 -0600447 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530448 snprintf(ipaddr, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
449 reqptr->data[0], reqptr->data[1],
450 reqptr->data[2], reqptr->data[3]);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500451
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800452 channelConf->ipaddr.assign(ipaddr);
Ratan Guptab8e99552017-07-27 07:07:48 +0530453 }
454 break;
455
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530456 case LAN_PARM_IPSRC:
457 {
458 uint8_t ipsrc{};
459 memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE);
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800460 channelConf->ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc);
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530461 }
462 break;
463
Ratan Guptab8e99552017-07-27 07:07:48 +0530464 case LAN_PARM_MAC:
465 {
466 char mac[SIZE_MAC];
467
468 snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
469 reqptr->data[0],
470 reqptr->data[1],
471 reqptr->data[2],
472 reqptr->data[3],
473 reqptr->data[4],
474 reqptr->data[5]);
475
476 auto macObjectInfo = ipmi::getDbusObject(
477 bus,
478 ipmi::network::MAC_INTERFACE,
479 ipmi::network::ROOT,
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800480 ethdevice);
Ratan Guptab8e99552017-07-27 07:07:48 +0530481
482 ipmi::setDbusProperty(bus,
483 macObjectInfo.second,
484 macObjectInfo.first,
485 ipmi::network::MAC_INTERFACE,
486 "MACAddress",
487 std::string(mac));
488
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800489 channelConf->macAddress = mac;
Ratan Guptab8e99552017-07-27 07:07:48 +0530490 }
491 break;
492
493 case LAN_PARM_SUBNET:
494 {
495 snprintf(netmask, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
496 reqptr->data[0], reqptr->data[1],
497 reqptr->data[2], reqptr->data[3]);
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800498 channelConf->netmask.assign(netmask);
Ratan Guptab8e99552017-07-27 07:07:48 +0530499 }
500 break;
501
502 case LAN_PARM_GATEWAY:
503 {
504 snprintf(gateway, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
505 reqptr->data[0], reqptr->data[1],
506 reqptr->data[2], reqptr->data[3]);
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800507 channelConf->gateway.assign(gateway);
Ratan Guptab8e99552017-07-27 07:07:48 +0530508 }
509 break;
510
Ratan Gupta533d03b2017-07-30 10:39:22 +0530511 case LAN_PARM_VLAN:
512 {
513 uint16_t vlan {};
514 memcpy(&vlan, reqptr->data, ipmi::network::VLAN_SIZE_BYTE);
515 // We are not storing the enable bit
516 // We assume that ipmitool always send enable
517 // bit as 1.
518 vlan = le16toh(vlan);
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800519 channelConf->vlanID = vlan;
Ratan Gupta533d03b2017-07-30 10:39:22 +0530520 }
521 break;
522
Ratan Guptab8e99552017-07-27 07:07:48 +0530523 case LAN_PARM_INPROGRESS:
524 {
525 if (reqptr->data[0] == SET_COMPLETE)
526 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800527 channelConf->lan_set_in_progress = SET_COMPLETE;
Ratan Guptab8e99552017-07-27 07:07:48 +0530528
529 log<level::INFO>("Network data from Cache",
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800530 entry("PREFIX=%s", channelConf->netmask.c_str()),
531 entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
532 entry("GATEWAY=%s", channelConf->gateway.c_str()),
533 entry("VLAN=%d", channelConf->vlanID));
Ratan Guptab8e99552017-07-27 07:07:48 +0530534
Ratan Gupta7a7f0122018-03-07 12:31:05 +0530535 if (!networkTimer)
536 {
537 log<level::ERR>("Network timer is not instantiated");
538 return IPMI_CC_UNSPECIFIED_ERROR;
539 }
540
541 // start/restart the timer
542 networkTimer->startTimer(networkTimeout);
Ratan Guptab8e99552017-07-27 07:07:48 +0530543 }
544 else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
545 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800546 channelConf->lan_set_in_progress = SET_IN_PROGRESS;
Ratan Gupta7a7f0122018-03-07 12:31:05 +0530547 channelConf->flush = true;
Ratan Guptab8e99552017-07-27 07:07:48 +0530548 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530549 }
550 break;
551
552 default:
553 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530554 rc = IPMI_CC_PARM_NOT_SUPPORTED;
555 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530556 }
vishwa1eaea4f2016-02-26 11:57:40 -0600557
tomjose26e17732016-03-03 08:52:51 -0600558 return rc;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500559}
560
Ratan Guptab8e99552017-07-27 07:07:48 +0530561struct get_lan_t
562{
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500563 uint8_t rev_channel;
564 uint8_t parameter;
565 uint8_t parameter_set;
566 uint8_t parameter_block;
Ratan Guptab8e99552017-07-27 07:07:48 +0530567} __attribute__((packed));
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500568
Ratan Guptab8e99552017-07-27 07:07:48 +0530569ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
570 ipmi_cmd_t cmd,
571 ipmi_request_t request,
572 ipmi_response_t response,
573 ipmi_data_len_t data_len,
574 ipmi_context_t context)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500575{
576 ipmi_ret_t rc = IPMI_CC_OK;
577 *data_len = 0;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500578 const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500579
580 get_lan_t *reqptr = (get_lan_t*) request;
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800581 // channel number is the lower nibble
582 int channel = reqptr->rev_channel & CHANNEL_MASK;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500583
584 if (reqptr->rev_channel & 0x80) // Revision is bit 7
585 {
586 // Only current revision was requested
587 *data_len = sizeof(current_revision);
588 memcpy(response, &current_revision, *data_len);
589 return IPMI_CC_OK;
590 }
591
Tom Josepha30c8d32018-03-22 02:15:03 +0530592 static std::vector<uint8_t> cipherList;
593 static auto listInit = false;
594
595 if (!listInit)
596 {
597 try
598 {
599 cipherList = cipher::getCipherList();
600 listInit = true;
601 }
602 catch (const std::exception &e)
603 {
604 return IPMI_CC_UNSPECIFIED_ERROR;
605 }
606 }
607
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800608 auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
609 if (ethdevice.empty())
610 {
611 return IPMI_CC_INVALID_FIELD_REQUEST;
612 }
613 auto channelConf = getChannelConfig(channel);
614
Adriana Kobylake08fbc62016-02-09 16:17:23 -0600615 if (reqptr->parameter == LAN_PARM_INPROGRESS)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500616 {
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800617 uint8_t buf[] = {current_revision, channelConf->lan_set_in_progress};
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500618 *data_len = sizeof(buf);
619 memcpy(response, &buf, *data_len);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500620 }
Adriana Kobylake08fbc62016-02-09 16:17:23 -0600621 else if (reqptr->parameter == LAN_PARM_AUTHSUPPORT)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500622 {
623 uint8_t buf[] = {current_revision,0x04};
624 *data_len = sizeof(buf);
625 memcpy(response, &buf, *data_len);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500626 }
Adriana Kobylake08fbc62016-02-09 16:17:23 -0600627 else if (reqptr->parameter == LAN_PARM_AUTHENABLES)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500628 {
629 uint8_t buf[] = {current_revision,0x04,0x04,0x04,0x04,0x04};
630 *data_len = sizeof(buf);
631 memcpy(response, &buf, *data_len);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500632 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530633 else if ((reqptr->parameter == LAN_PARM_IP) ||
634 (reqptr->parameter == LAN_PARM_SUBNET) ||
635 (reqptr->parameter == LAN_PARM_GATEWAY) ||
636 (reqptr->parameter == LAN_PARM_MAC))
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500637 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530638 uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1] = {};
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500639
tomjose26e17732016-03-03 08:52:51 -0600640 *data_len = sizeof(current_revision);
641 memcpy(buf, &current_revision, *data_len);
642
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800643 if (getNetworkData(reqptr->parameter, &buf[1], channel) == IPMI_CC_OK)
vishwa1eaea4f2016-02-26 11:57:40 -0600644 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530645 if (reqptr->parameter == LAN_PARM_MAC)
646 {
647 *data_len = sizeof(buf);
648 }
649 else
650 {
651 *data_len = ipmi::network::IPV4_ADDRESS_SIZE_BYTE + 1;
652 }
tomjose26e17732016-03-03 08:52:51 -0600653 memcpy(response, &buf, *data_len);
Adriana Kobylak342df102016-02-10 13:48:16 -0600654 }
tomjose26e17732016-03-03 08:52:51 -0600655 else
Hariharasubramanian R83951912016-01-20 07:06:36 -0600656 {
tomjose26e17732016-03-03 08:52:51 -0600657 rc = IPMI_CC_UNSPECIFIED_ERROR;
Hariharasubramanian R83951912016-01-20 07:06:36 -0600658 }
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500659 }
Ratan Gupta533d03b2017-07-30 10:39:22 +0530660 else if (reqptr->parameter == LAN_PARM_VLAN)
661 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530662 uint8_t buf[ipmi::network::VLAN_SIZE_BYTE + 1] = {};
Ratan Gupta533d03b2017-07-30 10:39:22 +0530663
664 *data_len = sizeof(current_revision);
665 memcpy(buf, &current_revision, *data_len);
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800666 if (getNetworkData(reqptr->parameter, &buf[1], channel) == IPMI_CC_OK)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530667 {
668 *data_len = sizeof(buf);
669 memcpy(response, &buf, *data_len);
670 }
671 }
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530672 else if (reqptr->parameter == LAN_PARM_IPSRC)
673 {
674 uint8_t buff[ipmi::network::IPSRC_SIZE_BYTE + 1] = {};
675 *data_len = sizeof(current_revision);
676 memcpy(buff, &current_revision, *data_len);
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800677 if (getNetworkData(reqptr->parameter, &buff[1], channel) == IPMI_CC_OK)
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530678 {
679 *data_len = sizeof(buff);
680 memcpy(response, &buff, *data_len);
681 }
682 }
Tom Josepha30c8d32018-03-22 02:15:03 +0530683 else if (reqptr->parameter == CIPHER_SUITE_COUNT)
684 {
685 *(static_cast<uint8_t*>(response)) = current_revision;
686 // Byte 1 is reserved byte and does not indicate a cipher suite ID, so
687 // no of cipher suite entry count is one less than the size of the
688 // vector
689 auto count = static_cast<uint8_t>(cipherList.size() - 1);
690 *(static_cast<uint8_t*>(response) + 1) = count;
691 *data_len = sizeof(current_revision) + sizeof(count);
692 }
693 else if (reqptr->parameter == CIPHER_SUITE_ENTRIES)
694 {
695 *(static_cast<uint8_t*>(response)) = current_revision;
696 // Byte 1 is reserved
697 std::copy_n(cipherList.data(),
698 cipherList.size(),
699 static_cast<uint8_t*>(response) + 1);
700 *data_len = sizeof(current_revision) +
701 static_cast<uint8_t>(cipherList.size());
702 }
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500703 else
704 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530705 log<level::ERR>("Unsupported parameter",
706 entry("PARAMETER=0x%x", reqptr->parameter));
vishwa1eaea4f2016-02-26 11:57:40 -0600707 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500708 }
709
710 return rc;
711}
712
Ratan Gupta7a7f0122018-03-07 12:31:05 +0530713void applyChanges(int channel)
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530714{
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530715 std::string ipaddress;
716 std::string gateway;
717 uint8_t prefix {};
718 uint32_t vlanID {};
719 std::string networkInterfacePath;
720 ipmi::DbusObjectInfo ipObject;
721 ipmi::DbusObjectInfo systemObject;
722
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530723 auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
724 if (ethdevice.empty())
725 {
Ratan Gupta7a7f0122018-03-07 12:31:05 +0530726 log<level::ERR>("Unable to get the interface name",
727 entry("CHANNEL=%d", channel));
728 return;
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530729 }
730 auto ethIp = ethdevice + "/" + ipmi::network::IP_TYPE;
731 auto channelConf = getChannelConfig(channel);
732
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530733 try
734 {
735 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
736
737 log<level::INFO>("Network data from Cache",
738 entry("PREFIX=%s", channelConf->netmask.c_str()),
739 entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
740 entry("GATEWAY=%s", channelConf->gateway.c_str()),
741 entry("VLAN=%d", channelConf->vlanID),
742 entry("IPSRC=%d", channelConf->ipsrc));
743 if (channelConf->vlanID != ipmi::network::VLAN_ID_MASK)
744 {
745 //get the first twelve bits which is vlan id
746 //not interested in rest of the bits.
747 channelConf->vlanID = le32toh(channelConf->vlanID);
748 vlanID = channelConf->vlanID & ipmi::network::VLAN_ID_MASK;
749 }
750
751 // if the asked ip src is DHCP then not interested in
752 // any given data except vlan.
753 if (channelConf->ipsrc != ipmi::network::IPOrigin::DHCP)
754 {
755 // always get the system object
756 systemObject = ipmi::getDbusObject(
757 bus,
758 ipmi::network::SYSTEMCONFIG_INTERFACE,
759 ipmi::network::ROOT);
760
761 // the below code is to determine the mode of the interface
762 // as the handling is same, if the system is configured with
763 // DHCP or user has given all the data.
764 try
765 {
766 ipmi::ObjectTree ancestorMap;
767
768 ipmi::InterfaceList interfaces {
769 ipmi::network::ETHERNET_INTERFACE };
770
771 // if the system is having ip object,then
772 // get the IP object.
Ratan Guptadf53d222018-03-18 23:13:39 +0530773 ipObject = ipmi::getIPObject(bus,
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530774 ipmi::network::IP_INTERFACE,
775 ipmi::network::ROOT,
776 ethIp);
777
778 // Get the parent interface of the IP object.
779 try
780 {
781 ancestorMap = ipmi::getAllAncestors(bus,
782 ipObject.first,
783 std::move(interfaces));
784 }
785 catch (InternalFailure& e)
786 {
787 // if unable to get the parent interface
788 // then commit the error and return.
789 log<level::ERR>("Unable to get the parent interface",
790 entry("PATH=%s", ipObject.first.c_str()),
791 entry("INTERFACE=%s",
792 ipmi::network::ETHERNET_INTERFACE));
793 commit<InternalFailure>();
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530794 channelConf->clear();
Ratan Gupta7a7f0122018-03-07 12:31:05 +0530795 return;
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530796 }
797
798 networkInterfacePath = ancestorMap.begin()->first;
799 }
800 catch (InternalFailure& e)
801 {
802 // TODO Currently IPMI supports single interface,need to handle
803 // Multiple interface through
804 // https://github.com/openbmc/openbmc/issues/2138
805
806 // if there is no ip configured on the system,then
807 // get the network interface object.
808 auto networkInterfaceObject = ipmi::getDbusObject(
809 bus,
810 ipmi::network::ETHERNET_INTERFACE,
811 ipmi::network::ROOT,
812 ethdevice);
813
814 networkInterfacePath = std::move(networkInterfaceObject.first);
815 }
816
817 // get the configured mode on the system.
818 auto enableDHCP = ipmi::getDbusProperty(
819 bus,
820 ipmi::network::SERVICE,
821 networkInterfacePath,
822 ipmi::network::ETHERNET_INTERFACE,
823 "DHCPEnabled").get<bool>();
824
825 // if ip address source is not given then get the ip source mode
826 // from the system so that it can be applied later.
827 if (channelConf->ipsrc == ipmi::network::IPOrigin::UNSPECIFIED)
828 {
829 channelConf->ipsrc = (enableDHCP) ?
830 ipmi::network::IPOrigin::DHCP :
831 ipmi::network::IPOrigin::STATIC;
832 }
833
834 // check whether user has given all the data
835 // or the configured system interface is dhcp enabled,
836 // in both of the cases get the values from the cache.
837 if ((!channelConf->ipaddr.empty() &&
838 !channelConf->netmask.empty() &&
839 !channelConf->gateway.empty()) ||
840 (enableDHCP)) // configured system interface mode = DHCP
841 {
842 //convert mask into prefix
843 ipaddress = channelConf->ipaddr;
844 prefix = ipmi::network::toPrefix(AF_INET, channelConf->netmask);
845 gateway = channelConf->gateway;
846 }
847 else // asked ip src = static and configured system src = static
848 // or partially given data.
849 {
850 // We have partial filled cache so get the remaining
851 // info from the system.
852
853 // Get the network data from the system as user has
854 // not given all the data then use the data fetched from the
855 // system but it is implementation dependent,IPMI spec doesn't
856 // force it.
857
858 // if system is not having any ip object don't throw error,
859 try
860 {
861 auto properties = ipmi::getAllDbusProperties(
862 bus,
863 ipObject.second,
864 ipObject.first,
865 ipmi::network::IP_INTERFACE);
866
867 ipaddress = channelConf->ipaddr.empty() ?
868 properties["Address"].get<std::string>() :
869 channelConf->ipaddr;
870
871 prefix = channelConf->netmask.empty() ?
872 properties["PrefixLength"].get<uint8_t>() :
873 ipmi::network::toPrefix(AF_INET,
874 channelConf->netmask);
875 }
876 catch (InternalFailure& e)
877 {
878 log<level::INFO>("Failed to get IP object which matches",
879 entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
Joseph Reynolds510eb9c2018-05-30 11:51:28 -0500880 entry("MATCH=%s", ethIp.c_str()));
Ratan Gupta1247e0b2018-03-07 10:47:25 +0530881 }
882
883 auto systemProperties = ipmi::getAllDbusProperties(
884 bus,
885 systemObject.second,
886 systemObject.first,
887 ipmi::network::SYSTEMCONFIG_INTERFACE);
888
889 gateway = channelConf->gateway.empty() ?
890 systemProperties["DefaultGateway"].get<std::string>() :
891 channelConf->gateway;
892 }
893 }
894
895 // Currently network manager doesn't support purging of all the
896 // ip addresses and the vlan interfaces from the parent interface,
897 // TODO once the support is there, will make the change here.
898 // https://github.com/openbmc/openbmc/issues/2141.
899
900 // TODO Currently IPMI supports single interface,need to handle
901 // Multiple interface through
902 // https://github.com/openbmc/openbmc/issues/2138
903
904 // instead of deleting all the vlan interfaces and
905 // all the ipv4 address,we will call reset method.
906 //delete all the vlan interfaces
907
908 ipmi::deleteAllDbusObjects(bus,
909 ipmi::network::ROOT,
910 ipmi::network::VLAN_INTERFACE);
911
912 // set the interface mode to static
913 auto networkInterfaceObject = ipmi::getDbusObject(
914 bus,
915 ipmi::network::ETHERNET_INTERFACE,
916 ipmi::network::ROOT,
917 ethdevice);
918
919 // setting the physical interface mode to static.
920 ipmi::setDbusProperty(bus,
921 ipmi::network::SERVICE,
922 networkInterfaceObject.first,
923 ipmi::network::ETHERNET_INTERFACE,
924 "DHCPEnabled",
925 false);
926
927 networkInterfacePath = networkInterfaceObject.first;
928
929 //delete all the ipv4 addresses
930 ipmi::deleteAllDbusObjects(bus,
931 ipmi::network::ROOT,
932 ipmi::network::IP_INTERFACE,
933 ethIp);
934
935 if (vlanID)
936 {
937 ipmi::network::createVLAN(bus,
938 ipmi::network::SERVICE,
939 ipmi::network::ROOT,
940 ethdevice,
941 vlanID);
942
943 auto networkInterfaceObject = ipmi::getDbusObject(
944 bus,
945 ipmi::network::VLAN_INTERFACE,
946 ipmi::network::ROOT);
947
948 networkInterfacePath = networkInterfaceObject.first;
949 }
950
951 if (channelConf->ipsrc == ipmi::network::IPOrigin::DHCP)
952 {
953 ipmi::setDbusProperty(bus,
954 ipmi::network::SERVICE,
955 networkInterfacePath,
956 ipmi::network::ETHERNET_INTERFACE,
957 "DHCPEnabled",
958 true);
959 }
960 else
961 {
962 //change the mode to static
963 ipmi::setDbusProperty(bus,
964 ipmi::network::SERVICE,
965 networkInterfacePath,
966 ipmi::network::ETHERNET_INTERFACE,
967 "DHCPEnabled",
968 false);
969
970 if (!ipaddress.empty())
971 {
972 ipmi::network::createIP(bus,
973 ipmi::network::SERVICE,
974 networkInterfacePath,
975 ipv4Protocol,
976 ipaddress,
977 prefix);
978 }
979
980 if (!gateway.empty())
981 {
982 ipmi::setDbusProperty(bus,
983 systemObject.second,
984 systemObject.first,
985 ipmi::network::SYSTEMCONFIG_INTERFACE,
986 "DefaultGateway",
987 std::string(gateway));
988 }
989 }
990
991 }
992 catch (InternalFailure& e)
993 {
994 log<level::ERR>("Failed to set network data",
995 entry("PREFIX=%d", prefix),
996 entry("ADDRESS=%s", ipaddress.c_str()),
997 entry("GATEWAY=%s", gateway.c_str()),
998 entry("VLANID=%d", vlanID),
999 entry("IPSRC=%d", channelConf->ipsrc));
1000
1001 commit<InternalFailure>();
Ratan Gupta1247e0b2018-03-07 10:47:25 +05301002 }
1003
1004 channelConf->clear();
Ratan Gupta7a7f0122018-03-07 12:31:05 +05301005}
1006
1007void commitNetworkChanges()
1008{
1009 for (const auto &channel : channelConfig)
1010 {
1011 if (channel.second->flush)
1012 {
1013 applyChanges(channel.first);
1014 }
1015 }
1016}
1017
1018void createNetworkTimer()
1019{
1020 if (!networkTimer)
1021 {
1022 std::function<void()> networkTimerCallback(
1023 std::bind(&commitNetworkChanges));
1024
1025 networkTimer =
1026 std::make_unique<phosphor::ipmi::Timer>(
1027 ipmid_get_sd_event_connection(),
1028 networkTimerCallback);
1029 }
1030
Ratan Gupta1247e0b2018-03-07 10:47:25 +05301031}
1032
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05001033void register_netfn_transport_functions()
1034{
Ratan Gupta7a7f0122018-03-07 12:31:05 +05301035 // As this timer is only for transport handler
1036 // so creating it here.
1037 createNetworkTimer();
Tom05732372016-09-06 17:21:23 +05301038 // <Wildcard Command>
Tom05732372016-09-06 17:21:23 +05301039 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_WILDCARD, NULL, ipmi_transport_wildcard,
1040 PRIVILEGE_USER);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05001041
Tom05732372016-09-06 17:21:23 +05301042 // <Set LAN Configuration Parameters>
Tom05732372016-09-06 17:21:23 +05301043 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_LAN, NULL, ipmi_transport_set_lan,
1044 PRIVILEGE_ADMIN);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05001045
Tom05732372016-09-06 17:21:23 +05301046 // <Get LAN Configuration Parameters>
Tom05732372016-09-06 17:21:23 +05301047 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_LAN, NULL, ipmi_transport_get_lan,
1048 PRIVILEGE_OPERATOR);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05001049
1050 return;
1051}