diff options
author | Ratan Gupta <ratagupt@in.ibm.com> | 2018-03-23 00:22:55 +0530 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2018-04-04 16:12:22 +0000 |
commit | bbe4579661b102fa0a5994c9b6a9ecb98add6954 (patch) | |
tree | 79067badcce404428106229ea70e3b71b59ddef2 | |
parent | b38401b283d9bc7410b6c6a276cc58ac1a4b33f6 (diff) | |
download | phosphor-networkd-bbe4579661b102fa0a5994c9b6a9ecb98add6954.tar.gz phosphor-networkd-bbe4579661b102fa0a5994c9b6a9ecb98add6954.zip |
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 <ratagupt@in.ibm.com>
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | ncsi_util.cpp | 131 | ||||
-rw-r--r-- | ncsi_util.hpp | 33 |
4 files changed, 180 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 8696d03..768b5a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,15 @@ noinst_HEADERS = \ ncsi_netlink_SOURCES = \ argument.cpp \ - ncsi_netlink_main.cpp + ncsi_netlink_main.cpp \ + ncsi_util.cpp + +ncsi_netlink_LDFLAGS = \ + $(PHOSPHOR_LOGGING_LIBS) \ + -lnl-3 \ + -lnl-genl-3 + +ncsi_netlink_CPPFLAGS = -isystem=/usr/include/libnl3 phosphor_network_manager_SOURCES = \ diff --git a/configure.ac b/configure.ac index e902973..bba116d 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,13 @@ AM_PROG_AR AC_PROG_INSTALL AC_PROG_MAKE_SET +# Download ncsi.h from github if necessary. +AC_CHECK_HEADER(linux/ncsi.h,[HAVE_LINUX_NCSI_H=""],[HAVE_LINUX_NCSI_H="-I linux/ncsi.h"]) +AS_IF([test "$HAVE_LINUX_NCSI_H" != ""], + AC_MSG_WARN([Could not find linux/ncsi.h: Attempting to download locally for building from https://raw.githubusercontent.com/openbmc/linux/dev-4.13/include/uapi/linux/ncsi.h]) + AC_SUBST([BT_BMC_DL],[`mkdir -p linux;wget https://raw.githubusercontent.com/openbmc/linux/dev-4.13/include/uapi/linux/ncsi.h -O linux/ncsi.h`]) +) + # Suppress the --with-libtool-sysroot error LT_INIT 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 <linux/ncsi.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> + +#include "ncsi_util.hpp" +#include "xyz/openbmc_project/Common/error.hpp" + +#include <phosphor-logging/elog-errors.hpp> +#include <phosphor-logging/log.hpp> + +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<nl_msg, decltype(&::nlmsg_free)>; +using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>; + +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<level::ERR>("Failed to open the socket", + entry("RC=%d", ret)); + return ret; + } + + auto driverID = genl_ctrl_resolve(socket.get(), "NCSI"); + if (driverID < 0) + { + log<level::ERR>("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<level::ERR>("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<level::ERR>("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<level::ERR>("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<level::ERR>("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<level::ERR>("Failed to send the message", + entry("RC=%d", ret)); + return ret; + } + + ret = nl_recvmsgs_default(socket.get()); + if (ret < 0) + { + log<level::ERR>("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 diff --git a/ncsi_util.hpp b/ncsi_util.hpp new file mode 100644 index 0000000..c519cb4 --- /dev/null +++ b/ncsi_util.hpp @@ -0,0 +1,33 @@ +namespace phosphor +{ +namespace network +{ +namespace ncsi +{ + +/* @brief This function will ask underlying NCSI driver + * to set a specific package or package/channel + * combination as the preferred choice. + * This function talks with the NCSI driver over + * netlink messages. + * @param[in] ifindex - Interface Index. + * @param[in] package - NCSI Package. + * @param[in] channel - Channel number with in the package. + * @returns 0 on success and negative value for failure. + */ +int setChannel(int ifindex, int package, int channel); + +/* @brief This function will ask underlying NCSI driver + * to clear any preferred setting from the given + * interface. + * This function talks with the NCSI driver over + * netlink messages. + * @param[in] ifindex - Interface Index. + * @returns 0 on success and negative value for failure. + */ +int clearInterface(int ifindex); + +}//namespace ncsi +}//namespace network +}//namespace phosphor + |