summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@in.ibm.com>2018-03-23 00:22:55 +0530
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2018-04-04 16:12:22 +0000
commitbbe4579661b102fa0a5994c9b6a9ecb98add6954 (patch)
tree79067badcce404428106229ea70e3b71b59ddef2
parentb38401b283d9bc7410b6c6a276cc58ac1a4b33f6 (diff)
downloadphosphor-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.am10
-rw-r--r--configure.ac7
-rw-r--r--ncsi_util.cpp131
-rw-r--r--ncsi_util.hpp33
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
+
OpenPOWER on IntegriCloud