ell.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/3] genl,netlink: Move extended ACK code to netlink-private
@ 2022-06-11  1:45 Andrew Zaborowski
  0 siblings, 0 replies; only message in thread
From: Andrew Zaborowski @ 2022-06-11  1:45 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 6191 bytes --]

Since extended ACK parsing can be also useful for rtnl, move it from
genl.c to netlink.c and declare in netlink-private.h.
---
 ell/genl.c            | 61 ++++---------------------------------------
 ell/netlink-private.h | 15 +++++++++++
 ell/netlink.c         | 56 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 75 insertions(+), 57 deletions(-)

diff --git a/ell/genl.c b/ell/genl.c
index 61b7b3a..c6965db 100644
--- a/ell/genl.c
+++ b/ell/genl.c
@@ -33,9 +33,9 @@
 #include "log.h"
 #include "queue.h"
 #include "io.h"
+#include "private.h"
 #include "netlink-private.h"
 #include "genl.h"
-#include "private.h"
 
 #define MAX_NESTING_LEVEL 4
 #define GENL_DEBUG(fmt, args...)	\
@@ -722,17 +722,6 @@ static bool match_request_hid(const void *a, const void *b)
 	return request->handle_id == id;
 }
 
-#define NLA_OK(nla,len)         ((len) >= (int) sizeof(struct nlattr) && \
-				(nla)->nla_len >= sizeof(struct nlattr) && \
-				(nla)->nla_len <= (len))
-#define NLA_NEXT(nla,attrlen)	((attrlen) -= NLMSG_ALIGN((nla)->nla_len), \
-				(struct nlattr*)(((char*)(nla)) + \
-				NLMSG_ALIGN((nla)->nla_len)))
-
-#define NLA_LENGTH(len)		(NLMSG_ALIGN(sizeof(struct nlattr)) + (len))
-#define NLA_DATA(nla)		((void*)(((char*)(nla)) + NLA_LENGTH(0)))
-#define NLA_PAYLOAD(nla)	((int)((nla)->nla_len) - NLA_LENGTH(0))
-
 static struct l_genl_msg *msg_alloc(uint8_t cmd, uint8_t version, uint32_t size)
 {
 	struct l_genl_msg *msg;
@@ -774,52 +763,13 @@ static bool msg_grow(struct l_genl_msg *msg, uint32_t needed)
 static struct l_genl_msg *msg_create(const struct nlmsghdr *nlmsg)
 {
 	struct l_genl_msg *msg;
+	const char *error_msg = NULL;
 
 	msg = l_new(struct l_genl_msg, 1);
 
-	if (nlmsg->nlmsg_type == NLMSG_ERROR) {
-		struct nlmsgerr *err = NLMSG_DATA(nlmsg);
-		unsigned int offset = 0;
-		struct nlattr *nla;
-		int len;
-
-		msg->error = err->error;
-
-		if (!(nlmsg->nlmsg_flags & NLM_F_ACK_TLVS))
-			goto done;
-
-		/*
-		 * If the message is capped, then err->msg.nlmsg_len contains
-		 * the length of the original message and thus can't be used
-		 * to calculate the offset
-		 */
-		if (!(nlmsg->nlmsg_flags & NLM_F_CAPPED))
-			offset = err->msg.nlmsg_len - sizeof(struct nlmsghdr);
-
-		/*
-		 * Attributes start past struct nlmsgerr.  The offset is 0
-		 * for NLM_F_CAPPED messages.  Otherwise the original message
-		 * is included, and thus the offset takes err->msg.nlmsg_len
-		 * into account
-		 */
-		nla = (void *)(err + 1) + offset;
-
-		/* Calculate bytes taken up by header + nlmsgerr contents */
-		offset += sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr);
-		if (nlmsg->nlmsg_len <= offset)
-			goto done;
-
-		len = nlmsg->nlmsg_len - offset;
-
-		for (; NLA_OK(nla, len); nla = NLA_NEXT(nla, len)) {
-			if ((nla->nla_type & NLA_TYPE_MASK) !=
-					NLMSGERR_ATTR_MSG)
-				continue;
-
-			msg->error_msg = l_strdup(NLA_DATA(nla));
-			goto done;
-		}
-	}
+	if (netlink_parse_ext_ack(nlmsg, &error_msg, NULL) &&
+			error_msg)
+		msg->error_msg = l_strdup(error_msg);
 
 	msg->data = l_memdup(nlmsg, nlmsg->nlmsg_len);
 
@@ -833,7 +783,6 @@ static struct l_genl_msg *msg_create(const struct nlmsghdr *nlmsg)
 		msg->version = genlmsg->version;
 	}
 
-done:
 	return l_genl_msg_ref(msg);
 }
 
diff --git a/ell/netlink-private.h b/ell/netlink-private.h
index fff30af..fab0ab9 100644
--- a/ell/netlink-private.h
+++ b/ell/netlink-private.h
@@ -23,3 +23,18 @@
 #ifndef SOL_NETLINK
 #define SOL_NETLINK 270
 #endif
+
+#define NLA_OK(nla,len)         ((len) >= (int) sizeof(struct nlattr) && \
+				(nla)->nla_len >= sizeof(struct nlattr) && \
+				(nla)->nla_len <= (len))
+#define NLA_NEXT(nla,attrlen)	((attrlen) -= NLMSG_ALIGN((nla)->nla_len), \
+				(struct nlattr*)(((char*)(nla)) + \
+				NLMSG_ALIGN((nla)->nla_len)))
+
+#define NLA_LENGTH(len)		(NLMSG_ALIGN(sizeof(struct nlattr)) + (len))
+#define NLA_DATA(nla)		((void*)(((char*)(nla)) + NLA_LENGTH(0)))
+#define NLA_PAYLOAD(nla)	((int)((nla)->nla_len) - NLA_LENGTH(0))
+
+bool netlink_parse_ext_ack(const struct nlmsghdr *nlmsg,
+				const char **out_error_msg,
+				uint32_t *out_error_offset);
diff --git a/ell/netlink.c b/ell/netlink.c
index 4b6d800..32d021b 100644
--- a/ell/netlink.c
+++ b/ell/netlink.c
@@ -32,9 +32,9 @@
 #include "hashmap.h"
 #include "queue.h"
 #include "io.h"
+#include "private.h"
 #include "netlink-private.h"
 #include "netlink.h"
-#include "private.h"
 
 struct command {
 	unsigned int id;
@@ -611,3 +611,57 @@ LIB_EXPORT bool l_netlink_set_debug(struct l_netlink *netlink,
 
 	return true;
 }
+
+bool netlink_parse_ext_ack(const struct nlmsghdr *nlmsg,
+				const char **out_error_msg,
+				uint32_t *out_error_offset)
+{
+	const struct nlmsgerr *err;
+	unsigned int offset = 0;
+	struct nlattr *nla;
+	int len;
+
+	if (nlmsg->nlmsg_type != NLMSG_ERROR ||
+			!(nlmsg->nlmsg_flags & NLM_F_ACK_TLVS))
+		return false;
+
+	err = NLMSG_DATA(nlmsg);
+
+	/*
+	 * If the message is capped, then err->msg.nlmsg_len contains the
+	 * length of the original message and thus can't be used to
+	 * calculate the offset.
+	 */
+	if (!(nlmsg->nlmsg_flags & NLM_F_CAPPED))
+		offset = err->msg.nlmsg_len - sizeof(struct nlmsghdr);
+
+	/*
+	 * Attributes start past struct nlmsgerr.  The offset is 0 for
+	 * NLM_F_CAPPED messages.  Otherwise the original message is
+	 * included, and thus the offset takes err->msg.nlmsg_len into
+	 * account.
+	 */
+	nla = (void *)(err + 1) + offset;
+
+	/* Calculate bytes taken up by header + nlmsgerr contents */
+	offset += sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr);
+	if (nlmsg->nlmsg_len <= offset)
+		return false;
+
+	len = nlmsg->nlmsg_len - offset;
+
+	for (; NLA_OK(nla, len); nla = NLA_NEXT(nla, len)) {
+		switch (nla->nla_type & NLA_TYPE_MASK) {
+		case NLMSGERR_ATTR_MSG:
+			if (out_error_msg)
+				*out_error_msg = NLA_DATA(nla);
+			break;
+		case NLMSGERR_ATTR_OFFS:
+			if (out_error_offset)
+				*out_error_offset = l_get_u32(NLA_DATA(nla));
+			break;
+		}
+	}
+
+	return true;
+}
-- 
2.34.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-11  1:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-11  1:45 [PATCH 2/3] genl,netlink: Move extended ACK code to netlink-private Andrew Zaborowski

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).