]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
lib: Extract from devlink/mnlg a helper, mnlu_socket_recv_run()
authorPetr Machata <me@pmachata.org>
Thu, 12 Nov 2020 22:24:43 +0000 (23:24 +0100)
committerDavid Ahern <dsahern@gmail.com>
Sat, 14 Nov 2020 02:43:15 +0000 (19:43 -0700)
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@pmachata.org>
Signed-off-by: David Ahern <dsahern@gmail.com>
devlink/mnlg.c
include/mnl_utils.h
lib/mnl_utils.c

index 4995b7af06a3953e68dc29924f91cfd4368c3a59..21b10c5a5669d4b14e6f9e0a36a5098a015326dc 100644 (file)
@@ -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 {
index 86ce30f49a94c878e5dff73683e31bb734ccdd1b..fa826ef1f8fe3c36cea8e7752b52ac4a3d67ce6f 100644 (file)
@@ -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__ */
index 61e8060ecbca1563777ab7a7aa92e26423305b5f..46384ff81cf184b439b54f3bfabbb268317b54bd 100644 (file)
@@ -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;
+}