summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipmid.cpp3
-rw-r--r--transporthandler.cpp87
-rw-r--r--transporthandler.hpp18
3 files changed, 73 insertions, 35 deletions
diff --git a/ipmid.cpp b/ipmid.cpp
index a05992b..91bbbee 100644
--- a/ipmid.cpp
+++ b/ipmid.cpp
@@ -42,6 +42,9 @@ sdbusPtr sdbusp;
using cmdManagerPtr = std::unique_ptr<phosphor::host::command::Manager>;
cmdManagerPtr cmdManager;
+// Global timer for network changes
+std::unique_ptr<phosphor::ipmi::Timer> networkTimer = nullptr;
+
// Command and handler tuple. Used when clients ask the command to be put
// into host message queue
using CommandHandler = phosphor::host::command::CommandHandler;
diff --git a/transporthandler.cpp b/transporthandler.cpp
index bbc6ae5..8bf0d43 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1,3 +1,4 @@
+#include <chrono>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
@@ -7,6 +8,7 @@
#include "host-ipmid/ipmid-api.h"
#include "ipmid.hpp"
+#include "timer.hpp"
#include "transporthandler.hpp"
#include "utils.hpp"
#include "net.hpp"
@@ -22,16 +24,7 @@
#include <mapper.h>
#endif
-/** @struct SetChannelAccessRequest
- *
- * IPMI payload for Set Channel access command request.
- */
-struct SetChannelAccessRequest
-{
- uint8_t channelNumber; //!< Channel number.
- uint8_t setting; //!< The setting values.
- uint8_t privilegeLevelLimit; //!< The Privilege Level Limit
-} __attribute__((packed));
+extern std::unique_ptr<phosphor::ipmi::Timer> networkTimer;
const int SIZE_MAC = 18; //xx:xx:xx:xx:xx:xx
constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
@@ -40,6 +33,7 @@ std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
namespace fs = std::experimental::filesystem;
void register_netfn_transport_functions() __attribute__((constructor));
@@ -391,6 +385,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
ipmi_ret_t rc = IPMI_CC_OK;
*data_len = 0;
+ using namespace std::chrono_literals;
+
+ // time to wait before applying the network changes.
+ constexpr auto networkTimeout = 10000000us; // 10 sec
+
char ipaddr[INET_ADDRSTRLEN];
char netmask[INET_ADDRSTRLEN];
char gateway[INET_ADDRSTRLEN];
@@ -498,11 +497,19 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
entry("GATEWAY=%s", channelConf->gateway.c_str()),
entry("VLAN=%d", channelConf->vlanID));
- log<level::INFO>("Use Set Channel Access command to apply");
+ if (!networkTimer)
+ {
+ log<level::ERR>("Network timer is not instantiated");
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ // start/restart the timer
+ networkTimer->startTimer(networkTimeout);
}
else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
{
channelConf->lan_set_in_progress = SET_IN_PROGRESS;
+ channelConf->flush = true;
}
}
break;
@@ -632,15 +639,8 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
return rc;
}
-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)
+void applyChanges(int channel)
{
- ipmi_ret_t rc = IPMI_CC_OK;
-
std::string ipaddress;
std::string gateway;
uint8_t prefix {};
@@ -649,25 +649,16 @@ ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn,
ipmi::DbusObjectInfo ipObject;
ipmi::DbusObjectInfo systemObject;
- if (*data_len < sizeof(SetChannelAccessRequest))
- {
- return IPMI_CC_INVALID;
- }
-
- auto requestData = reinterpret_cast<const SetChannelAccessRequest*>
- (request);
- int channel = requestData->channelNumber & CHANNEL_MASK;
-
auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
if (ethdevice.empty())
{
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ log<level::ERR>("Unable to get the interface name",
+ entry("CHANNEL=%d", channel));
+ return;
}
auto ethIp = ethdevice + "/" + ipmi::network::IP_TYPE;
auto channelConf = getChannelConfig(channel);
- // Todo: parse the request data if needed.
- // Using Set Channel cmd to apply changes of Set Lan Cmd.
try
{
sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
@@ -729,9 +720,8 @@ ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn,
entry("INTERFACE=%s",
ipmi::network::ETHERNET_INTERFACE));
commit<InternalFailure>();
- rc = IPMI_CC_UNSPECIFIED_ERROR;
channelConf->clear();
- return rc;
+ return;
}
networkInterfacePath = ancestorMap.begin()->first;
@@ -938,15 +928,42 @@ ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn,
entry("IPSRC=%d", channelConf->ipsrc));
commit<InternalFailure>();
- rc = IPMI_CC_UNSPECIFIED_ERROR;
}
channelConf->clear();
- return rc;
+}
+
+void commitNetworkChanges()
+{
+ for (const auto &channel : channelConfig)
+ {
+ if (channel.second->flush)
+ {
+ applyChanges(channel.first);
+ }
+ }
+}
+
+void createNetworkTimer()
+{
+ if (!networkTimer)
+ {
+ std::function<void()> networkTimerCallback(
+ std::bind(&commitNetworkChanges));
+
+ networkTimer =
+ std::make_unique<phosphor::ipmi::Timer>(
+ ipmid_get_sd_event_connection(),
+ networkTimerCallback);
+ }
+
}
void register_netfn_transport_functions()
{
+ // As this timer is only for transport handler
+ // so creating it here.
+ createNetworkTimer();
// <Wildcard Command>
printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_WILDCARD);
ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_WILDCARD, NULL, ipmi_transport_wildcard,
diff --git a/transporthandler.hpp b/transporthandler.hpp
index 42bf717..f440403 100644
--- a/transporthandler.hpp
+++ b/transporthandler.hpp
@@ -47,6 +47,7 @@ struct ChannelConfig_t
// vlan id is in 12 bits and the 16th bit is for enable mask.
uint32_t vlanID = ipmi::network::VLAN_ID_MASK;
uint8_t lan_set_in_progress = SET_COMPLETE;
+ bool flush = false;
void clear()
{
@@ -57,6 +58,7 @@ struct ChannelConfig_t
vlanID = ipmi::network::VLAN_ID_MASK;
ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
lan_set_in_progress = SET_COMPLETE;
+ flush = false;
}
};
@@ -66,3 +68,19 @@ struct ChannelConfig_t
// @param[in] channel the channel
// @return the ChannelConfig_t pointer.
struct ChannelConfig_t* getChannelConfig(int channel);
+
+/** @brief Iterate over all the channelconfig and if
+ * user has given the data for a channel then
+ * apply the network changes for that channel.
+ */
+void commitNetworkChanges();
+
+/* @brief Apply the network changes which is there in the
+ * network cache for a given channel which gets filled
+ * through setLan command. If some of the network
+ * parameter was not given by the setLan then this function
+ * gets the value of that parameter which is already
+ * configured on the system.
+ * @param[in] channel: channel number.
+ */
+void applyChanges(int channel);
OpenPOWER on IntegriCloud