summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@in.ibm.com>2017-09-01 23:06:25 +0530
committerPatrick Williams <patrick@stwcx.xyz>2017-09-08 17:30:39 +0000
commitcc6cdbf1d4111b0f29cc3dd37c61317a7abff58f (patch)
treeefb2948f0ab6738ba8be78f9d8ece193210ce29f
parent558184ea80cd34bb62052e885b64ab38a3edf950 (diff)
downloadphosphor-host-ipmid-cc6cdbf1d4111b0f29cc3dd37c61317a7abff58f.tar.gz
phosphor-host-ipmid-cc6cdbf1d4111b0f29cc3dd37c61317a7abff58f.zip
GetLan: Support for get/set of ipsrc parameter
Change-Id: Id9c52bb0963c5924f80f9e273b53ed5556b16a2c Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
-rw-r--r--transporthandler.cpp254
-rw-r--r--transporthandler.hpp3
-rw-r--r--types.hpp11
-rw-r--r--utils.cpp45
-rw-r--r--utils.hpp11
5 files changed, 265 insertions, 59 deletions
diff --git a/transporthandler.cpp b/transporthandler.cpp
index 30526b3..e571d30 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <arpa/inet.h>
#include <string>
+#include <experimental/filesystem>
#include "host-ipmid/ipmid-api.h"
#include "ipmid.hpp"
@@ -40,6 +41,7 @@ uint8_t lan_set_in_progress = SET_COMPLETE;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+namespace fs = std::experimental::filesystem;
void register_netfn_transport_functions() __attribute__((constructor));
@@ -59,19 +61,28 @@ ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
std::string ipaddress;
if (lan_set_in_progress == SET_COMPLETE)
{
- auto ipObjectInfo = ipmi::getDbusObject(
- bus,
- ipmi::network::IP_INTERFACE,
- ipmi::network::ROOT,
- ipmi::network::IP_TYPE);
-
- auto properties = ipmi::getAllDbusProperties(
- bus,
- ipObjectInfo.second,
- ipObjectInfo.first,
- ipmi::network::IP_INTERFACE);
-
- ipaddress = properties["Address"].get<std::string>();
+ try
+ {
+ auto ipObjectInfo = ipmi::getDbusObject(
+ bus,
+ ipmi::network::IP_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::IP_TYPE);
+
+ auto properties = ipmi::getAllDbusProperties(
+ bus,
+ ipObjectInfo.second,
+ ipObjectInfo.first,
+ ipmi::network::IP_INTERFACE);
+
+ ipaddress = properties["Address"].get<std::string>();
+ }
+ // ignore the exception, as it is a valid condtion that
+ // system is not confiured with any ip.
+ catch (InternalFailure& e)
+ {
+ // nothing to do.
+ }
}
else if (lan_set_in_progress == SET_IN_PROGRESS)
{
@@ -83,32 +94,120 @@ ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
}
break;
+ case LAN_PARM_IPSRC:
+ {
+ std::string networkInterfacePath;
+
+ if (lan_set_in_progress == SET_COMPLETE)
+ {
+ try
+ {
+ ipmi::ObjectTree ancestorMap;
+ // if the system is having ip object,then
+ // get the IP object.
+ auto ipObject = ipmi::getDbusObject(
+ bus,
+ ipmi::network::IP_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::IP_TYPE);
+
+ // Get the parent interface of the IP object.
+ try
+ {
+ ipmi::InterfaceList interfaces;
+ interfaces.emplace_back(
+ ipmi::network::ETHERNET_INTERFACE);
+
+ ancestorMap = ipmi::getAllAncestors(
+ bus,
+ ipObject.first,
+ std::move(interfaces));
+ }
+ catch (InternalFailure& e)
+ {
+ // if unable to get the parent interface
+ // then commit the error and return.
+ log<level::ERR>("Unable to get the parent interface",
+ entry("PATH=%s", ipObject.first.c_str()),
+ entry("INTERFACE=%s",
+ ipmi::network::ETHERNET_INTERFACE));
+ break;
+
+ }
+ // for an ip object there would be single parent
+ // interface.
+ networkInterfacePath = ancestorMap.begin()->first;
+ }
+ catch (InternalFailure& e)
+ {
+ // if there is no ip configured on the system,then
+ // get the network interface object.
+ auto networkInterfaceObject = ipmi::getDbusObject(
+ bus,
+ ipmi::network::ETHERNET_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::INTERFACE);
+
+ networkInterfacePath = networkInterfaceObject.first;
+ }
+
+ auto variant = ipmi::getDbusProperty(
+ bus,
+ ipmi::network::SERVICE,
+ networkInterfacePath,
+ ipmi::network::ETHERNET_INTERFACE,
+ "DHCPEnabled");
+
+ auto dhcpEnabled = variant.get<bool>();
+ // As per IPMI spec 2=>DHCP, 1=STATIC
+ auto ipsrc = dhcpEnabled ? ipmi::network::IPOrigin::DHCP :
+ ipmi::network::IPOrigin::STATIC;
+
+ memcpy(data, &ipsrc, ipmi::network::IPSRC_SIZE_BYTE);
+ }
+ else if (lan_set_in_progress == SET_IN_PROGRESS)
+ {
+ memcpy(data, &(channelConfig.ipsrc),
+ ipmi::network::IPSRC_SIZE_BYTE);
+ }
+ }
+ break;
+
case LAN_PARM_SUBNET:
{
+ unsigned long mask {};
if (lan_set_in_progress == SET_COMPLETE)
{
- auto ipObjectInfo = ipmi::getDbusObject(
- bus,
- ipmi::network::IP_INTERFACE,
- ipmi::network::ROOT,
- ipmi::network::IP_TYPE);
-
- auto properties = ipmi::getAllDbusProperties(
- bus,
- ipObjectInfo.second,
- ipObjectInfo.first,
- ipmi::network::IP_INTERFACE);
-
- auto prefix = properties["PrefixLength"].get<uint8_t>();
- unsigned long mask = ipmi::network::MASK_32_BIT;
- mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
+ try
+ {
+ auto ipObjectInfo = ipmi::getDbusObject(
+ bus,
+ ipmi::network::IP_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::IP_TYPE);
+
+ auto properties = ipmi::getAllDbusProperties(
+ bus,
+ ipObjectInfo.second,
+ ipObjectInfo.first,
+ ipmi::network::IP_INTERFACE);
+
+ auto prefix = properties["PrefixLength"].get<uint8_t>();
+ mask = ipmi::network::MASK_32_BIT;
+ mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
+ }
+ // ignore the exception, as it is a valid condtion that
+ // system is not confiured with any ip.
+ catch (InternalFailure& e)
+ {
+ // nothing to do
+ }
memcpy(data, &mask, ipmi::network::IPV4_ADDRESS_SIZE_BYTE);
}
else if (lan_set_in_progress == SET_IN_PROGRESS)
{
inet_pton(AF_INET, channelConfig.netmask.c_str(),
reinterpret_cast<void*>(data));
-
}
}
@@ -120,19 +219,28 @@ ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
if (lan_set_in_progress == SET_COMPLETE)
{
- auto systemObject = ipmi::getDbusObject(
- bus,
- ipmi::network::SYSTEMCONFIG_INTERFACE,
- ipmi::network::ROOT);
-
- auto systemProperties = ipmi::getAllDbusProperties(
- bus,
- systemObject.second,
- systemObject.first,
- ipmi::network::SYSTEMCONFIG_INTERFACE);
-
- gateway = systemProperties["DefaultGateway"].get<
- std::string>();
+ try
+ {
+ auto systemObject = ipmi::getDbusObject(
+ bus,
+ ipmi::network::SYSTEMCONFIG_INTERFACE,
+ ipmi::network::ROOT);
+
+ auto systemProperties = ipmi::getAllDbusProperties(
+ bus,
+ systemObject.second,
+ systemObject.first,
+ ipmi::network::SYSTEMCONFIG_INTERFACE);
+
+ gateway = systemProperties["DefaultGateway"].get<
+ std::string>();
+ }
+ // ignore the exception, as it is a valid condtion that
+ // system is not confiured with any ip.
+ catch (InternalFailure& e)
+ {
+ // nothing to do
+ }
}
else if (lan_set_in_progress == SET_IN_PROGRESS)
@@ -142,7 +250,6 @@ ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
inet_pton(AF_INET, gateway.c_str(),
reinterpret_cast<void*>(data));
-
}
break;
@@ -183,23 +290,33 @@ ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
case LAN_PARM_VLAN:
{
+ uint16_t vlanID {};
if (lan_set_in_progress == SET_COMPLETE)
{
- auto ipObjectInfo = ipmi::getDbusObject(
- bus,
- ipmi::network::IP_INTERFACE,
- ipmi::network::ROOT,
- ipmi::network::IP_TYPE);
-
- auto vlanID = static_cast<uint16_t>(
- ipmi::network::getVLAN(ipObjectInfo.first));
-
- vlanID = htole16(vlanID);
-
- if (vlanID)
+ try
+ {
+ auto ipObjectInfo = ipmi::getDbusObject(
+ bus,
+ ipmi::network::IP_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::IP_TYPE);
+
+ vlanID = static_cast<uint16_t>(
+ ipmi::network::getVLAN(ipObjectInfo.first));
+
+ vlanID = htole16(vlanID);
+
+ if (vlanID)
+ {
+ //Enable the 16th bit
+ vlanID |= htole16(ipmi::network::VLAN_ENABLE_MASK);
+ }
+ }
+ // ignore the exception, as it is a valid condtion that
+ // system is not confiured with any ip.
+ catch (InternalFailure& e)
{
- //Enable the 16th bit
- vlanID |= htole16(ipmi::network::VLAN_ENABLE_MASK);
+ // nothing to do
}
memcpy(data, &vlanID, ipmi::network::VLAN_SIZE_BYTE);
@@ -273,6 +390,14 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
}
break;
+ case LAN_PARM_IPSRC:
+ {
+ uint8_t ipsrc{};
+ memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE);
+ channelConfig.ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc);
+ }
+ break;
+
case LAN_PARM_MAC:
{
char mac[SIZE_MAC];
@@ -419,7 +544,7 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
(reqptr->parameter == LAN_PARM_GATEWAY) ||
(reqptr->parameter == LAN_PARM_MAC))
{
- uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1];
+ uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1] = {};
*data_len = sizeof(current_revision);
memcpy(buf, &current_revision, *data_len);
@@ -443,7 +568,7 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
}
else if (reqptr->parameter == LAN_PARM_VLAN)
{
- uint8_t buf[ipmi::network::VLAN_SIZE_BYTE + 1];
+ uint8_t buf[ipmi::network::VLAN_SIZE_BYTE + 1] = {};
*data_len = sizeof(current_revision);
memcpy(buf, &current_revision, *data_len);
@@ -453,6 +578,17 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
memcpy(response, &buf, *data_len);
}
}
+ else if (reqptr->parameter == LAN_PARM_IPSRC)
+ {
+ uint8_t buff[ipmi::network::IPSRC_SIZE_BYTE + 1] = {};
+ *data_len = sizeof(current_revision);
+ memcpy(buff, &current_revision, *data_len);
+ if (getNetworkData(reqptr->parameter, &buff[1]) == IPMI_CC_OK)
+ {
+ *data_len = sizeof(buff);
+ memcpy(response, &buff, *data_len);
+ }
+ }
else
{
log<level::ERR>("Unsupported parameter",
diff --git a/transporthandler.hpp b/transporthandler.hpp
index 24ee8be..4894190 100644
--- a/transporthandler.hpp
+++ b/transporthandler.hpp
@@ -21,6 +21,7 @@ static const int LAN_PARM_INPROGRESS = 0;
static const int LAN_PARM_AUTHSUPPORT = 1;
static const int LAN_PARM_AUTHENABLES = 2;
static const int LAN_PARM_IP = 3;
+static const int LAN_PARM_IPSRC = 4;
static const int LAN_PARM_MAC = 5;
static const int LAN_PARM_SUBNET = 6;
static const int LAN_PARM_GATEWAY = 12;
@@ -29,6 +30,7 @@ static const int LAN_PARM_VLAN = 20;
struct ChannelConfig_t
{
std::string ipaddr;
+ ipmi::network::IPOrigin ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
std::string netmask;
std::string gateway;
std::string macAddress;
@@ -44,5 +46,6 @@ struct ChannelConfig_t
gateway.clear();
macAddress.clear();
vlanID = ipmi::network::VLAN_ID_MASK;
+ ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
}
};
diff --git a/types.hpp b/types.hpp
index 5b943f4..9c2237f 100644
--- a/types.hpp
+++ b/types.hpp
@@ -26,6 +26,8 @@ using PropertyMap = std::map<DbusProperty, Value>;
using ObjectTree = std::map<DbusObjectPath,
std::map<DbusService, std::vector<DbusInterface>>>;
+using InterfaceList = std::vector<std::string>;
+
namespace sensor
{
@@ -110,10 +112,19 @@ constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
constexpr auto MAC_ADDRESS_SIZE_BYTE = 6;
constexpr auto VLAN_SIZE_BYTE = 2;
+constexpr auto IPSRC_SIZE_BYTE = 1;
constexpr auto BITS_32 = 32;
constexpr auto MASK_32_BIT = 0xFFFFFFFF;
constexpr auto VLAN_ID_MASK = 0x00000FFF;
constexpr auto VLAN_ENABLE_MASK = 0x8000;
+enum class IPOrigin: uint8_t
+{
+ UNSPECIFIED = 0,
+ STATIC = 1,
+ DHCP = 2,
+};
+
+
}//namespace network
}//namespace ipmi
diff --git a/utils.cpp b/utils.cpp
index 2e6c5e7..d81bf76 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -276,6 +276,51 @@ void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
}
}
+ObjectTree getAllAncestors(sdbusplus::bus::bus& bus,
+ const std::string& path,
+ InterfaceList&& interfaces)
+{
+ auto convertToString = [](InterfaceList& interfaces) -> std::string
+ {
+ std::string intfStr;
+ for (const auto& intf : interfaces)
+ {
+ intfStr += "," + intf;
+ }
+ return intfStr;
+ };
+
+ auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME,
+ MAPPER_OBJ,
+ MAPPER_INTF,
+ "GetAncestors");
+ mapperCall.append(path, interfaces);
+
+ auto mapperReply = bus.call(mapperCall);
+ if (mapperReply.is_method_error())
+ {
+ log<level::ERR>("Error in mapper call",
+ entry("PATH=%s", path.c_str()),
+ entry("INTERFACES=%s",
+ convertToString(interfaces).c_str()));
+
+ elog<InternalFailure>();
+ }
+
+ ObjectTree objectTree;
+ mapperReply.read(objectTree);
+
+ if (objectTree.empty())
+ {
+ log<level::ERR>("No Object has impelmented the interface",
+ entry("PATH=%s", path.c_str()),
+ entry("INTERFACES=%s",
+ convertToString(interfaces).c_str()));
+ elog<InternalFailure>();
+ }
+
+ return objectTree;
+}
namespace method_no_args
{
diff --git a/utils.hpp b/utils.hpp
index a172e22..b50fde7 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -113,6 +113,17 @@ void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
const std::string& interface,
const std::string& match = {});
+/** @brief Gets the ancestor objects of the given object
+ which implements the given interface.
+ * @param[in] bus - Dbus bus object.
+ * @param[in] path - Child Dbus object path.
+ * @param[in] interfaces - Dbus interface list.
+ * @return map of object path and service info.
+ */
+ObjectTree getAllAncestors(sdbusplus::bus::bus& bus,
+ const std::string& path,
+ InterfaceList&& interfaces);
+
namespace method_no_args
{
OpenPOWER on IntegriCloud