linux/include/linux/genl_magic_func.h

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GENL_MAGIC_FUNC_H
#define GENL_MAGIC_FUNC_H

#include <linux/args.h>
#include <linux/build_bug.h>
#include <linux/genl_magic_struct.h>

/*
 * Magic: declare tla policy						{{{1
 * Magic: declare nested policies
 *									{{{2
 */
#undef GENL_mc_group
#define GENL_mc_group(group)

#undef GENL_notification
#define GENL_notification(op_name, op_num, mcast_group, tla_list)

#undef GENL_op
#define GENL_op(op_name, op_num, handler, tla_list)

#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields)

static struct nla_policy CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy)[] =;

#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields)

#undef __field
#define __field(attr_nr, attr_flag, name, nla_type, _type, __get,	\
		 __put, __is_signed)

#undef __array
#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen,	\
		__get, __put, __is_signed)

#include GENL_MAGIC_INCLUDE_FILE

#ifndef __KERNEL__
#ifndef pr_info
#define pr_info
#endif
#endif

#ifdef GENL_MAGIC_DEBUG
static void dprint_field(const char *dir, int nla_type,
		const char *name, void *valp)
{
	__u64 val = valp ? *(__u32 *)valp : 1;
	switch (nla_type) {
	case NLA_U8:  val = (__u8)val;
	case NLA_U16: val = (__u16)val;
	case NLA_U32: val = (__u32)val;
		pr_info("%s attr %s: %d 0x%08x\n", dir,
			name, (int)val, (unsigned)val);
		break;
	case NLA_U64:
		val = *(__u64*)valp;
		pr_info("%s attr %s: %lld 0x%08llx\n", dir,
			name, (long long)val, (unsigned long long)val);
		break;
	case NLA_FLAG:
		if (val)
			pr_info("%s attr %s: set\n", dir, name);
		break;
	}
}

static void dprint_array(const char *dir, int nla_type,
		const char *name, const char *val, unsigned len)
{
	switch (nla_type) {
	case NLA_NUL_STRING:
		if (len && val[len-1] == '\0')
			len--;
		pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
		break;
	default:
		/* we can always show 4 byte,
		 * thats what nlattr are aligned to. */
		pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
			dir, name, len, val[0], val[1], val[2], val[3]);
	}
}

#define DPRINT_TLA

/* Name is a member field name of the struct s.
 * If s is NULL (only parsing, no copy requested in *_from_attrs()),
 * nla is supposed to point to the attribute containing the information
 * corresponding to that struct member. */
#define DPRINT_FIELD

#define DPRINT_ARRAY
#else
#define DPRINT_TLA(a, op, b)
#define DPRINT_FIELD(dir, nla_type, name, s, nla)
#define DPRINT_ARRAY(dir, nla_type, name, s, nla)
#endif

/*
 * Magic: provide conversion functions					{{{1
 * populate struct from attribute table:
 *									{{{2
 */

/* processing of generic netlink messages is serialized.
 * use one static buffer for parsing of nested attributes */
static struct nlattr *nested_attr_tb[128];

#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields)		\

#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...)

#undef __field
#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
		__is_signed)

/* validate_nla() already checked nla_len <= maxlen appropriately. */
#undef __array
#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
		__get, __put, __is_signed)

#include GENL_MAGIC_INCLUDE_FILE

#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields)

/*
 * Magic: define op number to op name mapping				{{{1
 *									{{{2
 */
static const char *CONCATENATE(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
{}

#ifdef __KERNEL__
#include <linux/stringify.h>
/*
 * Magic: define genl_ops						{{{1
 *									{{{2
 */

#undef GENL_op
#define GENL_op(op_name, op_num, handler, tla_list)

#define ZZZ_genl_ops
static struct genl_ops ZZZ_genl_ops[] __read_mostly =;

#undef GENL_op
#define GENL_op(op_name, op_num, handler, tla_list)

/*
 * Define the genl_family, multicast groups,				{{{1
 * and provide register/unregister functions.
 *									{{{2
 */
#define ZZZ_genl_family
static struct genl_family ZZZ_genl_family;
/*
 * Magic: define multicast groups
 * Magic: define multicast group registration helper
 */
#define ZZZ_genl_mcgrps
static const struct genl_multicast_group ZZZ_genl_mcgrps[] =;

enum CONCATENATE(GENL_MAGIC_FAMILY, group_ids) {};

#undef GENL_mc_group
#define GENL_mc_group(group)

#include GENL_MAGIC_INCLUDE_FILE

#undef GENL_mc_group
#define GENL_mc_group(group)

static struct genl_family ZZZ_genl_family __ro_after_init =;

int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void)
{}

void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void)
{}

/*
 * Magic: provide conversion functions					{{{1
 * populate skb from struct.
 *									{{{2
 */

#undef GENL_op
#define GENL_op(op_name, op_num, handler, tla_list)

#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields)


#undef __field
#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
		__is_signed)

#undef __array
#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
		__get, __put, __is_signed)

#include GENL_MAGIC_INCLUDE_FILE


/* Functions for initializing structs to default values.  */

#undef __field
#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
		__is_signed)
#undef __array
#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
		__get, __put, __is_signed)
#undef __u32_field_def
#define __u32_field_def(attr_nr, attr_flag, name, default)
#undef __s32_field_def
#define __s32_field_def(attr_nr, attr_flag, name, default)
#undef __flg_field_def
#define __flg_field_def(attr_nr, attr_flag, name, default)
#undef __str_field_def
#define __str_field_def(attr_nr, attr_flag, name, maxlen)
#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields)

#include GENL_MAGIC_INCLUDE_FILE

#endif /* __KERNEL__ */

/* }}}1 */
#endif /* GENL_MAGIC_FUNC_H */