From bbe4579661b102fa0a5994c9b6a9ecb98add6954 Mon Sep 17 00:00:00 2001 From: Ratan Gupta Date: Fri, 23 Mar 2018 00:22:55 +0530 Subject: ncsi: Impelment the setChannel/ClearInterface function SetChannel:This function will ask underlying NCSI driver to set the package or package/channel combination as the preferred choice. ClearInterface:This function clears any preferred setting from the specific interface. These functions talks with the NCSI driver through the netlink messages. Change-Id: Icb5ae35f83b5b0d0f9654ff4a0dd568fe10680a7 Signed-off-by: Ratan Gupta --- ncsi_util.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 ncsi_util.cpp (limited to 'ncsi_util.cpp') diff --git a/ncsi_util.cpp b/ncsi_util.cpp new file mode 100644 index 0000000..f05cc0b --- /dev/null +++ b/ncsi_util.cpp @@ -0,0 +1,131 @@ +#include +#include +#include +#include + +#include "ncsi_util.hpp" +#include "xyz/openbmc_project/Common/error.hpp" + +#include +#include + +namespace phosphor +{ +namespace network +{ +namespace ncsi +{ + +using namespace phosphor::logging; +using namespace sdbusplus::xyz::openbmc_project::Common::Error; + +namespace internal +{ + +constexpr auto DEFAULT_VALUE = -1; +constexpr auto NONE = 0; + +using nlMsgPtr = std::unique_ptr; +using nlSocketPtr = std::unique_ptr; + +int applyCmd(int ifindex, int cmd, int package = DEFAULT_VALUE, + int channel = DEFAULT_VALUE, int flags = NONE) +{ + nlSocketPtr socket(nl_socket_alloc(),&::nl_socket_free); + auto ret = genl_connect(socket.get()); + if (ret < 0) + { + log("Failed to open the socket", + entry("RC=%d", ret)); + return ret; + } + + auto driverID = genl_ctrl_resolve(socket.get(), "NCSI"); + if (driverID < 0) + { + log("Failed to resolve", + entry("RC=%d", ret)); + return driverID; + } + + nlMsgPtr msg(nlmsg_alloc(), &::nlmsg_free); + + auto msgHdr = genlmsg_put(msg.get(), 0, 0, driverID, 0, flags, + cmd, 0); + if (!msgHdr) + { + log("Unable to add the netlink headers", + entry("COMMAND=%d", cmd)); + return -1; + } + + if (package != DEFAULT_VALUE) + { + ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_PACKAGE_ID, + package); + if (ret < 0) + { + log("Failed to set the attribute", + entry("RC=%d", ret), + entry("PACKAGE=%x", package)); + return ret; + } + } + + if (channel != DEFAULT_VALUE) + { + ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_CHANNEL_ID, + channel); + if (ret < 0) + { + log("Failed to set the attribute", + entry("RC=%d", ret), + entry("CHANNEL=%x", channel)); + return ret; + } + } + + ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_IFINDEX, ifindex); + if (ret < 0) + { + log("Failed to set the attribute", + entry("RC=%d", ret), + entry("INTERFACE=%x", ifindex)); + return ret; + } + + + ret = nl_send_auto(socket.get(), msg.get()); + if (ret < 0) + { + log("Failed to send the message", + entry("RC=%d", ret)); + return ret; + } + + ret = nl_recvmsgs_default(socket.get()); + if (ret < 0) + { + log("Failed to recieve the message", + entry("RC=%d", ret)); + } + return ret; +} + +}//namespace internal + +int setChannel(int ifindex, int package, int channel) +{ + return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_SET_INTERFACE, + package, channel); +} + +int clearInterface(int ifindex) +{ + return internal::applyCmd(ifindex, + ncsi_nl_commands::NCSI_CMD_CLEAR_INTERFACE); +} + +}//namespace ncsi +}//namespace network +}//namespace phosphor -- cgit v1.2.1