Move LAN handling commands to the new xyz interfaces
Change-Id: I4631c79c171883e5f0d531cfb5957a09496e4b3a
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
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_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 @@
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());
+
+ 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()));
+
+ auto systemObject = ipmi::getDbusObject(bus,
+ ipmi::network::SYSTEMCONFIG_INTERFACE,
+ ipmi::network::ROOT);
+
+ // TODO Currently IPMI supports single interface,need to handle
+ // Multiple interface through
+ // https://github.com/openbmc/openbmc/issues/2138
+
+ auto networkInterfaceObject = ipmi::getDbusObject(
+ bus,
+ ipmi::network::ETHERNET_INTERFACE,
+ ipmi::network::ROOT,
+ ipmi::network::INTERFACE);
+
+
+
+ // 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));
- 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;
- }
-
- 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;
- }
-
- 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(channel_config.new_ipaddr.empty()) {
- channel_config.new_ipaddr.assign(ipaddr);
- }
-
- 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);
- }
-
- 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;
}