[PATCH] netlink: decode nlctrl generic netlink messages

Leo leo at managarm.org
Wed Jun 5 23:32:38 UTC 2024


Add decoding support for nlctrl-type generic netlink messages.

decode_nlattr_type_ignore() was added as a new nlattr helper, as nlctrl likes
to provide nested nlattrs where the type ID is used for numbering, not to
signify the type of the data, which is provided as nested nlattrs.

The new functionality provided by this patch can best be tested with programs
like `genl`, `genl-ctrl-list`, or anything that uses any other generic netlink
family, for instance `iw`, as ntctrl is used there for mapping family name to
nlmsg_type ID.

This decoder should be extendable to support other generic netlink families in
the future if so desired - the nlmsg_type can be resolved to the protocol name
in decode_netlink_generic.

---
 src/Makefile.am                      |   1 +
 src/defs.h                           |   1 +
 src/netlink.c                        |   3 +-
 src/netlink_generic.c                | 346 +++++++++++++++++++++++++++
 src/nlattr.c                         |  68 ++++++
 src/nlattr.h                         |  13 +
 src/xlat/genl_ctrl_attr.in           |  13 +
 src/xlat/genl_ctrl_attr_mcast_grp.in |   5 +
 src/xlat/genl_ctrl_attr_op.in        |   5 +
 src/xlat/genl_ctrl_attr_op_flags.in  |   7 +
 src/xlat/genl_ctrl_attr_policy.in    |   5 +
 src/xlat/genl_ctrl_cmd.in            |  13 +
 src/xlat/genl_netdev_cmd.in          |  12 +
 src/xlat/genl_nl80211_cmd.in         | 246 +++++++++++++++++++
 src/xlat/genl_thermal_cmd.in         |   7 +
 src/xlat/genl_vfs_dquot_cmd.in       |   2 +
 src/xlat/nl_attr_type.in             |  27 +++
 src/xlat/nl_policy_type_attr.in      |  15 ++
 tests/netlink_generic.c              |  10 +-
 19 files changed, 794 insertions(+), 5 deletions(-)
 create mode 100644 src/netlink_generic.c
 create mode 100644 src/xlat/genl_ctrl_attr.in
 create mode 100644 src/xlat/genl_ctrl_attr_mcast_grp.in
 create mode 100644 src/xlat/genl_ctrl_attr_op.in
 create mode 100644 src/xlat/genl_ctrl_attr_op_flags.in
 create mode 100644 src/xlat/genl_ctrl_attr_policy.in
 create mode 100644 src/xlat/genl_ctrl_cmd.in
 create mode 100644 src/xlat/genl_netdev_cmd.in
 create mode 100644 src/xlat/genl_nl80211_cmd.in
 create mode 100644 src/xlat/genl_thermal_cmd.in
 create mode 100644 src/xlat/genl_vfs_dquot_cmd.in
 create mode 100644 src/xlat/nl_attr_type.in
 create mode 100644 src/xlat/nl_policy_type_attr.in

diff --git a/src/Makefile.am b/src/Makefile.am
index a77994e8c..786561b5b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -225,6 +225,7 @@ libstrace_a_SOURCES =	\
 	netlink.c       \
 	netlink.h	\
 	netlink_crypto.c \
+	netlink_generic.c \
 	netlink_inet_diag.c \
 	netlink_kobject_uevent.c \
 	netlink_kobject_uevent.h \
diff --git a/src/defs.h b/src/defs.h
index a354212d0..8ddce3602 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -1489,6 +1489,7 @@ DECL_NETLINK(netfilter);
 DECL_NETLINK(route);
 DECL_NETLINK(selinux);
 DECL_NETLINK(sock_diag);
+DECL_NETLINK(generic);

 extern void
 decode_netlink_kobject_uevent(struct tcb *, kernel_ulong_t addr,
diff --git a/src/netlink.c b/src/netlink.c
index 4da537336..3b37db92b 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -597,7 +597,8 @@ static const netlink_decoder_t netlink_decoders[] = {
 	[NETLINK_NETFILTER] = decode_netlink_netfilter,
 	[NETLINK_ROUTE] = decode_netlink_route,
 	[NETLINK_SELINUX] = decode_netlink_selinux,
-	[NETLINK_SOCK_DIAG] = decode_netlink_sock_diag
+	[NETLINK_SOCK_DIAG] = decode_netlink_sock_diag,
+	[NETLINK_GENERIC] = decode_netlink_generic
 };

 static void
diff --git a/src/netlink_generic.c b/src/netlink_generic.c
new file mode 100644
index 000000000..b10322be0
--- /dev/null
+++ b/src/netlink_generic.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017-2024 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+#include "macros.h"
+#include "nlattr.h"
+
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+#include <linux/netdev.h>
+#include <linux/nl80211.h>
+#include <linux/quota.h>
+#include <linux/thermal.h>
+
+#include "xlat/genl_ctrl_attr.h"
+#include "xlat/genl_ctrl_attr_mcast_grp.h"
+#include "xlat/genl_ctrl_attr_op.h"
+#include "xlat/genl_ctrl_attr_op_flags.h"
+#include "xlat/genl_ctrl_attr_policy.h"
+#include "xlat/genl_ctrl_cmd.h"
+#include "xlat/genl_netdev_cmd.h"
+#include "xlat/genl_nl80211_cmd.h"
+#include "xlat/genl_thermal_cmd.h"
+#include "xlat/genl_vfs_dquot_cmd.h"
+#include "xlat/nl_attr_type.h"
+#include "xlat/nl_policy_type_attr.h"
+
+struct nlctrl_context {
+	char name[GENL_NAMSIZ];
+};
+
+static void
+update_ctx_str(struct tcb *const tcp,
+	       const kernel_ulong_t addr, const unsigned int len,
+	       char *const str, const size_t sz)
+{
+	memset(str, '\0', sz);
+
+	if (len >= sz)
+		return;
+
+	if (umoven(tcp, addr, len, str) < 0 || strnlen(str, sz) > len) {
+		/*
+		 * If we haven't seen NUL or an error occurred, set str
+		 * to an empty string.
+		 */
+		str[0] = '\0';
+		return;
+	}
+}
+
+struct {
+	const char *family;
+	const struct xlat *table;
+} ctrl_op_family_tables[] = {
+	{ "netdev", genl_netdev_cmd },
+	{ "nl80211", genl_nl80211_cmd },
+	{ "nlctrl", genl_ctrl_cmd },
+	{ "thermal", genl_thermal_cmd },
+	{ "VFS_DQUOT", genl_vfs_dquot_cmd },
+};
+
+static bool
+decode_ctrl_attr_op(struct tcb *const tcp,
+		     const kernel_ulong_t addr,
+		     const unsigned int len,
+		     const void *const opaque_data)
+{
+	const struct xlat *ops = NULL;
+	struct nlctrl_context *ctx = (void *) opaque_data;
+
+	for (size_t i = 0; i < ARRAY_SIZE(ctrl_op_family_tables); ++i) {
+		if (!strncmp(ctrl_op_family_tables[i].family, ARRSZ_PAIR(ctx->name)))
+			ops = ctrl_op_family_tables[i].table;
+	}
+
+	static struct decode_nla_xlat_opts opts = {
+		.dflt = NULL,
+		.size = 4,
+	};
+
+	opts.xlat = ops;
+
+	return decode_nla_xval(tcp, addr, len, &opts);
+}
+
+static bool
+decode_ctrl_attr_op_flags(struct tcb *const tcp,
+		     const kernel_ulong_t addr,
+		     const unsigned int len,
+		     const void *const opaque_data)
+{
+	static const struct decode_nla_xlat_opts opts = {
+		genl_ctrl_attr_op_flags, NULL, .size = 4,
+	};
+
+	return decode_nla_flags(tcp, addr, len, &opts);
+}
+
+static const nla_decoder_t ctrl_attr_op_nla_decoders[] = {
+	[CTRL_ATTR_OP_ID] = decode_ctrl_attr_op,
+	[CTRL_ATTR_OP_FLAGS] = decode_ctrl_attr_op_flags,
+};
+
+static bool
+decode_genl_attr_ops(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr(tcp, addr, len,
+		genl_ctrl_attr_op, "CTRL_ATTR_OP_???",
+		ARRSZ_PAIR(ctrl_attr_op_nla_decoders), opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_ops(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	nla_decoder_t genl_ops_decoder = &decode_genl_attr_ops;
+
+	decode_nlattr_type_ignore(tcp, addr, len, NULL, NULL, genl_ops_decoder, opaque_data);
+
+	return true;
+}
+
+static const nla_decoder_t ctrl_attr_mcast_grp_nla_decoders[] = {
+	[CTRL_ATTR_MCAST_GRP_NAME] = decode_nla_str,
+	[CTRL_ATTR_MCAST_GRP_ID] = decode_nla_u32,
+};
+
+static bool
+decode_genl_mcast_groups(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr(tcp, addr, len,
+		genl_ctrl_attr_mcast_grp, "CTRL_ATTR_MCAST_GRP_???",
+		ARRSZ_PAIR(ctrl_attr_mcast_grp_nla_decoders), opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_mcast_groups(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr_type_ignore(tcp, addr, len, NULL, NULL,
+		decode_genl_mcast_groups, opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_policy_attr_type(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	static const struct decode_nla_xlat_opts opts = {
+		nl_attr_type, "NL_ATTR_TYPE_???", .size = 4,
+	};
+
+	return decode_nla_xval(tcp, addr, len, &opts);
+}
+
+static const nla_decoder_t ctrl_attr_policy_attr_decoders[] = {
+	[NL_POLICY_TYPE_ATTR_MIN_VALUE_S] = decode_nla_s64,
+	[NL_POLICY_TYPE_ATTR_MAX_VALUE_S] = decode_nla_s64,
+	[NL_POLICY_TYPE_ATTR_MIN_VALUE_U] = decode_nla_u64,
+	[NL_POLICY_TYPE_ATTR_MAX_VALUE_U] = decode_nla_u64,
+	[NL_POLICY_TYPE_ATTR_MIN_LENGTH] = decode_nla_u32,
+	[NL_POLICY_TYPE_ATTR_MAX_LENGTH] = decode_nla_u32,
+	[NL_POLICY_TYPE_ATTR_POLICY_IDX] = decode_nla_u32,
+	[NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE] = decode_nla_u32,
+	[NL_POLICY_TYPE_ATTR_TYPE] = decode_ctrl_attr_policy_attr_type,
+};
+
+static bool
+decode_ctrl_attr_policy_attr_properties(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr(tcp, addr, len, nl_policy_type_attr, "NL_POLICY_TYPE_ATTR_???",
+		ARRSZ_PAIR(ctrl_attr_policy_attr_decoders), opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_policy_attr(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr_type_ignore(tcp, addr, len, NULL, NULL,
+		decode_ctrl_attr_policy_attr_properties, opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_policy(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr_type_ignore(tcp, addr, len, nl_policy_type_attr, NULL,
+		decode_ctrl_attr_policy_attr, opaque_data);
+
+	return true;
+}
+
+static const nla_decoder_t ctrl_attr_policy_decoders[] = {
+	[CTRL_ATTR_POLICY_DO] = decode_nla_u32,
+	[CTRL_ATTR_POLICY_DUMP] = decode_nla_u32,
+};
+
+static bool
+decode_ctrl_attr_op_policy_op(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr(tcp, addr, len, genl_ctrl_attr_policy, "CTRL_ATTR_POLICY_???",
+		ARRSZ_PAIR(ctrl_attr_policy_decoders), opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_op_policy(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	decode_nlattr_type_ignore(tcp, addr, len, NULL, NULL,
+		decode_ctrl_attr_op_policy_op, opaque_data);
+
+	return true;
+}
+
+static bool
+decode_ctrl_attr_family_name(struct tcb *const tcp,
+		   const kernel_ulong_t addr,
+		   const unsigned int len,
+		   const void *const opaque_data)
+{
+	struct nlctrl_context *ctx = (void *) opaque_data;
+
+	update_ctx_str(tcp, addr, len, ARRSZ_PAIR(ctx->name));
+	return decode_nla_str(tcp, addr, len, NULL);
+}
+
+static const nla_decoder_t ctrl_attr_nla_decoders[] = {
+	[CTRL_ATTR_FAMILY_NAME] = decode_ctrl_attr_family_name,
+	[CTRL_ATTR_FAMILY_ID] = decode_nla_u16,
+	[CTRL_ATTR_VERSION] = decode_nla_u32,
+	[CTRL_ATTR_HDRSIZE] = decode_nla_u32,
+	[CTRL_ATTR_MAXATTR] = decode_nla_u32,
+	[CTRL_ATTR_OPS] = decode_ctrl_attr_ops,
+	[CTRL_ATTR_MCAST_GROUPS] = decode_ctrl_attr_mcast_groups,
+	[CTRL_ATTR_OP_POLICY] = decode_ctrl_attr_op_policy,
+	[CTRL_ATTR_POLICY] = decode_ctrl_attr_policy,
+	[CTRL_ATTR_OP] = decode_nla_u32,
+};
+
+static void
+decode_nlctrl(struct tcb *const tcp, const struct genlmsghdr *hdr,
+	      const kernel_ulong_t addr, const unsigned int len)
+{
+	struct nlctrl_context context = {0};
+
+	tprint_struct_begin();
+	tprints_field_name("cmd");
+	printxval(genl_ctrl_cmd, hdr->cmd, "CTRL_CMD_???");
+	tprint_struct_next();
+	PRINT_FIELD_U(*hdr, version);
+	if (hdr->reserved) {
+		tprint_struct_next();
+		PRINT_FIELD_U(*hdr, reserved);
+	}
+
+	if (len > sizeof(*hdr)) {
+		tprint_struct_next();
+		decode_nlattr(tcp, addr + sizeof(*hdr), len - sizeof(*hdr),
+			genl_ctrl_attr, "CTRL_ATTR_???",
+			ARRSZ_PAIR(ctrl_attr_nla_decoders), &context);
+	}
+
+	tprint_struct_end();
+}
+
+static void
+decode_unknown_family(struct tcb *const tcp, const struct genlmsghdr *hdr,
+	      const kernel_ulong_t addr, const unsigned int len)
+{
+	tprint_struct_begin();
+	PRINT_FIELD_X(*hdr, cmd);
+	tprint_struct_next();
+	PRINT_FIELD_U(*hdr, version);
+
+	if (len > sizeof(*hdr)) {
+		tprint_array_next();
+		decode_nlattr(tcp, addr + sizeof(*hdr), len - sizeof(*hdr),
+			NULL, NULL, NULL, 0, NULL);
+	}
+
+	tprint_struct_end();
+}
+
+bool
+decode_netlink_generic(struct tcb *const tcp,
+			 const struct nlmsghdr *const nlmsghdr,
+			 const kernel_ulong_t addr,
+			 const unsigned int len)
+{
+	struct genlmsghdr command;
+
+	if (nlmsghdr->nlmsg_type == NLMSG_DONE)
+		return false;
+
+	if (!umove_or_printaddr(tcp, addr, &command)) {
+		const struct xlat *genl_families = genl_families_xlat(tcp);
+		const char *family_name = xlookup(genl_families, nlmsghdr->nlmsg_type);
+
+		if (!strcmp(family_name, "nlctrl"))
+			decode_nlctrl(tcp, &command, addr, len);
+		else
+			decode_unknown_family(tcp, &command, addr, len);
+	}
+
+	return true;
+}
diff --git a/src/nlattr.c b/src/nlattr.c
index c19497631..0c1e0a51a 100644
--- a/src/nlattr.c
+++ b/src/nlattr.c
@@ -166,6 +166,74 @@ decode_nlattr(struct tcb *const tcp,
 	}
 }

+extern void
+decode_nlattr_type_ignore(struct tcb *tcp,
+	      kernel_ulong_t addr,
+	      unsigned int len,
+	      const struct xlat *table,
+	      const char *dflt,
+	      const nla_decoder_t decoder,
+	      const void *opaque_data)
+{
+	struct nlattr nla;
+	bool is_array = false;
+
+	for (unsigned int elt = 0;
+	     fetch_nlattr(tcp, &nla, addr, len, is_array);
+	     ++elt) {
+		/* elt starts with 0, hence elt + 1 */
+		if (sequence_truncation_needed(tcp, elt + 1)) {
+			tprint_more_data_follows();
+			break;
+		}
+
+		const unsigned int nla_len = NLA_ALIGN(nla.nla_len);
+		kernel_ulong_t next_addr = 0;
+		unsigned int next_len = 0;
+
+		if (nla.nla_len >= NLA_HDRLEN) {
+			next_len = (len >= nla_len) ? len - nla_len : 0;
+
+			if (next_len && addr + nla_len > addr)
+				next_addr = addr + nla_len;
+		}
+
+		if (!is_array && next_addr) {
+			tprint_array_begin();
+			is_array = true;
+		}
+
+		if (nla_len > NLA_HDRLEN)
+			tprint_array_begin();
+
+		print_nlattr(&nla, table, dflt);
+
+		if (nla_len > NLA_HDRLEN) {
+			tprint_array_next();
+			if (!decoder
+				|| !decoder(
+					tcp, addr + NLA_HDRLEN,
+					nla_len - NLA_HDRLEN,
+					opaque_data
+				))
+				printstr_ex(tcp, addr + NLA_HDRLEN,
+						nla_len - NLA_HDRLEN, QUOTE_FORCE_HEX);
+			tprint_array_end();
+		}
+
+		if (!next_addr)
+			break;
+
+		tprint_array_next();
+		addr = next_addr;
+		len = next_len;
+	}
+
+	if (is_array) {
+		tprint_array_end();
+	}
+}
+
 bool
 decode_nla_str(struct tcb *const tcp,
 	       const kernel_ulong_t addr,
diff --git a/src/nlattr.h b/src/nlattr.h
index 603b3df00..b806b258e 100644
--- a/src/nlattr.h
+++ b/src/nlattr.h
@@ -50,6 +50,19 @@ decode_nlattr(struct tcb *,
 	      unsigned int size,
 	      const void *opaque_data);

+/**
+ * This behaves like decode_nlattr with zero size and only taking a single
+ * decoder, except that the opaque data is passed through instead of nla_type.
+ */
+extern void
+decode_nlattr_type_ignore(struct tcb *,
+	      kernel_ulong_t addr,
+	      unsigned int len,
+	      const struct xlat *,
+	      const char *dflt,
+	      const nla_decoder_t decoder,
+	      const void *opaque_data);
+
 # define DECL_NLA(name)					\
 extern bool						\
 decode_nla_ ## name(struct tcb *, kernel_ulong_t addr,	\
diff --git a/src/xlat/genl_ctrl_attr.in b/src/xlat/genl_ctrl_attr.in
new file mode 100644
index 000000000..1a88069cf
--- /dev/null
+++ b/src/xlat/genl_ctrl_attr.in
@@ -0,0 +1,13 @@
+#unconditional
+
+CTRL_ATTR_UNSPEC
+CTRL_ATTR_FAMILY_ID
+CTRL_ATTR_FAMILY_NAME
+CTRL_ATTR_VERSION
+CTRL_ATTR_HDRSIZE
+CTRL_ATTR_MAXATTR
+CTRL_ATTR_OPS
+CTRL_ATTR_MCAST_GROUPS
+CTRL_ATTR_POLICY
+CTRL_ATTR_OP_POLICY
+CTRL_ATTR_OP
diff --git a/src/xlat/genl_ctrl_attr_mcast_grp.in b/src/xlat/genl_ctrl_attr_mcast_grp.in
new file mode 100644
index 000000000..7eb4df29b
--- /dev/null
+++ b/src/xlat/genl_ctrl_attr_mcast_grp.in
@@ -0,0 +1,5 @@
+#unconditional
+
+CTRL_ATTR_MCAST_GRP_UNSPEC
+CTRL_ATTR_MCAST_GRP_NAME
+CTRL_ATTR_MCAST_GRP_ID
diff --git a/src/xlat/genl_ctrl_attr_op.in b/src/xlat/genl_ctrl_attr_op.in
new file mode 100644
index 000000000..9ef344246
--- /dev/null
+++ b/src/xlat/genl_ctrl_attr_op.in
@@ -0,0 +1,5 @@
+#unconditional
+
+CTRL_ATTR_OP_UNSPEC
+CTRL_ATTR_OP_ID
+CTRL_ATTR_OP_FLAGS
diff --git a/src/xlat/genl_ctrl_attr_op_flags.in b/src/xlat/genl_ctrl_attr_op_flags.in
new file mode 100644
index 000000000..f17cfbaa2
--- /dev/null
+++ b/src/xlat/genl_ctrl_attr_op_flags.in
@@ -0,0 +1,7 @@
+#unconditional
+
+GENL_ADMIN_PERM		0x0001
+GENL_CMD_CAP_DO		0x0002
+GENL_CMD_CAP_DUMP	0x0004
+GENL_CMD_CAP_HASPOL	0x0008
+GENL_UNS_ADMIN_PERM	0x0010
diff --git a/src/xlat/genl_ctrl_attr_policy.in b/src/xlat/genl_ctrl_attr_policy.in
new file mode 100644
index 000000000..4380416ca
--- /dev/null
+++ b/src/xlat/genl_ctrl_attr_policy.in
@@ -0,0 +1,5 @@
+#unconditional
+
+CTRL_ATTR_POLICY_UNSPEC
+CTRL_ATTR_POLICY_DO
+CTRL_ATTR_POLICY_DUMP
diff --git a/src/xlat/genl_ctrl_cmd.in b/src/xlat/genl_ctrl_cmd.in
new file mode 100644
index 000000000..399225edf
--- /dev/null
+++ b/src/xlat/genl_ctrl_cmd.in
@@ -0,0 +1,13 @@
+#unconditional
+
+CTRL_CMD_UNSPEC
+CTRL_CMD_NEWFAMILY
+CTRL_CMD_DELFAMILY
+CTRL_CMD_GETFAMILY
+CTRL_CMD_NEWOPS
+CTRL_CMD_DELOPS
+CTRL_CMD_GETOPS
+CTRL_CMD_NEWMCAST_GRP
+CTRL_CMD_DELMCAST_GRP
+CTRL_CMD_GETMCAST_GRP
+CTRL_CMD_GETPOLICY
diff --git a/src/xlat/genl_netdev_cmd.in b/src/xlat/genl_netdev_cmd.in
new file mode 100644
index 000000000..cb0d953dd
--- /dev/null
+++ b/src/xlat/genl_netdev_cmd.in
@@ -0,0 +1,12 @@
+NETDEV_CMD_DEV_GET 1
+NETDEV_CMD_DEV_ADD_NTF 2
+NETDEV_CMD_DEV_DEL_NTF 3
+NETDEV_CMD_DEV_CHANGE_NTF 4
+NETDEV_CMD_PAGE_POOL_GET 5
+NETDEV_CMD_PAGE_POOL_ADD_NTF 6
+NETDEV_CMD_PAGE_POOL_DEL_NTF 7
+NETDEV_CMD_PAGE_POOL_CHANGE_NTF 8
+NETDEV_CMD_PAGE_POOL_STATS_GET 9
+NETDEV_CMD_QUEUE_GET 10
+NETDEV_CMD_NAPI_GET 11
+NETDEV_CMD_QSTATS_GET 12
diff --git a/src/xlat/genl_nl80211_cmd.in b/src/xlat/genl_nl80211_cmd.in
new file mode 100644
index 000000000..fb6e8bcdd
--- /dev/null
+++ b/src/xlat/genl_nl80211_cmd.in
@@ -0,0 +1,246 @@
+NL80211_CMD_UNSPEC
+
+NL80211_CMD_GET_WIPHY
+NL80211_CMD_SET_WIPHY
+NL80211_CMD_NEW_WIPHY
+NL80211_CMD_DEL_WIPHY
+
+NL80211_CMD_GET_INTERFACE
+NL80211_CMD_SET_INTERFACE
+NL80211_CMD_NEW_INTERFACE
+NL80211_CMD_DEL_INTERFACE
+
+NL80211_CMD_GET_KEY
+NL80211_CMD_SET_KEY
+NL80211_CMD_NEW_KEY
+NL80211_CMD_DEL_KEY
+
+NL80211_CMD_GET_BEACON
+NL80211_CMD_SET_BEACON
+NL80211_CMD_START_AP
+NL80211_CMD_STOP_AP
+
+NL80211_CMD_GET_STATION
+NL80211_CMD_SET_STATION
+NL80211_CMD_NEW_STATION
+NL80211_CMD_DEL_STATION
+
+NL80211_CMD_GET_MPATH
+NL80211_CMD_SET_MPATH
+NL80211_CMD_NEW_MPATH
+NL80211_CMD_DEL_MPATH
+
+NL80211_CMD_SET_BSS
+
+NL80211_CMD_SET_REG
+NL80211_CMD_REQ_SET_REG
+
+NL80211_CMD_GET_MESH_CONFIG
+NL80211_CMD_SET_MESH_CONFIG
+
+NL80211_CMD_SET_MGMT_EXTRA_IE
+
+NL80211_CMD_GET_REG
+
+NL80211_CMD_GET_SCAN
+NL80211_CMD_TRIGGER_SCAN
+NL80211_CMD_NEW_SCAN_RESULTS
+NL80211_CMD_SCAN_ABORTED
+
+NL80211_CMD_REG_CHANGE
+
+NL80211_CMD_AUTHENTICATE
+NL80211_CMD_ASSOCIATE
+NL80211_CMD_DEAUTHENTICATE
+NL80211_CMD_DISASSOCIATE
+
+NL80211_CMD_MICHAEL_MIC_FAILURE
+
+NL80211_CMD_REG_BEACON_HINT
+
+NL80211_CMD_JOIN_IBSS
+NL80211_CMD_LEAVE_IBSS
+
+NL80211_CMD_TESTMODE
+
+NL80211_CMD_CONNECT
+NL80211_CMD_ROAM
+NL80211_CMD_DISCONNECT
+
+NL80211_CMD_SET_WIPHY_NETNS
+
+NL80211_CMD_GET_SURVEY
+NL80211_CMD_NEW_SURVEY_RESULTS
+
+NL80211_CMD_SET_PMKSA
+NL80211_CMD_DEL_PMKSA
+NL80211_CMD_FLUSH_PMKSA
+
+NL80211_CMD_REMAIN_ON_CHANNEL
+NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL
+
+NL80211_CMD_SET_TX_BITRATE_MASK
+
+NL80211_CMD_REGISTER_FRAME
+NL80211_CMD_FRAME
+NL80211_CMD_FRAME_TX_STATUS
+
+NL80211_CMD_SET_POWER_SAVE
+NL80211_CMD_GET_POWER_SAVE
+
+NL80211_CMD_SET_CQM
+NL80211_CMD_NOTIFY_CQM
+
+NL80211_CMD_SET_CHANNEL
+NL80211_CMD_SET_WDS_PEER
+
+NL80211_CMD_FRAME_WAIT_CANCEL
+
+NL80211_CMD_JOIN_MESH
+NL80211_CMD_LEAVE_MESH
+
+NL80211_CMD_UNPROT_DEAUTHENTICATE
+NL80211_CMD_UNPROT_DISASSOCIATE
+
+NL80211_CMD_NEW_PEER_CANDIDATE
+
+NL80211_CMD_GET_WOWLAN
+NL80211_CMD_SET_WOWLAN
+
+NL80211_CMD_START_SCHED_SCAN
+NL80211_CMD_STOP_SCHED_SCAN
+NL80211_CMD_SCHED_SCAN_RESULTS
+NL80211_CMD_SCHED_SCAN_STOPPED
+
+NL80211_CMD_SET_REKEY_OFFLOAD
+
+NL80211_CMD_PMKSA_CANDIDATE
+
+NL80211_CMD_TDLS_OPER
+NL80211_CMD_TDLS_MGMT
+
+NL80211_CMD_UNEXPECTED_FRAME
+
+NL80211_CMD_PROBE_CLIENT
+
+NL80211_CMD_REGISTER_BEACONS
+
+NL80211_CMD_UNEXPECTED_4ADDR_FRAME
+
+NL80211_CMD_SET_NOACK_MAP
+
+NL80211_CMD_CH_SWITCH_NOTIFY
+
+NL80211_CMD_START_P2P_DEVICE
+NL80211_CMD_STOP_P2P_DEVICE
+
+NL80211_CMD_CONN_FAILED
+
+NL80211_CMD_SET_MCAST_RATE
+
+NL80211_CMD_SET_MAC_ACL
+
+NL80211_CMD_RADAR_DETECT
+
+NL80211_CMD_GET_PROTOCOL_FEATURES
+
+NL80211_CMD_UPDATE_FT_IES
+NL80211_CMD_FT_EVENT
+
+NL80211_CMD_CRIT_PROTOCOL_START
+NL80211_CMD_CRIT_PROTOCOL_STOP
+
+NL80211_CMD_GET_COALESCE
+NL80211_CMD_SET_COALESCE
+
+NL80211_CMD_CHANNEL_SWITCH
+
+NL80211_CMD_VENDOR
+
+NL80211_CMD_SET_QOS_MAP
+
+NL80211_CMD_ADD_TX_TS
+NL80211_CMD_DEL_TX_TS
+
+NL80211_CMD_GET_MPP
+
+NL80211_CMD_JOIN_OCB
+NL80211_CMD_LEAVE_OCB
+
+NL80211_CMD_CH_SWITCH_STARTED_NOTIFY
+
+NL80211_CMD_TDLS_CHANNEL_SWITCH
+NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH
+
+NL80211_CMD_WIPHY_REG_CHANGE
+
+NL80211_CMD_ABORT_SCAN
+
+NL80211_CMD_START_NAN
+NL80211_CMD_STOP_NAN
+NL80211_CMD_ADD_NAN_FUNCTION
+NL80211_CMD_DEL_NAN_FUNCTION
+NL80211_CMD_CHANGE_NAN_CONFIG
+NL80211_CMD_NAN_MATCH
+
+NL80211_CMD_SET_MULTICAST_TO_UNICAST
+
+NL80211_CMD_UPDATE_CONNECT_PARAMS
+
+NL80211_CMD_SET_PMK
+NL80211_CMD_DEL_PMK
+
+NL80211_CMD_PORT_AUTHORIZED
+
+NL80211_CMD_RELOAD_REGDB
+
+NL80211_CMD_EXTERNAL_AUTH
+
+NL80211_CMD_STA_OPMODE_CHANGED
+
+NL80211_CMD_CONTROL_PORT_FRAME
+
+NL80211_CMD_GET_FTM_RESPONDER_STATS
+
+NL80211_CMD_PEER_MEASUREMENT_START
+NL80211_CMD_PEER_MEASUREMENT_RESULT
+NL80211_CMD_PEER_MEASUREMENT_COMPLETE
+
+NL80211_CMD_NOTIFY_RADAR
+
+NL80211_CMD_UPDATE_OWE_INFO
+
+NL80211_CMD_PROBE_MESH_LINK
+
+NL80211_CMD_SET_TID_CONFIG
+
+NL80211_CMD_UNPROT_BEACON
+
+NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS
+
+NL80211_CMD_SET_SAR_SPECS
+
+NL80211_CMD_OBSS_COLOR_COLLISION
+
+NL80211_CMD_COLOR_CHANGE_REQUEST
+
+NL80211_CMD_COLOR_CHANGE_STARTED
+NL80211_CMD_COLOR_CHANGE_ABORTED
+NL80211_CMD_COLOR_CHANGE_COMPLETED
+
+NL80211_CMD_SET_FILS_AAD
+
+NL80211_CMD_ASSOC_COMEBACK
+
+NL80211_CMD_ADD_LINK
+NL80211_CMD_REMOVE_LINK
+
+NL80211_CMD_ADD_LINK_STA
+NL80211_CMD_MODIFY_LINK_STA
+NL80211_CMD_REMOVE_LINK_STA
+
+NL80211_CMD_SET_HW_TIMESTAMP
+
+NL80211_CMD_LINKS_REMOVED
+
+NL80211_CMD_SET_TID_TO_LINK_MAPPING
diff --git a/src/xlat/genl_thermal_cmd.in b/src/xlat/genl_thermal_cmd.in
new file mode 100644
index 000000000..2eeb4a9f8
--- /dev/null
+++ b/src/xlat/genl_thermal_cmd.in
@@ -0,0 +1,7 @@
+THERMAL_GENL_CMD_UNSPEC
+THERMAL_GENL_CMD_TZ_GET_ID
+THERMAL_GENL_CMD_TZ_GET_TRIP
+THERMAL_GENL_CMD_TZ_GET_TEMP
+THERMAL_GENL_CMD_TZ_GET_GOV
+THERMAL_GENL_CMD_TZ_GET_MODE
+THERMAL_GENL_CMD_CDEV_GET
diff --git a/src/xlat/genl_vfs_dquot_cmd.in b/src/xlat/genl_vfs_dquot_cmd.in
new file mode 100644
index 000000000..770f3d716
--- /dev/null
+++ b/src/xlat/genl_vfs_dquot_cmd.in
@@ -0,0 +1,2 @@
+QUOTA_NL_C_UNSPEC
+QUOTA_NL_C_WARNING
diff --git a/src/xlat/nl_attr_type.in b/src/xlat/nl_attr_type.in
new file mode 100644
index 000000000..ffd8e7b69
--- /dev/null
+++ b/src/xlat/nl_attr_type.in
@@ -0,0 +1,27 @@
+#unconditional
+
+NL_ATTR_TYPE_INVALID
+
+NL_ATTR_TYPE_FLAG
+
+NL_ATTR_TYPE_U8
+NL_ATTR_TYPE_U16
+NL_ATTR_TYPE_U32
+NL_ATTR_TYPE_U64
+
+NL_ATTR_TYPE_S8
+NL_ATTR_TYPE_S16
+NL_ATTR_TYPE_S32
+NL_ATTR_TYPE_S64
+
+NL_ATTR_TYPE_BINARY
+NL_ATTR_TYPE_STRING
+NL_ATTR_TYPE_NUL_STRING
+
+NL_ATTR_TYPE_NESTED
+NL_ATTR_TYPE_NESTED_ARRAY
+
+NL_ATTR_TYPE_BITFIELD32
+
+NL_ATTR_TYPE_SINT
+NL_ATTR_TYPE_UINT
diff --git a/src/xlat/nl_policy_type_attr.in b/src/xlat/nl_policy_type_attr.in
new file mode 100644
index 000000000..818468845
--- /dev/null
+++ b/src/xlat/nl_policy_type_attr.in
@@ -0,0 +1,15 @@
+#unconditional
+
+NL_POLICY_TYPE_ATTR_UNSPEC
+NL_POLICY_TYPE_ATTR_TYPE
+NL_POLICY_TYPE_ATTR_MIN_VALUE_S
+NL_POLICY_TYPE_ATTR_MAX_VALUE_S
+NL_POLICY_TYPE_ATTR_MIN_VALUE_U
+NL_POLICY_TYPE_ATTR_MAX_VALUE_U
+NL_POLICY_TYPE_ATTR_MIN_LENGTH
+NL_POLICY_TYPE_ATTR_MAX_LENGTH
+NL_POLICY_TYPE_ATTR_POLICY_IDX
+NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE
+NL_POLICY_TYPE_ATTR_BITFIELD32_MASK
+NL_POLICY_TYPE_ATTR_PAD
+NL_POLICY_TYPE_ATTR_MASK
diff --git a/tests/netlink_generic.c b/tests/netlink_generic.c
index e486206d4..e5c076820 100644
--- a/tests/netlink_generic.c
+++ b/tests/netlink_generic.c
@@ -34,14 +34,15 @@ test_nlmsg_type(const int fd)
 			.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
 		},
 		.gnlh = {
-			.cmd = CTRL_CMD_GETFAMILY
+			.cmd = CTRL_CMD_GETFAMILY,
+			.version = 1
 		}
 	};

 	rc = sendto(fd, &req, sizeof(req), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, [{nlmsg_len=%u, nlmsg_type=nlctrl"
 	       ", nlmsg_flags=NLM_F_REQUEST|0x300, nlmsg_seq=0, nlmsg_pid=0}"
-	       ", \"\\x03\\x00\\x00\\x00\"], %u"
+	       ", {cmd=CTRL_CMD_GETFAMILY, version=1}], %u"
 	       ", MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, req.nlh.nlmsg_len,
 	       (unsigned int) sizeof(req), sprintrc(rc));
@@ -66,7 +67,8 @@ test_sendmsg_nlmsg_type(const int fd)
 			.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
 		},
 		.gnlh = {
-			.cmd = CTRL_CMD_GETFAMILY
+			.cmd = CTRL_CMD_GETFAMILY,
+			.version = 1
 		}
 	};

@@ -82,7 +84,7 @@ test_sendmsg_nlmsg_type(const int fd)
         printf("sendmsg(%d, {msg_name=NULL, msg_namelen=0"
 	       ", msg_iov=[{iov_base=[{nlmsg_len=%u, nlmsg_type=nlctrl"
 	       ", nlmsg_flags=NLM_F_REQUEST|0x300, nlmsg_seq=0, nlmsg_pid=0}"
-	       ", \"\\x03\\x00\\x00\\x00\"], iov_len=%u}], msg_iovlen=1"
+	       ", {cmd=CTRL_CMD_GETFAMILY, version=1}], iov_len=%u}], msg_iovlen=1"
 	       ", msg_controllen=0, msg_flags=0}, MSG_DONTWAIT) = %s\n",
 	       fd, req.nlh.nlmsg_len, (unsigned int) iov[0].iov_len,
 	       sprintrc(rc));
--
2.45.1



More information about the Strace-devel mailing list