1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2ec2c35acSLars Ellenberg #ifndef GENL_MAGIC_STRUCT_H
3ec2c35acSLars Ellenberg #define GENL_MAGIC_STRUCT_H
4ec2c35acSLars Ellenberg 
5ec2c35acSLars Ellenberg #ifndef GENL_MAGIC_FAMILY
6ec2c35acSLars Ellenberg # error "you need to define GENL_MAGIC_FAMILY before inclusion"
7ec2c35acSLars Ellenberg #endif
8ec2c35acSLars Ellenberg 
9ec2c35acSLars Ellenberg #ifndef GENL_MAGIC_VERSION
10ec2c35acSLars Ellenberg # error "you need to define GENL_MAGIC_VERSION before inclusion"
11ec2c35acSLars Ellenberg #endif
12ec2c35acSLars Ellenberg 
13ec2c35acSLars Ellenberg #ifndef GENL_MAGIC_INCLUDE_FILE
14ec2c35acSLars Ellenberg # error "you need to define GENL_MAGIC_INCLUDE_FILE before inclusion"
15ec2c35acSLars Ellenberg #endif
16ec2c35acSLars Ellenberg 
172e106e56SAndy Shevchenko #include <linux/args.h>
18ec2c35acSLars Ellenberg #include <linux/types.h>
19*cd720962SJakub Kicinski #include <net/genetlink.h>
20ec2c35acSLars Ellenberg 
212e106e56SAndy Shevchenko extern int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void);
222e106e56SAndy Shevchenko extern void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void);
23ec2c35acSLars Ellenberg 
24ec2c35acSLars Ellenberg /*
25ec2c35acSLars Ellenberg  * Extension of genl attribute validation policies			{{{2
26ec2c35acSLars Ellenberg  */
27ec2c35acSLars Ellenberg 
285f935920SAndreas Gruenbacher /*
295f935920SAndreas Gruenbacher  * @DRBD_GENLA_F_MANDATORY: By default, netlink ignores attributes it does not
305f935920SAndreas Gruenbacher  * know about.  This flag can be set in nlattr->nla_type to indicate that this
315f935920SAndreas Gruenbacher  * attribute must not be ignored.
32ec2c35acSLars Ellenberg  *
335f935920SAndreas Gruenbacher  * We check and remove this flag in drbd_nla_check_mandatory() before
345f935920SAndreas Gruenbacher  * validating the attribute types and lengths via nla_parse_nested().
35ec2c35acSLars Ellenberg  */
365f935920SAndreas Gruenbacher #define DRBD_GENLA_F_MANDATORY (1 << 14)
37ec2c35acSLars Ellenberg 
385f935920SAndreas Gruenbacher /*
395f935920SAndreas Gruenbacher  * Flags specific to drbd and not visible at the netlink layer, used in
405f935920SAndreas Gruenbacher  * <struct>_from_attrs and <struct>_to_skb:
415f935920SAndreas Gruenbacher  *
425f935920SAndreas Gruenbacher  * @DRBD_F_REQUIRED: Attribute is required; a request without this attribute is
435f935920SAndreas Gruenbacher  * invalid.
445f935920SAndreas Gruenbacher  *
455f935920SAndreas Gruenbacher  * @DRBD_F_SENSITIVE: Attribute includes sensitive information and must not be
465f935920SAndreas Gruenbacher  * included in unpriviledged get requests or broadcasts.
475f935920SAndreas Gruenbacher  *
485f935920SAndreas Gruenbacher  * @DRBD_F_INVARIANT: Attribute is set when an object is initially created, but
495f935920SAndreas Gruenbacher  * cannot subsequently be changed.
50f399002eSLars Ellenberg  */
515f935920SAndreas Gruenbacher #define DRBD_F_REQUIRED (1 << 0)
525f935920SAndreas Gruenbacher #define DRBD_F_SENSITIVE (1 << 1)
535f935920SAndreas Gruenbacher #define DRBD_F_INVARIANT (1 << 2)
54ec2c35acSLars Ellenberg 
555f935920SAndreas Gruenbacher #define __nla_type(x)	((__u16)((x) & NLA_TYPE_MASK & ~DRBD_GENLA_F_MANDATORY))
56ec2c35acSLars Ellenberg 
57ec2c35acSLars Ellenberg /*									}}}1
58ec2c35acSLars Ellenberg  * MAGIC
59ec2c35acSLars Ellenberg  * multi-include macro expansion magic starts here
60ec2c35acSLars Ellenberg  */
61ec2c35acSLars Ellenberg 
62ec2c35acSLars Ellenberg /* MAGIC helpers							{{{2 */
63ec2c35acSLars Ellenberg 
nla_put_u64_0pad(struct sk_buff * skb,int attrtype,u64 value)641dee3f59SNicolas Dichtel static inline int nla_put_u64_0pad(struct sk_buff *skb, int attrtype, u64 value)
651dee3f59SNicolas Dichtel {
661dee3f59SNicolas Dichtel 	return nla_put_64bit(skb, attrtype, sizeof(u64), &value, 0);
671dee3f59SNicolas Dichtel }
681dee3f59SNicolas Dichtel 
69ec2c35acSLars Ellenberg /* possible field types */
70ec2c35acSLars Ellenberg #define __flg_field(attr_nr, attr_flag, name) \
71a5d8e1fbSAndreas Gruenbacher 	__field(attr_nr, attr_flag, name, NLA_U8, char, \
7226ec9287SAndreas Gruenbacher 			nla_get_u8, nla_put_u8, false)
73ec2c35acSLars Ellenberg #define __u8_field(attr_nr, attr_flag, name)	\
74ec2c35acSLars Ellenberg 	__field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \
7526ec9287SAndreas Gruenbacher 			nla_get_u8, nla_put_u8, false)
76ec2c35acSLars Ellenberg #define __u16_field(attr_nr, attr_flag, name)	\
77ec2c35acSLars Ellenberg 	__field(attr_nr, attr_flag, name, NLA_U16, __u16, \
7826ec9287SAndreas Gruenbacher 			nla_get_u16, nla_put_u16, false)
79ec2c35acSLars Ellenberg #define __u32_field(attr_nr, attr_flag, name)	\
80ec2c35acSLars Ellenberg 	__field(attr_nr, attr_flag, name, NLA_U32, __u32, \
8126ec9287SAndreas Gruenbacher 			nla_get_u32, nla_put_u32, false)
82563e4cf2SLars Ellenberg #define __s32_field(attr_nr, attr_flag, name)	\
83563e4cf2SLars Ellenberg 	__field(attr_nr, attr_flag, name, NLA_U32, __s32, \
8426ec9287SAndreas Gruenbacher 			nla_get_u32, nla_put_u32, true)
85ec2c35acSLars Ellenberg #define __u64_field(attr_nr, attr_flag, name)	\
86ec2c35acSLars Ellenberg 	__field(attr_nr, attr_flag, name, NLA_U64, __u64, \
871dee3f59SNicolas Dichtel 			nla_get_u64, nla_put_u64_0pad, false)
88ec2c35acSLars Ellenberg #define __str_field(attr_nr, attr_flag, name, maxlen) \
89ec2c35acSLars Ellenberg 	__array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
90872f6903SFrancis Laniel 			nla_strscpy, nla_put, false)
91ec2c35acSLars Ellenberg #define __bin_field(attr_nr, attr_flag, name, maxlen) \
92ec2c35acSLars Ellenberg 	__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
9326ec9287SAndreas Gruenbacher 			nla_memcpy, nla_put, false)
94ec2c35acSLars Ellenberg 
95b966b5ddSAndreas Gruenbacher /* fields with default values */
96b966b5ddSAndreas Gruenbacher #define __flg_field_def(attr_nr, attr_flag, name, default) \
97b966b5ddSAndreas Gruenbacher 	__flg_field(attr_nr, attr_flag, name)
98b966b5ddSAndreas Gruenbacher #define __u32_field_def(attr_nr, attr_flag, name, default) \
99b966b5ddSAndreas Gruenbacher 	__u32_field(attr_nr, attr_flag, name)
1003a45abd5SAndreas Gruenbacher #define __s32_field_def(attr_nr, attr_flag, name, default) \
1013a45abd5SAndreas Gruenbacher 	__s32_field(attr_nr, attr_flag, name)
102b966b5ddSAndreas Gruenbacher #define __str_field_def(attr_nr, attr_flag, name, maxlen) \
103b966b5ddSAndreas Gruenbacher 	__str_field(attr_nr, attr_flag, name, maxlen)
104b966b5ddSAndreas Gruenbacher 
105ec2c35acSLars Ellenberg #define GENL_op_init(args...)	args
106ec2c35acSLars Ellenberg #define GENL_doit(handler)		\
107ec2c35acSLars Ellenberg 	.doit = handler,		\
108ec2c35acSLars Ellenberg 	.flags = GENL_ADMIN_PERM,
109ec2c35acSLars Ellenberg #define GENL_dumpit(handler)		\
110ec2c35acSLars Ellenberg 	.dumpit = handler,		\
111ec2c35acSLars Ellenberg 	.flags = GENL_ADMIN_PERM,
112ec2c35acSLars Ellenberg 
113ec2c35acSLars Ellenberg /*									}}}1
114ec2c35acSLars Ellenberg  * Magic: define the enum symbols for genl_ops
115ec2c35acSLars Ellenberg  * Magic: define the enum symbols for top level attributes
116ec2c35acSLars Ellenberg  * Magic: define the enum symbols for nested attributes
117ec2c35acSLars Ellenberg  *									{{{2
118ec2c35acSLars Ellenberg  */
119ec2c35acSLars Ellenberg 
120ec2c35acSLars Ellenberg #undef GENL_struct
121ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields)
122ec2c35acSLars Ellenberg 
123ec2c35acSLars Ellenberg #undef GENL_mc_group
124ec2c35acSLars Ellenberg #define GENL_mc_group(group)
125ec2c35acSLars Ellenberg 
126ec2c35acSLars Ellenberg #undef GENL_notification
127ec2c35acSLars Ellenberg #define GENL_notification(op_name, op_num, mcast_group, tla_list)	\
128ec2c35acSLars Ellenberg 	op_name = op_num,
129ec2c35acSLars Ellenberg 
130ec2c35acSLars Ellenberg #undef GENL_op
131ec2c35acSLars Ellenberg #define GENL_op(op_name, op_num, handler, tla_list)			\
132ec2c35acSLars Ellenberg 	op_name = op_num,
133ec2c35acSLars Ellenberg 
134ec2c35acSLars Ellenberg enum {
135ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
136ec2c35acSLars Ellenberg };
137ec2c35acSLars Ellenberg 
138ec2c35acSLars Ellenberg #undef GENL_notification
139ec2c35acSLars Ellenberg #define GENL_notification(op_name, op_num, mcast_group, tla_list)
140ec2c35acSLars Ellenberg 
141ec2c35acSLars Ellenberg #undef GENL_op
142ec2c35acSLars Ellenberg #define GENL_op(op_name, op_num, handler, attr_list)
143ec2c35acSLars Ellenberg 
144ec2c35acSLars Ellenberg #undef GENL_struct
145ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields) \
146ec2c35acSLars Ellenberg 		tag_name = tag_number,
147ec2c35acSLars Ellenberg 
148ec2c35acSLars Ellenberg enum {
149ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
150ec2c35acSLars Ellenberg };
151ec2c35acSLars Ellenberg 
152ec2c35acSLars Ellenberg #undef GENL_struct
153ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields)	\
154ec2c35acSLars Ellenberg enum {								\
155ec2c35acSLars Ellenberg 	s_fields						\
156ec2c35acSLars Ellenberg };
157ec2c35acSLars Ellenberg 
158ec2c35acSLars Ellenberg #undef __field
159509100e6SAndreas Gruenbacher #define __field(attr_nr, attr_flag, name, nla_type, type,	\
160509100e6SAndreas Gruenbacher 		__get, __put, __is_signed)			\
1615f935920SAndreas Gruenbacher 	T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)),
162ec2c35acSLars Ellenberg 
163ec2c35acSLars Ellenberg #undef __array
164509100e6SAndreas Gruenbacher #define __array(attr_nr, attr_flag, name, nla_type, type,	\
165509100e6SAndreas Gruenbacher 		maxlen, __get, __put, __is_signed)		\
1665f935920SAndreas Gruenbacher 	T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)),
167ec2c35acSLars Ellenberg 
168ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
169ec2c35acSLars Ellenberg 
170ec2c35acSLars Ellenberg /*									}}}1
171ec2c35acSLars Ellenberg  * Magic: compile time assert unique numbers for operations
172ec2c35acSLars Ellenberg  * Magic: -"- unique numbers for top level attributes
173ec2c35acSLars Ellenberg  * Magic: -"- unique numbers for nested attributes
174ec2c35acSLars Ellenberg  *									{{{2
175ec2c35acSLars Ellenberg  */
176ec2c35acSLars Ellenberg 
177ec2c35acSLars Ellenberg #undef GENL_struct
178ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields)
179ec2c35acSLars Ellenberg 
180ec2c35acSLars Ellenberg #undef GENL_op
181ec2c35acSLars Ellenberg #define GENL_op(op_name, op_num, handler, attr_list)	\
182ec2c35acSLars Ellenberg 	case op_name:
183ec2c35acSLars Ellenberg 
184ec2c35acSLars Ellenberg #undef GENL_notification
185ec2c35acSLars Ellenberg #define GENL_notification(op_name, op_num, mcast_group, tla_list)	\
186ec2c35acSLars Ellenberg 	case op_name:
187ec2c35acSLars Ellenberg 
ct_assert_unique_operations(void)188ec2c35acSLars Ellenberg static inline void ct_assert_unique_operations(void)
189ec2c35acSLars Ellenberg {
190ec2c35acSLars Ellenberg 	switch (0) {
191ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
192a52c5a16SNathan Chancellor 	case 0:
193ec2c35acSLars Ellenberg 		;
194ec2c35acSLars Ellenberg 	}
195ec2c35acSLars Ellenberg }
196ec2c35acSLars Ellenberg 
197ec2c35acSLars Ellenberg #undef GENL_op
198ec2c35acSLars Ellenberg #define GENL_op(op_name, op_num, handler, attr_list)
199ec2c35acSLars Ellenberg 
200ec2c35acSLars Ellenberg #undef GENL_notification
201ec2c35acSLars Ellenberg #define GENL_notification(op_name, op_num, mcast_group, tla_list)
202ec2c35acSLars Ellenberg 
203ec2c35acSLars Ellenberg #undef GENL_struct
204ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
205ec2c35acSLars Ellenberg 		case tag_number:
206ec2c35acSLars Ellenberg 
ct_assert_unique_top_level_attributes(void)207ec2c35acSLars Ellenberg static inline void ct_assert_unique_top_level_attributes(void)
208ec2c35acSLars Ellenberg {
209ec2c35acSLars Ellenberg 	switch (0) {
210ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
211a52c5a16SNathan Chancellor 	case 0:
212ec2c35acSLars Ellenberg 		;
213ec2c35acSLars Ellenberg 	}
214ec2c35acSLars Ellenberg }
215ec2c35acSLars Ellenberg 
216ec2c35acSLars Ellenberg #undef GENL_struct
217ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
218ec2c35acSLars Ellenberg static inline void ct_assert_unique_ ## s_name ## _attributes(void)	\
219ec2c35acSLars Ellenberg {									\
220ec2c35acSLars Ellenberg 	switch (0) {							\
221ec2c35acSLars Ellenberg 	s_fields							\
222a52c5a16SNathan Chancellor 	case 0:								\
223ec2c35acSLars Ellenberg 			;						\
224ec2c35acSLars Ellenberg 	}								\
225ec2c35acSLars Ellenberg }
226ec2c35acSLars Ellenberg 
227ec2c35acSLars Ellenberg #undef __field
228509100e6SAndreas Gruenbacher #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
229509100e6SAndreas Gruenbacher 		__is_signed)						\
230ec2c35acSLars Ellenberg 	case attr_nr:
231ec2c35acSLars Ellenberg 
232ec2c35acSLars Ellenberg #undef __array
233509100e6SAndreas Gruenbacher #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
234509100e6SAndreas Gruenbacher 		__get, __put, __is_signed)				\
235ec2c35acSLars Ellenberg 	case attr_nr:
236ec2c35acSLars Ellenberg 
237ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
238ec2c35acSLars Ellenberg 
239ec2c35acSLars Ellenberg /*									}}}1
240ec2c35acSLars Ellenberg  * Magic: declare structs
241ec2c35acSLars Ellenberg  * struct <name> {
242ec2c35acSLars Ellenberg  *	fields
243ec2c35acSLars Ellenberg  * };
244ec2c35acSLars Ellenberg  *									{{{2
245ec2c35acSLars Ellenberg  */
246ec2c35acSLars Ellenberg 
247ec2c35acSLars Ellenberg #undef GENL_struct
248ec2c35acSLars Ellenberg #define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
249ec2c35acSLars Ellenberg struct s_name { s_fields };
250ec2c35acSLars Ellenberg 
251ec2c35acSLars Ellenberg #undef __field
252509100e6SAndreas Gruenbacher #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
253509100e6SAndreas Gruenbacher 		__is_signed)						\
254ec2c35acSLars Ellenberg 	type name;
255ec2c35acSLars Ellenberg 
256ec2c35acSLars Ellenberg #undef __array
257509100e6SAndreas Gruenbacher #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
258509100e6SAndreas Gruenbacher 		__get, __put, __is_signed)				\
259ec2c35acSLars Ellenberg 	type name[maxlen];	\
260ec2c35acSLars Ellenberg 	__u32 name ## _len;
261ec2c35acSLars Ellenberg 
262ec2c35acSLars Ellenberg #include GENL_MAGIC_INCLUDE_FILE
263ec2c35acSLars Ellenberg 
264509100e6SAndreas Gruenbacher #undef GENL_struct
265509100e6SAndreas Gruenbacher #define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
266509100e6SAndreas Gruenbacher enum {									\
267509100e6SAndreas Gruenbacher 	s_fields							\
268509100e6SAndreas Gruenbacher };
269509100e6SAndreas Gruenbacher 
270509100e6SAndreas Gruenbacher #undef __field
271509100e6SAndreas Gruenbacher #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,	\
272509100e6SAndreas Gruenbacher 		is_signed)						\
273509100e6SAndreas Gruenbacher 	F_ ## name ## _IS_SIGNED = is_signed,
274509100e6SAndreas Gruenbacher 
275509100e6SAndreas Gruenbacher #undef __array
276509100e6SAndreas Gruenbacher #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,	\
277509100e6SAndreas Gruenbacher 		__get, __put, is_signed)				\
278509100e6SAndreas Gruenbacher 	F_ ## name ## _IS_SIGNED = is_signed,
279509100e6SAndreas Gruenbacher 
280509100e6SAndreas Gruenbacher #include GENL_MAGIC_INCLUDE_FILE
281509100e6SAndreas Gruenbacher 
282ec2c35acSLars Ellenberg /* }}}1 */
283ec2c35acSLars Ellenberg #endif /* GENL_MAGIC_STRUCT_H */
284