cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

genl_magic_func.h (11809B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef GENL_MAGIC_FUNC_H
      3#define GENL_MAGIC_FUNC_H
      4
      5#include <linux/build_bug.h>
      6#include <linux/genl_magic_struct.h>
      7
      8/*
      9 * Magic: declare tla policy						{{{1
     10 * Magic: declare nested policies
     11 *									{{{2
     12 */
     13#undef GENL_mc_group
     14#define GENL_mc_group(group)
     15
     16#undef GENL_notification
     17#define GENL_notification(op_name, op_num, mcast_group, tla_list)
     18
     19#undef GENL_op
     20#define GENL_op(op_name, op_num, handler, tla_list)
     21
     22#undef GENL_struct
     23#define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
     24	[tag_name] = { .type = NLA_NESTED },
     25
     26static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = {
     27#include GENL_MAGIC_INCLUDE_FILE
     28};
     29
     30#undef GENL_struct
     31#define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
     32static struct nla_policy s_name ## _nl_policy[] __read_mostly =		\
     33{ s_fields };
     34
     35#undef __field
     36#define __field(attr_nr, attr_flag, name, nla_type, _type, __get,	\
     37		 __put, __is_signed)					\
     38	[attr_nr] = { .type = nla_type },
     39
     40#undef __array
     41#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen,	\
     42		__get, __put, __is_signed)				\
     43	[attr_nr] = { .type = nla_type,					\
     44		      .len = maxlen - (nla_type == NLA_NUL_STRING) },
     45
     46#include GENL_MAGIC_INCLUDE_FILE
     47
     48#ifndef __KERNEL__
     49#ifndef pr_info
     50#define pr_info(args...)	fprintf(stderr, args);
     51#endif
     52#endif
     53
     54#ifdef GENL_MAGIC_DEBUG
     55static void dprint_field(const char *dir, int nla_type,
     56		const char *name, void *valp)
     57{
     58	__u64 val = valp ? *(__u32 *)valp : 1;
     59	switch (nla_type) {
     60	case NLA_U8:  val = (__u8)val;
     61	case NLA_U16: val = (__u16)val;
     62	case NLA_U32: val = (__u32)val;
     63		pr_info("%s attr %s: %d 0x%08x\n", dir,
     64			name, (int)val, (unsigned)val);
     65		break;
     66	case NLA_U64:
     67		val = *(__u64*)valp;
     68		pr_info("%s attr %s: %lld 0x%08llx\n", dir,
     69			name, (long long)val, (unsigned long long)val);
     70		break;
     71	case NLA_FLAG:
     72		if (val)
     73			pr_info("%s attr %s: set\n", dir, name);
     74		break;
     75	}
     76}
     77
     78static void dprint_array(const char *dir, int nla_type,
     79		const char *name, const char *val, unsigned len)
     80{
     81	switch (nla_type) {
     82	case NLA_NUL_STRING:
     83		if (len && val[len-1] == '\0')
     84			len--;
     85		pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
     86		break;
     87	default:
     88		/* we can always show 4 byte,
     89		 * thats what nlattr are aligned to. */
     90		pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
     91			dir, name, len, val[0], val[1], val[2], val[3]);
     92	}
     93}
     94
     95#define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b);
     96
     97/* Name is a member field name of the struct s.
     98 * If s is NULL (only parsing, no copy requested in *_from_attrs()),
     99 * nla is supposed to point to the attribute containing the information
    100 * corresponding to that struct member. */
    101#define DPRINT_FIELD(dir, nla_type, name, s, nla)			\
    102	do {								\
    103		if (s)							\
    104			dprint_field(dir, nla_type, #name, &s->name);	\
    105		else if (nla)						\
    106			dprint_field(dir, nla_type, #name,		\
    107				(nla_type == NLA_FLAG) ? NULL		\
    108						: nla_data(nla));	\
    109	} while (0)
    110
    111#define	DPRINT_ARRAY(dir, nla_type, name, s, nla)			\
    112	do {								\
    113		if (s)							\
    114			dprint_array(dir, nla_type, #name,		\
    115					s->name, s->name ## _len);	\
    116		else if (nla)						\
    117			dprint_array(dir, nla_type, #name,		\
    118					nla_data(nla), nla_len(nla));	\
    119	} while (0)
    120#else
    121#define DPRINT_TLA(a, op, b) do {} while (0)
    122#define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0)
    123#define	DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0)
    124#endif
    125
    126/*
    127 * Magic: provide conversion functions					{{{1
    128 * populate struct from attribute table:
    129 *									{{{2
    130 */
    131
    132/* processing of generic netlink messages is serialized.
    133 * use one static buffer for parsing of nested attributes */
    134static struct nlattr *nested_attr_tb[128];
    135
    136#undef GENL_struct
    137#define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
    138/* *_from_attrs functions are static, but potentially unused */		\
    139static int __ ## s_name ## _from_attrs(struct s_name *s,		\
    140		struct genl_info *info, bool exclude_invariants)	\
    141{									\
    142	const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1;		\
    143	struct nlattr *tla = info->attrs[tag_number];			\
    144	struct nlattr **ntb = nested_attr_tb;				\
    145	struct nlattr *nla;						\
    146	int err;							\
    147	BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb));	\
    148	if (!tla)							\
    149		return -ENOMSG;						\
    150	DPRINT_TLA(#s_name, "<=-", #tag_name);				\
    151	err = drbd_nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy);	\
    152	if (err)							\
    153		return err;						\
    154									\
    155	s_fields							\
    156	return 0;							\
    157}					__attribute__((unused))		\
    158static int s_name ## _from_attrs(struct s_name *s,			\
    159						struct genl_info *info)	\
    160{									\
    161	return __ ## s_name ## _from_attrs(s, info, false);		\
    162}					__attribute__((unused))		\
    163static int s_name ## _from_attrs_for_change(struct s_name *s,		\
    164						struct genl_info *info)	\
    165{									\
    166	return __ ## s_name ## _from_attrs(s, info, true);		\
    167}					__attribute__((unused))		\
    168
    169#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...)	\
    170		nla = ntb[attr_nr];						\
    171		if (nla) {						\
    172			if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) {		\
    173				pr_info("<< must not change invariant attr: %s\n", #name);	\
    174				return -EEXIST;				\
    175			}						\
    176			assignment;					\
    177		} else if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) {		\
    178			/* attribute missing from payload, */		\
    179			/* which was expected */			\
    180		} else if ((attr_flag) & DRBD_F_REQUIRED) {		\
    181			pr_info("<< missing attr: %s\n", #name);	\
    182			return -ENOMSG;					\
    183		}
    184
    185#undef __field
    186#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
    187		__is_signed)						\
    188	__assign(attr_nr, attr_flag, name, nla_type, type,		\
    189			if (s)						\
    190				s->name = __get(nla);			\
    191			DPRINT_FIELD("<<", nla_type, name, s, nla))
    192
    193/* validate_nla() already checked nla_len <= maxlen appropriately. */
    194#undef __array
    195#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
    196		__get, __put, __is_signed)				\
    197	__assign(attr_nr, attr_flag, name, nla_type, type,		\
    198			if (s)						\
    199				s->name ## _len =			\
    200					__get(s->name, nla, maxlen);	\
    201			DPRINT_ARRAY("<<", nla_type, name, s, nla))
    202
    203#include GENL_MAGIC_INCLUDE_FILE
    204
    205#undef GENL_struct
    206#define GENL_struct(tag_name, tag_number, s_name, s_fields)
    207
    208/*
    209 * Magic: define op number to op name mapping				{{{1
    210 *									{{{2
    211 */
    212const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
    213{
    214	switch (cmd) {
    215#undef GENL_op
    216#define GENL_op(op_name, op_num, handler, tla_list)		\
    217	case op_num: return #op_name;
    218#include GENL_MAGIC_INCLUDE_FILE
    219	default:
    220		     return "unknown";
    221	}
    222}
    223
    224#ifdef __KERNEL__
    225#include <linux/stringify.h>
    226/*
    227 * Magic: define genl_ops						{{{1
    228 *									{{{2
    229 */
    230
    231#undef GENL_op
    232#define GENL_op(op_name, op_num, handler, tla_list)		\
    233{								\
    234	handler							\
    235	.cmd = op_name,						\
    236},
    237
    238#define ZZZ_genl_ops		CONCAT_(GENL_MAGIC_FAMILY, _genl_ops)
    239static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
    240#include GENL_MAGIC_INCLUDE_FILE
    241};
    242
    243#undef GENL_op
    244#define GENL_op(op_name, op_num, handler, tla_list)
    245
    246/*
    247 * Define the genl_family, multicast groups,				{{{1
    248 * and provide register/unregister functions.
    249 *									{{{2
    250 */
    251#define ZZZ_genl_family		CONCAT_(GENL_MAGIC_FAMILY, _genl_family)
    252static struct genl_family ZZZ_genl_family;
    253/*
    254 * Magic: define multicast groups
    255 * Magic: define multicast group registration helper
    256 */
    257#define ZZZ_genl_mcgrps		CONCAT_(GENL_MAGIC_FAMILY, _genl_mcgrps)
    258static const struct genl_multicast_group ZZZ_genl_mcgrps[] = {
    259#undef GENL_mc_group
    260#define GENL_mc_group(group) { .name = #group, },
    261#include GENL_MAGIC_INCLUDE_FILE
    262};
    263
    264enum CONCAT_(GENL_MAGIC_FAMILY, group_ids) {
    265#undef GENL_mc_group
    266#define GENL_mc_group(group) CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group),
    267#include GENL_MAGIC_INCLUDE_FILE
    268};
    269
    270#undef GENL_mc_group
    271#define GENL_mc_group(group)						\
    272static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)(	\
    273	struct sk_buff *skb, gfp_t flags)				\
    274{									\
    275	unsigned int group_id =						\
    276		CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group);		\
    277	return genlmsg_multicast(&ZZZ_genl_family, skb, 0,		\
    278				 group_id, flags);			\
    279}
    280
    281#include GENL_MAGIC_INCLUDE_FILE
    282
    283#undef GENL_mc_group
    284#define GENL_mc_group(group)
    285
    286static struct genl_family ZZZ_genl_family __ro_after_init = {
    287	.name = __stringify(GENL_MAGIC_FAMILY),
    288	.version = GENL_MAGIC_VERSION,
    289#ifdef GENL_MAGIC_FAMILY_HDRSZ
    290	.hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
    291#endif
    292	.maxattr = ARRAY_SIZE(CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy))-1,
    293	.policy	= CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy),
    294	.ops = ZZZ_genl_ops,
    295	.n_ops = ARRAY_SIZE(ZZZ_genl_ops),
    296	.mcgrps = ZZZ_genl_mcgrps,
    297	.n_mcgrps = ARRAY_SIZE(ZZZ_genl_mcgrps),
    298	.module = THIS_MODULE,
    299};
    300
    301int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
    302{
    303	return genl_register_family(&ZZZ_genl_family);
    304}
    305
    306void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
    307{
    308	genl_unregister_family(&ZZZ_genl_family);
    309}
    310
    311/*
    312 * Magic: provide conversion functions					{{{1
    313 * populate skb from struct.
    314 *									{{{2
    315 */
    316
    317#undef GENL_op
    318#define GENL_op(op_name, op_num, handler, tla_list)
    319
    320#undef GENL_struct
    321#define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
    322static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s,	\
    323		const bool exclude_sensitive)				\
    324{									\
    325	struct nlattr *tla = nla_nest_start(skb, tag_number);		\
    326	if (!tla)							\
    327		goto nla_put_failure;					\
    328	DPRINT_TLA(#s_name, "-=>", #tag_name);				\
    329	s_fields							\
    330	nla_nest_end(skb, tla);						\
    331	return 0;							\
    332									\
    333nla_put_failure:							\
    334	if (tla)							\
    335		nla_nest_cancel(skb, tla);				\
    336        return -EMSGSIZE;						\
    337}									\
    338static inline int s_name ## _to_priv_skb(struct sk_buff *skb,		\
    339		struct s_name *s)					\
    340{									\
    341	return s_name ## _to_skb(skb, s, 0);				\
    342}									\
    343static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb,		\
    344		struct s_name *s)					\
    345{									\
    346	return s_name ## _to_skb(skb, s, 1);				\
    347}
    348
    349
    350#undef __field
    351#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
    352		__is_signed)						\
    353	if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {	\
    354		DPRINT_FIELD(">>", nla_type, name, s, NULL);		\
    355		if (__put(skb, attr_nr, s->name))			\
    356			goto nla_put_failure;				\
    357	}
    358
    359#undef __array
    360#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
    361		__get, __put, __is_signed)				\
    362	if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {	\
    363		DPRINT_ARRAY(">>",nla_type, name, s, NULL);		\
    364		if (__put(skb, attr_nr, min_t(int, maxlen,		\
    365			s->name ## _len + (nla_type == NLA_NUL_STRING)),\
    366						s->name))		\
    367			goto nla_put_failure;				\
    368	}
    369
    370#include GENL_MAGIC_INCLUDE_FILE
    371
    372
    373/* Functions for initializing structs to default values.  */
    374
    375#undef __field
    376#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
    377		__is_signed)
    378#undef __array
    379#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
    380		__get, __put, __is_signed)
    381#undef __u32_field_def
    382#define __u32_field_def(attr_nr, attr_flag, name, default)		\
    383	x->name = default;
    384#undef __s32_field_def
    385#define __s32_field_def(attr_nr, attr_flag, name, default)		\
    386	x->name = default;
    387#undef __flg_field_def
    388#define __flg_field_def(attr_nr, attr_flag, name, default)		\
    389	x->name = default;
    390#undef __str_field_def
    391#define __str_field_def(attr_nr, attr_flag, name, maxlen)		\
    392	memset(x->name, 0, sizeof(x->name));				\
    393	x->name ## _len = 0;
    394#undef GENL_struct
    395#define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
    396static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
    397static void set_ ## s_name ## _defaults(struct s_name *x) {	\
    398s_fields								\
    399}
    400
    401#include GENL_MAGIC_INCLUDE_FILE
    402
    403#endif /* __KERNEL__ */
    404
    405/* }}}1 */
    406#endif /* GENL_MAGIC_FUNC_H */