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