[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <0b98137c7e1d8006a4c4b7cd1edae6a9cbede7fc.1604059429.git.me@pmachata.org>
Date: Fri, 30 Oct 2020 13:29:53 +0100
From: Petr Machata <me@...chata.org>
To: netdev@...r.kernel.org, dsahern@...il.com,
stephen@...workplumber.org
Cc: john.fastabend@...il.com, jiri@...dia.com, idosch@...dia.com,
Jakub Kicinski <kuba@...nel.org>,
Roman Mashak <mrv@...atatu.com>, Petr Machata <me@...chata.org>
Subject: [PATCH iproute2-next v2 06/11] lib: Extract from devlink/mnlg a helper, mnlu_socket_recv_run()
Receiving a message in libmnl is a somewhat involved operation. Devlink's
mnlg library has an implementation that is going to be handy for other
tools as well. Extract it into a new helper.
Signed-off-by: Petr Machata <me@...chata.org>
---
devlink/mnlg.c | 56 ++---------------------------------------
include/mnl_utils.h | 2 ++
lib/mnl_utils.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+), 54 deletions(-)
diff --git a/devlink/mnlg.c b/devlink/mnlg.c
index 4995b7af06a3..21b10c5a5669 100644
--- a/devlink/mnlg.c
+++ b/devlink/mnlg.c
@@ -28,7 +28,6 @@ struct mnlg_socket {
uint32_t id;
uint8_t version;
unsigned int seq;
- unsigned int portid;
};
static struct nlmsghdr *__mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
@@ -57,61 +56,10 @@ int mnlg_socket_send(struct mnlg_socket *nlg, const struct nlmsghdr *nlh)
return mnl_socket_sendto(nlg->nl, nlh, nlh->nlmsg_len);
}
-static int mnlg_cb_noop(const struct nlmsghdr *nlh, void *data)
-{
- return MNL_CB_OK;
-}
-
-static int mnlg_cb_error(const struct nlmsghdr *nlh, void *data)
-{
- const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
-
- /* Netlink subsystems returns the errno value with different signess */
- if (err->error < 0)
- errno = -err->error;
- else
- errno = err->error;
-
- if (nl_dump_ext_ack(nlh, NULL))
- return MNL_CB_ERROR;
-
- return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
-}
-
-static int mnlg_cb_stop(const struct nlmsghdr *nlh, void *data)
-{
- int len = *(int *)NLMSG_DATA(nlh);
-
- if (len < 0) {
- errno = -len;
- nl_dump_ext_ack_done(nlh, len);
- return MNL_CB_ERROR;
- }
- return MNL_CB_STOP;
-}
-
-static mnl_cb_t mnlg_cb_array[NLMSG_MIN_TYPE] = {
- [NLMSG_NOOP] = mnlg_cb_noop,
- [NLMSG_ERROR] = mnlg_cb_error,
- [NLMSG_DONE] = mnlg_cb_stop,
- [NLMSG_OVERRUN] = mnlg_cb_noop,
-};
-
int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data)
{
- int err;
-
- do {
- err = mnl_socket_recvfrom(nlg->nl, nlg->buf,
- MNL_SOCKET_BUFFER_SIZE);
- if (err <= 0)
- break;
- err = mnl_cb_run2(nlg->buf, err, nlg->seq, nlg->portid,
- data_cb, data, mnlg_cb_array,
- ARRAY_SIZE(mnlg_cb_array));
- } while (err > 0);
-
- return err;
+ return mnlu_socket_recv_run(nlg->nl, nlg->seq, nlg->buf, MNL_SOCKET_BUFFER_SIZE,
+ data_cb, data);
}
struct group_info {
diff --git a/include/mnl_utils.h b/include/mnl_utils.h
index 86ce30f49a94..fa826ef1f8fe 100644
--- a/include/mnl_utils.h
+++ b/include/mnl_utils.h
@@ -5,5 +5,7 @@
struct mnl_socket *mnlu_socket_open(int bus);
struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags,
void *extra_header, size_t extra_header_size);
+int mnlu_socket_recv_run(struct mnl_socket *nl, unsigned int seq, void *buf, size_t buf_size,
+ mnl_cb_t cb, void *data);
#endif /* __MNL_UTILS_H__ */
diff --git a/lib/mnl_utils.c b/lib/mnl_utils.c
index 61e8060ecbca..46384ff81cf1 100644
--- a/lib/mnl_utils.c
+++ b/lib/mnl_utils.c
@@ -3,11 +3,14 @@
* mnl_utils.c Helpers for working with libmnl.
*/
+#include <errno.h>
#include <string.h>
#include <time.h>
#include <libmnl/libmnl.h>
+#include "libnetlink.h"
#include "mnl_utils.h"
+#include "utils.h"
struct mnl_socket *mnlu_socket_open(int bus)
{
@@ -47,3 +50,61 @@ struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags
return nlh;
}
+
+static int mnlu_cb_noop(const struct nlmsghdr *nlh, void *data)
+{
+ return MNL_CB_OK;
+}
+
+static int mnlu_cb_error(const struct nlmsghdr *nlh, void *data)
+{
+ const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
+
+ /* Netlink subsystems returns the errno value with different signess */
+ if (err->error < 0)
+ errno = -err->error;
+ else
+ errno = err->error;
+
+ if (nl_dump_ext_ack(nlh, NULL))
+ return MNL_CB_ERROR;
+
+ return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+}
+
+static int mnlu_cb_stop(const struct nlmsghdr *nlh, void *data)
+{
+ int len = *(int *)NLMSG_DATA(nlh);
+
+ if (len < 0) {
+ errno = -len;
+ nl_dump_ext_ack_done(nlh, len);
+ return MNL_CB_ERROR;
+ }
+ return MNL_CB_STOP;
+}
+
+static mnl_cb_t mnlu_cb_array[NLMSG_MIN_TYPE] = {
+ [NLMSG_NOOP] = mnlu_cb_noop,
+ [NLMSG_ERROR] = mnlu_cb_error,
+ [NLMSG_DONE] = mnlu_cb_stop,
+ [NLMSG_OVERRUN] = mnlu_cb_noop,
+};
+
+int mnlu_socket_recv_run(struct mnl_socket *nl, unsigned int seq, void *buf, size_t buf_size,
+ mnl_cb_t cb, void *data)
+{
+ unsigned int portid = mnl_socket_get_portid(nl);
+ int err;
+
+ do {
+ err = mnl_socket_recvfrom(nl, buf, buf_size);
+ if (err <= 0)
+ break;
+ err = mnl_cb_run2(buf, err, seq, portid,
+ cb, data, mnlu_cb_array,
+ ARRAY_SIZE(mnlu_cb_array));
+ } while (err > 0);
+
+ return err;
+}
--
2.25.1
Powered by blists - more mailing lists