From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
nicolas.dichtel@6wind.com, donald.hunter@gmail.com,
jiri@resnulli.us, sdf@google.com,
Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next v3 10/15] tools: ynl: stop using mnl_cb_run2()
Date: Tue, 27 Feb 2024 14:30:27 -0800 [thread overview]
Message-ID: <20240227223032.1835527-11-kuba@kernel.org> (raw)
In-Reply-To: <20240227223032.1835527-1-kuba@kernel.org>
There's only one set of callbacks in YNL, for netlink control
messages, and most of them are trivial. So implement the message
walking directly without depending on mnl_cb_run2().
Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--
v2:
- fold NLMSG_NEXT(nlh, rem) into the for () statement
---
tools/net/ynl/lib/ynl.c | 63 ++++++++++++++++++++++++++++-------------
tools/net/ynl/lib/ynl.h | 1 +
2 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/tools/net/ynl/lib/ynl.c b/tools/net/ynl/lib/ynl.c
index f830990b3f4a..fd658aaff345 100644
--- a/tools/net/ynl/lib/ynl.c
+++ b/tools/net/ynl/lib/ynl.c
@@ -255,10 +255,10 @@ ynl_ext_ack_check(struct ynl_sock *ys, const struct nlmsghdr *nlh,
return MNL_CB_OK;
}
-static int ynl_cb_error(const struct nlmsghdr *nlh, void *data)
+static int
+ynl_cb_error(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
const struct nlmsgerr *err = ynl_nlmsg_data(nlh);
- struct ynl_parse_arg *yarg = data;
unsigned int hlen;
int code;
@@ -275,9 +275,8 @@ static int ynl_cb_error(const struct nlmsghdr *nlh, void *data)
return code ? MNL_CB_ERROR : MNL_CB_STOP;
}
-static int ynl_cb_done(const struct nlmsghdr *nlh, void *data)
+static int ynl_cb_done(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
- struct ynl_parse_arg *yarg = data;
int err;
err = *(int *)NLMSG_DATA(nlh);
@@ -292,18 +291,6 @@ static int ynl_cb_done(const struct nlmsghdr *nlh, void *data)
return MNL_CB_STOP;
}
-static int ynl_cb_noop(const struct nlmsghdr *nlh, void *data)
-{
- return MNL_CB_OK;
-}
-
-static mnl_cb_t ynl_cb_array[NLMSG_MIN_TYPE] = {
- [NLMSG_NOOP] = ynl_cb_noop,
- [NLMSG_ERROR] = ynl_cb_error,
- [NLMSG_DONE] = ynl_cb_done,
- [NLMSG_OVERRUN] = ynl_cb_noop,
-};
-
/* Attribute validation */
int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr)
@@ -475,14 +462,52 @@ static int ynl_cb_null(const struct nlmsghdr *nlh, void *data)
static int ynl_sock_read_msgs(struct ynl_parse_arg *yarg, mnl_cb_t cb)
{
struct ynl_sock *ys = yarg->ys;
- ssize_t len;
+ const struct nlmsghdr *nlh;
+ ssize_t len, rem;
+ int ret;
len = mnl_socket_recvfrom(ys->sock, ys->rx_buf, MNL_SOCKET_BUFFER_SIZE);
if (len < 0)
return len;
- return mnl_cb_run2(ys->rx_buf, len, ys->seq, ys->portid,
- cb, yarg, ynl_cb_array, NLMSG_MIN_TYPE);
+ ret = MNL_CB_STOP;
+ for (rem = len; rem > 0; NLMSG_NEXT(nlh, rem)) {
+ nlh = (struct nlmsghdr *)&ys->rx_buf[len - rem];
+ if (!NLMSG_OK(nlh, rem)) {
+ yerr(yarg->ys, YNL_ERROR_INV_RESP,
+ "Invalid message or trailing data in the response.");
+ return MNL_CB_ERROR;
+ }
+
+ if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
+ /* TODO: handle this better */
+ yerr(yarg->ys, YNL_ERROR_DUMP_INTER,
+ "Dump interrupted / inconsistent, please retry.");
+ return MNL_CB_ERROR;
+ }
+
+ switch (nlh->nlmsg_type) {
+ case 0:
+ yerr(yarg->ys, YNL_ERROR_INV_RESP,
+ "Invalid message type in the response.");
+ return MNL_CB_ERROR;
+ case NLMSG_NOOP:
+ case NLMSG_OVERRUN ... NLMSG_MIN_TYPE - 1:
+ ret = MNL_CB_OK;
+ break;
+ case NLMSG_ERROR:
+ ret = ynl_cb_error(nlh, yarg);
+ break;
+ case NLMSG_DONE:
+ ret = ynl_cb_done(nlh, yarg);
+ break;
+ default:
+ ret = cb(nlh, yarg);
+ break;
+ }
+ }
+
+ return ret;
}
static int ynl_recv_ack(struct ynl_sock *ys, int ret)
diff --git a/tools/net/ynl/lib/ynl.h b/tools/net/ynl/lib/ynl.h
index ce77a6d76ce0..4849c142fce0 100644
--- a/tools/net/ynl/lib/ynl.h
+++ b/tools/net/ynl/lib/ynl.h
@@ -12,6 +12,7 @@ enum ynl_error_code {
YNL_ERROR_NONE = 0,
__YNL_ERRNO_END = 4096,
YNL_ERROR_INTERNAL,
+ YNL_ERROR_DUMP_INTER,
YNL_ERROR_EXPECT_ACK,
YNL_ERROR_EXPECT_MSG,
YNL_ERROR_UNEXPECT_MSG,
--
2.43.2
next prev parent reply other threads:[~2024-02-27 22:30 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-27 22:30 [PATCH net-next v3 00/15] tools: ynl: stop using libmnl Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 01/15] tools: ynl: give up on libmnl for auto-ints Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 02/15] tools: ynl: create local attribute helpers Jakub Kicinski
2024-02-28 8:21 ` Nicolas Dichtel
2024-02-27 22:30 ` [PATCH net-next v3 03/15] tools: ynl: create local for_each helpers Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 04/15] tools: ynl: create local nlmsg access helpers Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 05/15] tools: ynl: create local ARRAY_SIZE() helper Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 06/15] tools: ynl: make yarg the first member of struct ynl_dump_state Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 07/15] tools: ynl-gen: remove unused parse code Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 08/15] tools: ynl: wrap recv() + mnl_cb_run2() into a single helper Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 09/15] tools: ynl: use ynl_sock_read_msgs() for ACK handling Jakub Kicinski
2024-02-27 22:30 ` Jakub Kicinski [this message]
2024-02-27 22:30 ` [PATCH net-next v3 11/15] tools: ynl: switch away from mnl_cb_t Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 12/15] tools: ynl: switch away from MNL_CB_* Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 13/15] tools: ynl: stop using mnl socket helpers Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 14/15] tools: ynl: remove the libmnl dependency Jakub Kicinski
2024-02-27 22:30 ` [PATCH net-next v3 15/15] tools: ynl: use MSG_DONTWAIT for getting notifications Jakub Kicinski
2024-02-28 23:50 ` [PATCH net-next v3 00/15] tools: ynl: stop using libmnl patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240227223032.1835527-11-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=jiri@resnulli.us \
--cc=netdev@vger.kernel.org \
--cc=nicolas.dichtel@6wind.com \
--cc=pabeni@redhat.com \
--cc=sdf@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).