ncsi: remove loop for netlink receive
Currently, we call nl_recmsg_default repeatedly, stopping when the
callback indicates by setting its context arg pointer to zero.
However, current callbacks all set the context immediately, so we would
only ever perform one iteration of the loop anyway.
Remove the loop and the context flag, and return NL_STOP on callback
invocation. In order to do this, we have to disable the auto-ACK
behavior, as the ACKs may arrive before the message respnonse, and
those will also cause a STOP
Tested: get info (as an example of kernel-handled NCSI control) and OEM
message (as an example of NIC-handled NCSI messaging) commands are
functional, using the kernel NCSI interface against a development NCSI
NIC implementation, including injection of AEN events between each
command/response operation.
Change-Id: I9e73bf61e095a17d7eaecc01e0883e343cd26744
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
diff --git a/src/ncsi_util.cpp b/src/ncsi_util.cpp
index a8cfbb2..b71451e 100644
--- a/src/ncsi_util.cpp
+++ b/src/ncsi_util.cpp
@@ -78,7 +78,7 @@
using nlMsgPtr = std::unique_ptr<nl_msg, decltype(&::nlmsg_free)>;
using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>;
-CallBack infoCallBack = [](struct nl_msg* msg, void* arg) {
+CallBack infoCallBack = [](struct nl_msg* msg, void*) {
using namespace phosphor::network::ncsi;
auto nlh = nlmsg_hdr(msg);
@@ -100,8 +100,6 @@
{NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_UNSPEC, 0, 0},
};
- *(int*)arg = 0;
-
auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
if (!tb[NCSI_ATTR_PACKAGE_LIST])
{
@@ -225,10 +223,10 @@
}
}
}
- return (int)NL_SKIP;
+ return static_cast<int>(NL_STOP);
};
-CallBack sendCallBack = [](struct nl_msg* msg, void* arg) {
+CallBack sendCallBack = [](struct nl_msg* msg, void*) {
using namespace phosphor::network::ncsi;
auto nlh = nlmsg_hdr(msg);
struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
@@ -238,8 +236,6 @@
{NLA_FLAG, 0, 0}, {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
};
- *(int*)arg = 0;
-
auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
if (ret)
{
@@ -262,14 +258,13 @@
lg2::debug("Response {DATA_LEN} bytes: {DATA}", "DATA_LEN", data_len,
"DATA", str);
- return 0;
+ return static_cast<int>(NL_STOP);
};
int applyCmd(Interface& interface, const Command& cmd,
int package = DEFAULT_VALUE, int channel = DEFAULT_VALUE,
int flags = NONE, CallBack function = nullptr)
{
- int cb_ret = 0;
nlSocketPtr socket(nl_socket_alloc(), &::nl_socket_free);
if (socket == nullptr)
{
@@ -277,6 +272,8 @@
return -ENOMEM;
}
+ nl_socket_disable_auto_ack(socket.get());
+
auto ret = genl_connect(socket.get());
if (ret < 0)
{
@@ -391,11 +388,9 @@
if (function)
{
- cb_ret = 1;
-
// Add a callback function to the socket
nl_socket_modify_cb(socket.get(), NL_CB_VALID, NL_CB_CUSTOM, function,
- &cb_ret);
+ nullptr);
}
ret = nl_send_auto(socket.get(), msg.get());
@@ -405,17 +400,14 @@
return ret;
}
- do
+ ret = nl_recvmsgs_default(socket.get());
+ if (ret < 0)
{
- ret = nl_recvmsgs_default(socket.get());
- if (ret < 0)
- {
- lg2::error("Failed to receive the message , RC : {RC}", "RC", ret);
- break;
- }
- } while (cb_ret);
+ lg2::error("Failed to receive the message , RC : {RC}", "RC", ret);
+ return ret;
+ }
- return ret;
+ return 0;
}
} // namespace internal