summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@in.ibm.com>2017-07-27 07:07:48 +0530
committerRatan Gupta <ratagupt@in.ibm.com>2017-08-13 06:46:22 +0530
commitb8e9955db5216a0b170a2fb99125d1f22bb9d1c0 (patch)
tree122efef97394c3af93b4dc4bbc35fdef2a24c129
parent8c31d237f67caa5698fca5aedd449f8c98f0b0c0 (diff)
downloadphosphor-host-ipmid-b8e9955db5216a0b170a2fb99125d1f22bb9d1c0.tar.gz
phosphor-host-ipmid-b8e9955db5216a0b170a2fb99125d1f22bb9d1c0.zip
Move LAN handling commands to the new xyz interfaces
Change-Id: I4631c79c171883e5f0d531cfb5957a09496e4b3a Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
-rw-r--r--apphandler.cpp221
-rw-r--r--transporthandler.cpp524
-rw-r--r--transporthandler.hpp (renamed from transporthandler.h)24
-rw-r--r--types.hpp5
-rw-r--r--utils.cpp169
-rw-r--r--utils.hpp87
6 files changed, 681 insertions, 349 deletions
diff --git a/apphandler.cpp b/apphandler.cpp
index 6759462..7b30edd 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -1,6 +1,9 @@
#include "apphandler.h"
#include "host-ipmid/ipmid-api.h"
#include "ipmid.hpp"
+#include "types.hpp"
+#include "utils.hpp"
+
#include <stdio.h>
#include <string.h>
#include <stdint.h>
@@ -8,7 +11,12 @@
#include <mapper.h>
#include <array>
#include <arpa/inet.h>
-#include "transporthandler.h"
+#include "transporthandler.hpp"
+
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
+
extern sd_bus *bus;
@@ -16,8 +24,13 @@ constexpr auto app_obj = "/org/openbmc/NetworkManager/Interface";
constexpr auto app_ifc = "org.openbmc.NetworkManager";
constexpr auto app_nwinterface = "eth0";
+constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
+
void register_netfn_app_functions() __attribute__((constructor));
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
// Offset in get device id command.
typedef struct
{
@@ -508,114 +521,146 @@ finish:
return rc;
}
-extern struct channel_config_t channel_config;
+extern struct ChannelConfig_t channelConfig;
-ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request, ipmi_response_t response,
- ipmi_data_len_t data_len, ipmi_context_t context)
+ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn,
+ ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+ ipmi_data_len_t data_len,
+ ipmi_context_t context)
{
ipmi_ret_t rc = IPMI_CC_OK;
- sd_bus *bus = ipmid_get_sd_bus_connection();
- sd_bus_message *reply = nullptr;
- sd_bus_error error = SD_BUS_ERROR_NULL;
- int r = 0;
- char *app = nullptr;
- int family = 0;
- unsigned char prefixlen = 0;
- char* ipaddr = nullptr;
- uint32_t mask = 0xFFFFFFFF;
- char* gateway = nullptr;
- char tmp_netmask[INET_ADDRSTRLEN];
+ std::string ipaddress;
+ std::string gateway;
+ uint8_t prefix {};
// Todo: parse the request data if needed.
// Using Set Channel cmd to apply changes of Set Lan Cmd.
+ try
+ {
- r = mapper_get_service(bus, app_obj, &app);
- if (r < 0) {
- fprintf(stderr, "Failed to get %s bus name: %s\n",
- app_obj, strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto finish;
- }
+ sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
- r = sd_bus_call_method(bus, app, app_obj, app_ifc, "GetAddress4", &error,
- &reply, "s", app_nwinterface);
- if (r < 0) {
- fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto finish;
- }
+ log<level::INFO>("Network data from Cache",
+ entry("PREFIX=%s", channelConfig.netmask.c_str()),
+ entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
+ entry("GATEWAY=%s", channelConfig.gateway.c_str()));
- r = sd_bus_message_read(reply, "iyss",
- &family, &prefixlen, &ipaddr, &gateway);
- if (r < 0) {
- fprintf(stderr, "Failed to get a response: %s\n", strerror(-r));
- rc = IPMI_CC_RESPONSE_ERROR;
- goto finish;
- }
+ auto systemObject = ipmi::getDbusObject(bus,
+ ipmi::network::SYSTEMCONFIG_INTERFACE,
+ ipmi::network::ROOT);
- printf("N/W data from Cache: %s:%s:%s\n",
- channel_config.new_ipaddr.c_str(),
- channel_config.new_netmask.c_str(),
- channel_config.new_gateway.c_str());
+ // TODO Currently IPMI supports single interface,need to handle
+ // Multiple interface through
+ // https://github.com/openbmc/openbmc/issues/2138
- if(channel_config.new_ipaddr.empty()) {
- channel_config.new_ipaddr.assign(ipaddr);
- }
+ auto networkInterfaceObject = ipmi::getDbusObject(
+ bus,
+ ipmi::network::ETHERNET_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::INTERFACE);
- if(channel_config.new_netmask.empty()) {
- mask = htonl(mask<<(32-prefixlen));
- uint8_t* p = (uint8_t*)&mask;
- snprintf(tmp_netmask, INET_ADDRSTRLEN, "%d.%d.%d.%d",
- *p, *(p+1), *(p+2), *(p+3));
- channel_config.new_netmask.assign(tmp_netmask);
- }
- if(channel_config.new_gateway.empty()) {
- channel_config.new_gateway.assign(gateway);
+ // check wthether user has given all the data
+ if (!channelConfig.ipaddr.empty() &&
+ !channelConfig.netmask.empty() &&
+ !channelConfig.gateway.empty())
+ {
+ //convert mask into prefix
+ ipaddress = channelConfig.ipaddr;
+ prefix = ipmi::network::toPrefix(AF_INET, channelConfig.netmask);
+ gateway = channelConfig.gateway;
+ }
+ else
+ {
+ // gets the network data from the system as user has
+ // not given all the data then use the data fetched from the
+ // system but it is implementation dependent,IPMI spec doesn't
+ // force it.
+
+ // if system is not having any ip object don't throw error,
+ 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 = channelConfig.ipaddr.empty() ?
+ std::move(properties["Address"].get<std::string>()) :
+ channelConfig.ipaddr;
+
+ prefix = channelConfig.netmask.empty() ?
+ properties["PrefixLength"].get<uint8_t>() :
+ ipmi::network::toPrefix(AF_INET,
+ channelConfig.netmask);
+
+ }
+ catch (InternalFailure& e)
+ {
+ log<level::INFO>("Failed to get IP object which matches",
+ entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
+ entry("MATCH=%s", ipmi::network::IP_TYPE));
+ }
+
+ auto systemProperties = ipmi::getAllDbusProperties(
+ bus,
+ systemObject.second,
+ systemObject.first,
+ ipmi::network::SYSTEMCONFIG_INTERFACE);
+
+ gateway = channelConfig.gateway.empty() ?
+ std::move(systemProperties["DefaultGateway"].get<std::string>()) :
+ channelConfig.gateway;
+
+ }
+
+ // Currently network manager doesn't support purging of all the
+ // ip addresses from the parent interface,
+ // TODO once the support is there, will make the change here.
+ // https://github.com/openbmc/openbmc/issues/2141.
+
+ // TODO Currently IPMI supports single interface,need to handle
+ // Multiple interface through
+ // https://github.com/openbmc/openbmc/issues/2138
+
+ //delete all the ipv4 addresses
+
+ ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
+ ipmi::network::IP_INTERFACE,
+ ipmi::network::IP_TYPE);
+
+ ipmi::network::createIP(bus, networkInterfaceObject.second,
+ networkInterfaceObject.first,
+ ipv4Protocol, ipaddress, prefix);
+
+ ipmi::setDbusProperty(bus, systemObject.second, systemObject.first,
+ ipmi::network::SYSTEMCONFIG_INTERFACE,
+ "DefaultGateway", gateway);
+
}
+ catch (InternalFailure& e)
+ {
+ log<level::ERR>("Failed to set network data",
+ entry("PREFIX=%d", prefix),
+ entry("ADDRESS=%s", ipaddress),
+ entry("GATEWAY=%s", gateway));
- printf("N/W data from HW %s:%d:%s:%s\n",
- family==AF_INET?"IPv4":"IPv6", prefixlen, ipaddr,gateway);
- printf("N/W data from Cache: %s:%s:%s\n",
- channel_config.new_ipaddr.c_str(),
- channel_config.new_netmask.c_str(),
- channel_config.new_gateway.c_str());
-
- r = sd_bus_call_method(bus, // On the System Bus
- app, // Service to contact
- app_obj, // Object path
- app_ifc, // Interface name
- "SetAddress4", // Method to be called
- &error, // object to return error
- &reply, // Response message on success
- "ssss", // input message (Interface,
- // IP Address, Netmask, Gateway)
- app_nwinterface, // eth0
- channel_config.new_ipaddr.c_str(),
- channel_config.new_netmask.c_str(),
- channel_config.new_gateway.c_str());
- if(r < 0) {
- fprintf(stderr, "Failed to set network data %s:%s:%s %s\n",
- channel_config.new_ipaddr.c_str(),
- channel_config.new_netmask.c_str(),
- channel_config.new_gateway.c_str(),
- error.message);
+ commit<InternalFailure>();
rc = IPMI_CC_UNSPECIFIED_ERROR;
}
- channel_config.new_ipaddr.clear();
- channel_config.new_netmask.clear();
- channel_config.new_gateway.clear();
-
-finish:
- sd_bus_error_free(&error);
- reply = sd_bus_message_unref(reply);
- free(app);
-
+ channelConfig.clear();
return rc;
}
diff --git a/transporthandler.cpp b/transporthandler.cpp
index 9cbae11..4de9400 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -6,7 +6,12 @@
#include "host-ipmid/ipmid-api.h"
#include "ipmid.hpp"
-#include "transporthandler.h"
+#include "transporthandler.hpp"
+#include "utils.hpp"
+
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
#define SYSTEMD_NETWORKD_DBUS 1
@@ -23,7 +28,7 @@ const char *nwinterface = "eth0";
const int SIZE_MAC = 18; //xx:xx:xx:xx:xx:xx
-struct channel_config_t channel_config;
+struct ChannelConfig_t channelConfig;
const uint8_t SET_COMPLETE = 0;
const uint8_t SET_IN_PROGRESS = 1;
@@ -33,104 +38,158 @@ const uint8_t SET_IN_PROGRESS_RESERVED = 3; //Reserved
// Status of Set-In-Progress Parameter (# 0)
uint8_t lan_set_in_progress = SET_COMPLETE;
-
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
void register_netfn_transport_functions() __attribute__((constructor));
-// Helper Function to get IP Address/NetMask/Gateway from Network Manager or
+// Helper Function to get IP Address/NetMask/Gateway/MAC Address from Network Manager or
// Cache based on Set-In-Progress State
-ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t * data)
+ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
{
- sd_bus *bus = ipmid_get_sd_bus_connection();
- sd_bus_message *reply = NULL;
- sd_bus_error error = SD_BUS_ERROR_NULL;
- int family;
- unsigned char prefixlen;
- char* ipaddr = NULL;
- unsigned long mask = 0xFFFFFFFF;
- char* gateway = NULL;
- int r = 0;
ipmi_ret_t rc = IPMI_CC_OK;
- char *app = NULL;
-
- r = mapper_get_service(bus, obj, &app);
- if (r < 0) {
- fprintf(stderr, "Failed to get %s bus name: %s\n",
- obj, strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto cleanup;
- }
- r = sd_bus_call_method(bus, app, obj, ifc, "GetAddress4", &error,
- &reply, "s", nwinterface);
- if(r < 0)
- {
- fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto cleanup;
- }
-
- r = sd_bus_message_read(reply, "iyss",
- &family, &prefixlen, &ipaddr, &gateway);
- if(r < 0)
- {
- fprintf(stderr, "Failed to get a response: %s\n", strerror(-rc));
- rc = IPMI_CC_RESPONSE_ERROR;
- goto cleanup;
- }
-
- printf("N/W data from HW %s:%d:%s:%s\n",
- family==AF_INET?"IPv4":"IPv6", prefixlen, ipaddr,gateway);
- printf("N/W data from Cache: %s:%s:%s\n",
- channel_config.new_ipaddr.c_str(),
- channel_config.new_netmask.c_str(),
- channel_config.new_gateway.c_str());
-
- if(lan_param == LAN_PARM_IP)
+ sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+ try
{
- if(lan_set_in_progress == SET_COMPLETE)
- {
- std::string ipaddrstr(ipaddr);
- inet_pton(AF_INET, ipaddrstr.c_str(),(void *)data);
- }
- else if(lan_set_in_progress == SET_IN_PROGRESS)
+ switch (lan_param)
{
- inet_pton(AF_INET, channel_config.new_ipaddr.c_str(), (void *)data);
+ case LAN_PARM_IP:
+ {
+ 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>();
+ }
+ else if (lan_set_in_progress == SET_IN_PROGRESS)
+ {
+ ipaddress = channelConfig.ipaddr;
+ }
+
+ inet_pton(AF_INET, ipaddress.c_str(),
+ reinterpret_cast<void*>(data));
+ }
+ break;
+
+ case LAN_PARM_SUBNET:
+ {
+ 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));
+ 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));
+
+ }
+
+ }
+ break;
+
+ case LAN_PARM_GATEWAY:
+ {
+ std::string gateway;
+
+ 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>();
+
+ }
+ else if (lan_set_in_progress == SET_IN_PROGRESS)
+ {
+ gateway = channelConfig.gateway;
+ }
+
+ inet_pton(AF_INET, gateway.c_str(),
+ reinterpret_cast<void*>(data));
+
+ }
+ break;
+
+ case LAN_PARM_MAC:
+ {
+ std::string macAddress;
+ if (lan_set_in_progress == SET_COMPLETE)
+ {
+ auto macObjectInfo = ipmi::getDbusObject(
+ bus,
+ ipmi::network::MAC_INTERFACE,
+ ipmi::network::ROOT);
+
+ auto variant = ipmi::getDbusProperty(
+ bus,
+ macObjectInfo.second,
+ macObjectInfo.first,
+ ipmi::network::MAC_INTERFACE,
+ "MACAddress");
+
+ macAddress = variant.get<std::string>();
+
+ }
+ else if (lan_set_in_progress == SET_IN_PROGRESS)
+ {
+ macAddress = channelConfig.macAddress;
+ }
+
+ sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
+ (data),
+ (data + 1),
+ (data + 2),
+ (data + 3),
+ (data + 4),
+ (data + 5));
+ }
+ break;
+
+ default:
+ rc = IPMI_CC_PARM_OUT_OF_RANGE;
}
}
- else if(lan_param == LAN_PARM_SUBNET)
- {
- if(lan_set_in_progress == SET_COMPLETE)
- {
- mask = htonl(mask<<(32-prefixlen));
- memcpy(data, &mask, 4);
- }
- else if(lan_set_in_progress == SET_IN_PROGRESS)
- {
- inet_pton(AF_INET, channel_config.new_netmask.c_str(), (void *)data);
- }
- }
- else if(lan_param == LAN_PARM_GATEWAY)
+ catch (InternalFailure& e)
{
- if(lan_set_in_progress == SET_COMPLETE)
- {
- std::string gatewaystr(gateway);
- inet_pton(AF_INET, gatewaystr.c_str(), (void *)data);
- }
- else if(lan_set_in_progress == SET_IN_PROGRESS)
- {
- inet_pton(AF_INET, channel_config.new_gateway.c_str(),(void *)data);
- }
- }
- else
- {
- rc = IPMI_CC_PARM_OUT_OF_RANGE;
+ commit<InternalFailure>();
+ rc = IPMI_CC_UNSPECIFIED_ERROR;
+ return rc;
}
-
-cleanup:
- sd_bus_error_free(&error);
- reply = sd_bus_message_unref(reply);
- free(app);
-
return rc;
}
@@ -145,120 +204,144 @@ ipmi_ret_t ipmi_transport_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
-struct set_lan_t {
+struct set_lan_t
+{
uint8_t channel;
uint8_t parameter;
uint8_t data[8]; // Per IPMI spec, not expecting more than this size
-} __attribute__ ((packed));
-
-ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request, ipmi_response_t response,
- ipmi_data_len_t data_len, ipmi_context_t context)
+} __attribute__((packed));
+
+ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
+ ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+ ipmi_data_len_t data_len,
+ ipmi_context_t context)
{
ipmi_ret_t rc = IPMI_CC_OK;
*data_len = 0;
- sd_bus *bus = ipmid_get_sd_bus_connection();
- sd_bus_message *reply = nullptr;
- sd_bus_error error = SD_BUS_ERROR_NULL;
- int r = 0;
- char *app = nullptr;
-
- char tmp_ipaddr[INET_ADDRSTRLEN];
- char tmp_netmask[INET_ADDRSTRLEN];
- char tmp_gateway[INET_ADDRSTRLEN];
-
- printf("IPMI SET_LAN\n");
-
- set_lan_t *reqptr = (set_lan_t*) request;
-
- if (reqptr->parameter == LAN_PARM_IP) {
- snprintf(tmp_ipaddr, INET_ADDRSTRLEN, "%d.%d.%d.%d",
- reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
- channel_config.new_ipaddr.assign(tmp_ipaddr);
- } else if (reqptr->parameter == LAN_PARM_MAC) {
- char mac[SIZE_MAC];
-
- snprintf(mac, SIZE_MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
- reqptr->data[0],
- reqptr->data[1],
- reqptr->data[2],
- reqptr->data[3],
- reqptr->data[4],
- reqptr->data[5]);
-
- r = mapper_get_service(bus, obj, &app);
- if (r < 0) {
- fprintf(stderr, "Failed to get %s bus name: %s\n",
- obj, strerror(-r));
- goto finish;
+
+ char ipaddr[INET_ADDRSTRLEN];
+ char netmask[INET_ADDRSTRLEN];
+ char gateway[INET_ADDRSTRLEN];
+
+ auto reqptr = reinterpret_cast<const set_lan_t*>(request);
+ sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+ switch (reqptr->parameter)
+ {
+ case LAN_PARM_IP:
+ {
+ snprintf(ipaddr, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
+ reqptr->data[0], reqptr->data[1],
+ reqptr->data[2], reqptr->data[3]);
+
+ channelConfig.ipaddr.assign(ipaddr);
+
}
- r = sd_bus_call_method(bus, app, obj, ifc, "SetHwAddress", &error,
- &reply, "ss", nwinterface, mac);
- if (r < 0) {
- fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
+ break;
+
+ case LAN_PARM_MAC:
+ {
+ char mac[SIZE_MAC];
+
+ snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
+ reqptr->data[0],
+ reqptr->data[1],
+ reqptr->data[2],
+ reqptr->data[3],
+ reqptr->data[4],
+ reqptr->data[5]);
+
+ auto macObjectInfo = ipmi::getDbusObject(
+ bus,
+ ipmi::network::MAC_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::INTERFACE);
+
+ ipmi::setDbusProperty(bus,
+ macObjectInfo.second,
+ macObjectInfo.first,
+ ipmi::network::MAC_INTERFACE,
+ "MACAddress",
+ std::string(mac));
+
+ channelConfig.macAddress = mac;
+
}
- } else if (reqptr->parameter == LAN_PARM_SUBNET)
- {
- snprintf(tmp_netmask, INET_ADDRSTRLEN, "%d.%d.%d.%d",
- reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
- channel_config.new_netmask.assign(tmp_netmask);
- } else if (reqptr->parameter == LAN_PARM_GATEWAY)
- {
- snprintf(tmp_gateway, INET_ADDRSTRLEN, "%d.%d.%d.%d",
- reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
- channel_config.new_gateway.assign(tmp_gateway);
- } else if (reqptr->parameter == LAN_PARM_INPROGRESS)
- {
- if(reqptr->data[0] == SET_COMPLETE) {
- lan_set_in_progress = SET_COMPLETE;
+ break;
+
+ case LAN_PARM_SUBNET:
+ {
+ snprintf(netmask, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
+ reqptr->data[0], reqptr->data[1],
+ reqptr->data[2], reqptr->data[3]);
+ channelConfig.netmask.assign(netmask);
+ }
+ break;
- printf("N/W data from Cache: %s:%s:%s\n",
- channel_config.new_ipaddr.c_str(),
- channel_config.new_netmask.c_str(),
- channel_config.new_gateway.c_str());
- printf("Use Set Channel Access command to apply them\n");
+ case LAN_PARM_GATEWAY:
+ {
+ snprintf(gateway, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
+ reqptr->data[0], reqptr->data[1],
+ reqptr->data[2], reqptr->data[3]);
+ channelConfig.gateway.assign(gateway);
+
+ }
+ break;
- } else if(reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
+ case LAN_PARM_INPROGRESS:
{
- lan_set_in_progress = SET_IN_PROGRESS;
+ if (reqptr->data[0] == SET_COMPLETE)
+ {
+ lan_set_in_progress = SET_COMPLETE;
+
+ log<level::INFO>("Network data from Cache",
+ entry("PREFIX=%s", channelConfig.netmask.c_str()),
+ entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
+ entry("GATEWAY=%s", channelConfig.gateway.c_str()));
+
+ log<level::INFO>("Use Set Channel Access command to apply");
+
+ }
+ else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
+ {
+ lan_set_in_progress = SET_IN_PROGRESS;
+ }
+
+ }
+ break;
+
+ default:
+ {
+ log<level::ERR>("Unsupported parameter",
+ entry("PARAMETER=0x%x", reqptr->parameter));
+ rc = IPMI_CC_PARM_NOT_SUPPORTED;
}
- } else
- {
- fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
- rc = IPMI_CC_PARM_NOT_SUPPORTED;
- }
-finish:
- sd_bus_error_free(&error);
- reply = sd_bus_message_unref(reply);
- free(app);
+ }
return rc;
}
-struct get_lan_t {
+struct get_lan_t
+{
uint8_t rev_channel;
uint8_t parameter;
uint8_t parameter_set;
uint8_t parameter_block;
-} __attribute__ ((packed));
-
-ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request, ipmi_response_t response,
- ipmi_data_len_t data_len, ipmi_context_t context)
+} __attribute__((packed));
+
+ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
+ ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+ ipmi_data_len_t data_len,
+ ipmi_context_t context)
{
ipmi_ret_t rc = IPMI_CC_OK;
*data_len = 0;
- sd_bus *bus = ipmid_get_sd_bus_connection();
- sd_bus_message *reply = NULL;
- sd_bus_error error = SD_BUS_ERROR_NULL;
- int r = 0;
const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
- int i = 0;
- char *app = NULL;
-
- printf("IPMI GET_LAN\n");
get_lan_t *reqptr = (get_lan_t*) request;
@@ -270,9 +353,6 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return IPMI_CC_OK;
}
- // TODO Use dbus interface once available. For now use ip cmd.
- // TODO Add the rest of the parameters, like gateway
-
if (reqptr->parameter == LAN_PARM_INPROGRESS)
{
uint8_t buf[] = {current_revision, lan_set_in_progress};
@@ -291,16 +371,26 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
*data_len = sizeof(buf);
memcpy(response, &buf, *data_len);
}
- else if ((reqptr->parameter == LAN_PARM_IP) || (reqptr->parameter == LAN_PARM_SUBNET) || (reqptr->parameter == LAN_PARM_GATEWAY))
+ else if ((reqptr->parameter == LAN_PARM_IP) ||
+ (reqptr->parameter == LAN_PARM_SUBNET) ||
+ (reqptr->parameter == LAN_PARM_GATEWAY) ||
+ (reqptr->parameter == LAN_PARM_MAC))
{
- uint8_t buf[5];
+ uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1];
*data_len = sizeof(current_revision);
memcpy(buf, &current_revision, *data_len);
- if(getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
+ if (getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
{
- *data_len = sizeof(buf);
+ if (reqptr->parameter == LAN_PARM_MAC)
+ {
+ *data_len = sizeof(buf);
+ }
+ else
+ {
+ *data_len = ipmi::network::IPV4_ADDRESS_SIZE_BYTE + 1;
+ }
memcpy(response, &buf, *data_len);
}
else
@@ -308,75 +398,13 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
rc = IPMI_CC_UNSPECIFIED_ERROR;
}
}
- else if (reqptr->parameter == LAN_PARM_MAC)
- {
- //string to parse: link/ether xx:xx:xx:xx:xx:xx
- uint8_t buf[7];
- char *eaddr1 = NULL;
-
- r = mapper_get_service(bus, obj, &app);
- if (r < 0) {
- fprintf(stderr, "Failed to get %s bus name: %s\n",
- obj, strerror(-r));
- goto cleanup;
- }
- r = sd_bus_call_method(bus, app, obj, ifc, "GetHwAddress", &error,
- &reply, "s", nwinterface);
- if(r < 0)
- {
- fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto cleanup;
- }
-
- r = sd_bus_message_read(reply, "s", &eaddr1);
- if (r < 0)
- {
- fprintf(stderr, "Failed to get a response: %s", strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto cleanup;
- }
- if (eaddr1 == NULL)
- {
- fprintf(stderr, "Failed to get a valid response: %s", strerror(-r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto cleanup;
- }
-
- memcpy((void*)&buf[0], &current_revision, 1);
-
- char *tokptr = NULL;
- char* digit = strtok_r(eaddr1, ":", &tokptr);
- if (digit == NULL)
- {
- fprintf(stderr, "Unexpected MAC format: %s", eaddr1);
- rc = IPMI_CC_RESPONSE_ERROR;
- goto cleanup;
- }
-
- i=0;
- while (digit != NULL)
- {
- int resp_byte = strtoul(digit, NULL, 16);
- memcpy((void*)&buf[i+1], &resp_byte, 1);
- i++;
- digit = strtok_r(NULL, ":", &tokptr);
- }
-
- *data_len = sizeof(buf);
- memcpy(response, &buf, *data_len);
- }
else
{
- fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
+ log<level::ERR>("Unsupported parameter",
+ entry("PARAMETER=0x%x", reqptr->parameter));
rc = IPMI_CC_PARM_NOT_SUPPORTED;
}
-cleanup:
- sd_bus_error_free(&error);
- reply = sd_bus_message_unref(reply);
- free(app);
-
return rc;
}
diff --git a/transporthandler.h b/transporthandler.hpp
index 171a636..f1fd410 100644
--- a/transporthandler.h
+++ b/transporthandler.hpp
@@ -1,5 +1,6 @@
-#ifndef __HOST_IPMI_TRANSPORT_HANDLER_H__
-#define __HOST_IPMI_TRANSPORT_HANDLER_H__
+#pragma once
+
+#include <string>
// IPMI commands for Transport net functions.
enum ipmi_netfn_storage_cmds
@@ -24,10 +25,17 @@ static const int LAN_PARM_MAC = 5;
static const int LAN_PARM_SUBNET = 6;
static const int LAN_PARM_GATEWAY = 12;
-struct channel_config_t {
- std::string new_ipaddr;
- std::string new_netmask;
- std::string new_gateway;
+struct ChannelConfig_t
+{
+ std::string ipaddr;
+ std::string netmask;
+ std::string gateway;
+ std::string macAddress;
+ void clear()
+ {
+ ipaddr.clear();
+ netmask.clear();
+ gateway.clear();
+ macAddress.clear();
+ }
};
-
-#endif
diff --git a/types.hpp b/types.hpp
index b6d27e3..5b39c38 100644
--- a/types.hpp
+++ b/types.hpp
@@ -22,6 +22,7 @@ using Value = sdbusplus::message::variant<bool, uint8_t, int16_t,
int64_t, uint64_t, std::string>;
using PropertyMap = std::map<DbusProperty, Value>;
+
using ObjectTree = std::map<DbusObjectPath,
std::map<DbusService, std::vector<DbusInterface>>>;
@@ -106,5 +107,9 @@ constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
+constexpr auto MAC_ADDRESS_SIZE_BYTE = 6;
+constexpr auto BITS_32 = 32;
+constexpr auto MASK_32_BIT = 0xFFFFFFFF;
+
}//namespace network
}//namespace ipmi
diff --git a/utils.cpp b/utils.cpp
index fa92e48..11dc2d4 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -1,9 +1,12 @@
#include "utils.hpp"
-#include "host-ipmid/ipmid-api.h"
#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include "xyz/openbmc_project/Common/error.hpp"
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <net/if.h>
+
namespace ipmi
{
@@ -203,7 +206,171 @@ std::string getService(sdbusplus::bus::bus& bus,
return mapperResponse.begin()->first;
}
+ipmi::ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
+ const std::string& serviceRoot,
+ const std::string& interface,
+ const std::string& match)
+{
+ std::vector<std::string> interfaces;
+ interfaces.emplace_back(interface);
+
+ auto depth = 0;
+
+ auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME,
+ MAPPER_OBJ,
+ MAPPER_INTF,
+ "GetSubTree");
+
+ mapperCall.append(serviceRoot, depth, interfaces);
+
+ auto mapperReply = bus.call(mapperCall);
+ if (mapperReply.is_method_error())
+ {
+ log<level::ERR>("Error in mapper call",
+ entry("SERVICEROOT=%s",serviceRoot.c_str()),
+ entry("INTERFACE=%s", interface.c_str()));
+
+ elog<InternalFailure>();
+ }
+
+ ObjectTree objectTree;
+ mapperReply.read(objectTree);
+
+ for (auto it = objectTree.begin(); it != objectTree.end();)
+ {
+ if (it->first.find(match) == std::string::npos)
+ {
+ it = objectTree.erase(it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+
+ return objectTree;
+}
+
+void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
+ const std::string& serviceRoot,
+ const std::string& interface,
+ const std::string& match)
+{
+ try
+ {
+ auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
+
+ for (auto& object : objectTree)
+ {
+ method_no_args::callDbusMethod(bus,
+ object.second.begin()->first,
+ object.first,
+ DELETE_INTERFACE, "Delete");
+ }
+ }
+ catch (InternalFailure& e)
+ {
+ log<level::INFO>("Unable to delete the objects having",
+ entry("INTERFACE=%s", interface.c_str()),
+ entry("SERVICE=%s", serviceRoot.c_str()));
+ }
+}
+
+
+namespace method_no_args
+{
+
+void callDbusMethod(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& interface,
+ const std::string& method)
+
+{
+ auto busMethod = bus.new_method_call(
+ service.c_str(),
+ objPath.c_str(),
+ interface.c_str(),
+ method.c_str());
+
+ auto reply = bus.call(busMethod);
+
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Failed to execute method",
+ entry("METHOD=%s", method.c_str()),
+ entry("PATH=%s", objPath.c_str()),
+ entry("INTERFACE=%s", interface.c_str()));
+ elog<InternalFailure>();
+ }
+}
+
+}// namespace method_no_args
+
+namespace network
+{
+
+void createIP(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& protocolType,
+ const std::string& ipaddress,
+ uint8_t prefix)
+{
+ std::string gateway = "";
+
+ auto busMethod = bus.new_method_call(
+ service.c_str(),
+ objPath.c_str(),
+ IP_CREATE_INTERFACE,
+ "IP");
+
+ busMethod.append(protocolType, ipaddress, prefix, gateway);
+
+ auto reply = bus.call(busMethod);
+
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Failed to excute method",
+ entry("METHOD=%s", "IP"),
+ entry("PATH=%s", objPath.c_str()));
+ elog<InternalFailure>();
+ }
+
+}
+
+uint8_t toPrefix(int addressFamily, const std::string& subnetMask)
+{
+ if (addressFamily == AF_INET6)
+ {
+ return 0;
+ }
+
+ uint32_t buff {};
+
+ auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
+ if (rc <= 0)
+ {
+ log<level::ERR>("inet_pton failed:",
+ entry("SUBNETMASK=%s", subnetMask));
+ return 0;
+ }
+
+ buff = be32toh(buff);
+ // total no of bits - total no of leading zero == total no of ones
+ if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) == __builtin_popcount(buff))
+ {
+ return __builtin_popcount(buff);
+ }
+ else
+ {
+ log<level::ERR>("Invalid Mask",
+ entry("SUBNETMASK=%s", subnetMask));
+ return 0;
+ }
+}
+} // namespace network
} // namespace ipmi
diff --git a/utils.hpp b/utils.hpp
index 0c7ae76..cb64a25 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -12,16 +12,14 @@ constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";
constexpr auto ROOT = "/";
constexpr auto HOST_MATCH = "host0";
-constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
-constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
-constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
+constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
+constexpr auto DELETE_INTERFACE = "xyz.openbmc_project.Object.Delete";
constexpr auto METHOD_GET = "Get";
constexpr auto METHOD_GET_ALL = "GetAll";
constexpr auto METHOD_SET = "Set";
-
/**
* @brief Get the DBUS Service name for the input dbus path
*
@@ -90,6 +88,87 @@ void setDbusProperty(sdbusplus::bus::bus& bus,
const std::string& property,
const Value& value);
+/** @brief Gets all the dbus objects from the given service root
+ * which matches the object identifier.
+ * @param[in] bus - DBUS Bus Object.
+ * @param[in] serviceRoot - Service root path.
+ * @param[in] interface - Dbus interface.
+ * @param[in] match - Identifier for a path.
+ * @returns map of object path and service info.
+ */
+ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
+ const std::string& serviceRoot,
+ const std::string& interface,
+ const std::string& match);
+
+/** @brief Deletes all the dbus objects from the given service root
+ which matches the object identifier.
+ * @param[in] bus - DBUS Bus Object.
+ * @param[in] serviceRoot - Service root path.
+ * @param[in] interface - Dbus interface.
+ * @param[in] match - Identifier for object.
+ */
+void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
+ const std::string& serviceRoot,
+ const std::string& interface,
+ const std::string& match = {});
+
+namespace method_no_args
+{
+
+/** @brief Calls the Dbus method which waits for response.
+ * @param[in] bus - DBUS Bus Object.
+ * @param[in] service - Dbus service name.
+ * @param[in] objPath - Dbus object path.
+ * @param[in] interface - Dbus interface.
+ * @param[in] method - Dbus method.
+ */
+void callDbusMethod(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& interface,
+ const std::string& method);
+
+} //namespace method_no_args
+
+namespace network
+{
+
+constexpr auto ROOT = "/xyz/openbmc_project/network";
+constexpr auto NETWORK_SERVICE = "xyz.openbmc_project.Network";
+constexpr auto INTERFACE = "eth0";
+constexpr auto IP_TYPE = "ipv4";
+constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
+constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
+constexpr auto SYSTEMCONFIG_INTERFACE = "xyz.openbmc_project.Network.SystemConfiguration";
+constexpr auto ETHERNET_INTERFACE = "xyz.openbmc_project.Network.EthernetInterface";
+constexpr auto IP_CREATE_INTERFACE = "xyz.openbmc_project.Network.IP.Create";
+
+/* @brief converts the given subnet into prefix notation.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] mask - Subnet Mask.
+ * @returns prefix.
+ */
+uint8_t toPrefix(int addressFamily, const std::string& subnetMask);
+
+
+/** @brief Sets the ip on the system.
+ * @param[in] bus - DBUS Bus Object.
+ * @param[in] service - Dbus service name.
+ * @param[in] objPath - Dbus object path.
+ * @param[in] protocolType - Protocol type
+ * @param[in] ipaddress - IPaddress.
+ * @param[in] prefix - Prefix length.
+ */
+void createIP(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& protocolType,
+ const std::string& ipaddress,
+ uint8_t prefix);
+
+}//namespace network
+
} // namespace ipmi
OpenPOWER on IntegriCloud