blob: 2ae16126c6a40ce4089e092a11d3ff8cd3193c8f [file] [log] [blame]
Lars Ellenbergec2c35a2011-03-07 10:20:08 +01001#ifndef GENL_MAGIC_FUNC_H
2#define GENL_MAGIC_FUNC_H
3
4#include <linux/genl_magic_struct.h>
5
6/*
7 * Extension of genl attribute validation policies {{{1
8 * {{{2
9 */
10
11/**
12 * nla_is_required - return true if this attribute is required
13 * @nla: netlink attribute
14 */
15static inline int nla_is_required(const struct nlattr *nla)
16{
17 return nla->nla_type & GENLA_F_REQUIRED;
18}
19
20/**
21 * nla_is_mandatory - return true if understanding this attribute is mandatory
22 * @nla: netlink attribute
23 * Note: REQUIRED attributes are implicitly MANDATORY as well
24 */
25static inline int nla_is_mandatory(const struct nlattr *nla)
26{
27 return nla->nla_type & (GENLA_F_MANDATORY | GENLA_F_REQUIRED);
28}
29
30/* Functionality to be integrated into nla_parse(), and validate_nla(),
31 * respectively.
32 *
33 * Enforcing the "mandatory" bit is done here,
34 * by rejecting unknown mandatory attributes.
35 *
36 * Part of enforcing the "required" flag would mean to embed it into
37 * nla_policy.type, and extending validate_nla(), which currently does
38 * BUG_ON(pt->type > NLA_TYPE_MAX); we have to work on existing kernels,
39 * so we cannot do that. Thats why enforcing "required" is done in the
40 * generated assignment functions below. */
41static int nla_check_unknown(int maxtype, struct nlattr *head, int len)
42{
43 struct nlattr *nla;
44 int rem;
45 nla_for_each_attr(nla, head, len, rem) {
46 __u16 type = nla_type(nla);
47 if (type > maxtype && nla_is_mandatory(nla))
48 return -EOPNOTSUPP;
49 }
50 return 0;
51}
52
53/*
54 * Magic: declare tla policy {{{1
55 * Magic: declare nested policies
56 * {{{2
57 */
58#undef GENL_mc_group
59#define GENL_mc_group(group)
60
61#undef GENL_notification
62#define GENL_notification(op_name, op_num, mcast_group, tla_list)
63
64#undef GENL_op
65#define GENL_op(op_name, op_num, handler, tla_list)
66
67#undef GENL_struct
68#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
69 [tag_name] = { .type = NLA_NESTED },
70
71static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = {
72#include GENL_MAGIC_INCLUDE_FILE
73};
74
75#undef GENL_struct
76#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
77static struct nla_policy s_name ## _nl_policy[] __read_mostly = \
78{ s_fields };
79
80#undef __field
Andreas Gruenbacher509100e2011-05-17 13:29:46 +020081#define __field(attr_nr, attr_flag, name, nla_type, _type, __get, \
82 __put, __is_signed) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +010083 [__nla_type(attr_nr)] = { .type = nla_type },
84
85#undef __array
86#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen, \
Andreas Gruenbacher509100e2011-05-17 13:29:46 +020087 __get, __put, __is_signed) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +010088 [__nla_type(attr_nr)] = { .type = nla_type, \
89 .len = maxlen - (nla_type == NLA_NUL_STRING) },
90
91#include GENL_MAGIC_INCLUDE_FILE
92
93#ifndef __KERNEL__
94#ifndef pr_info
95#define pr_info(args...) fprintf(stderr, args);
96#endif
97#endif
98
Lars Ellenberg3b98c0c2011-03-07 12:49:34 +010099#ifdef GENL_MAGIC_DEBUG
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100100static void dprint_field(const char *dir, int nla_type,
101 const char *name, void *valp)
102{
103 __u64 val = valp ? *(__u32 *)valp : 1;
104 switch (nla_type) {
105 case NLA_U8: val = (__u8)val;
106 case NLA_U16: val = (__u16)val;
107 case NLA_U32: val = (__u32)val;
108 pr_info("%s attr %s: %d 0x%08x\n", dir,
109 name, (int)val, (unsigned)val);
110 break;
111 case NLA_U64:
112 val = *(__u64*)valp;
113 pr_info("%s attr %s: %lld 0x%08llx\n", dir,
114 name, (long long)val, (unsigned long long)val);
115 break;
116 case NLA_FLAG:
117 if (val)
118 pr_info("%s attr %s: set\n", dir, name);
119 break;
120 }
121}
122
123static void dprint_array(const char *dir, int nla_type,
124 const char *name, const char *val, unsigned len)
125{
126 switch (nla_type) {
127 case NLA_NUL_STRING:
128 if (len && val[len-1] == '\0')
129 len--;
130 pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
131 break;
132 default:
133 /* we can always show 4 byte,
134 * thats what nlattr are aligned to. */
135 pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
136 dir, name, len, val[0], val[1], val[2], val[3]);
137 }
138}
139
140#define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b);
141
142/* Name is a member field name of the struct s.
143 * If s is NULL (only parsing, no copy requested in *_from_attrs()),
144 * nla is supposed to point to the attribute containing the information
145 * corresponding to that struct member. */
146#define DPRINT_FIELD(dir, nla_type, name, s, nla) \
147 do { \
148 if (s) \
149 dprint_field(dir, nla_type, #name, &s->name); \
150 else if (nla) \
151 dprint_field(dir, nla_type, #name, \
152 (nla_type == NLA_FLAG) ? NULL \
153 : nla_data(nla)); \
154 } while (0)
155
156#define DPRINT_ARRAY(dir, nla_type, name, s, nla) \
157 do { \
158 if (s) \
159 dprint_array(dir, nla_type, #name, \
160 s->name, s->name ## _len); \
161 else if (nla) \
162 dprint_array(dir, nla_type, #name, \
163 nla_data(nla), nla_len(nla)); \
164 } while (0)
165#else
166#define DPRINT_TLA(a, op, b) do {} while (0)
167#define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0)
168#define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0)
169#endif
170
171/*
172 * Magic: provide conversion functions {{{1
173 * populate struct from attribute table:
174 * {{{2
175 */
176
177/* processing of generic netlink messages is serialized.
178 * use one static buffer for parsing of nested attributes */
179static struct nlattr *nested_attr_tb[128];
180
181#ifndef BUILD_BUG_ON
182/* Force a compilation error if condition is true */
183#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
184/* Force a compilation error if condition is true, but also produce a
185 result (of value 0 and type size_t), so the expression can be used
186 e.g. in a structure initializer (or where-ever else comma expressions
187 aren't permitted). */
188#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
189#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
190#endif
191
192#undef GENL_struct
193#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100194/* *_from_attrs functions are static, but potentially unused */ \
195static int __ ## s_name ## _from_attrs(struct s_name *s, \
196 struct genl_info *info, bool exclude_invariants) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100197{ \
198 const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100199 struct nlattr *tla = info->attrs[tag_number]; \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100200 struct nlattr **ntb = nested_attr_tb; \
201 struct nlattr *nla; \
202 int err; \
203 BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb)); \
204 if (!tla) \
205 return -ENOMSG; \
206 DPRINT_TLA(#s_name, "<=-", #tag_name); \
207 err = nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy); \
208 if (err) \
209 return err; \
210 err = nla_check_unknown(maxtype, nla_data(tla), nla_len(tla)); \
211 if (err) \
212 return err; \
213 \
214 s_fields \
215 return 0; \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100216} __attribute__((unused)) \
217static int s_name ## _from_attrs(struct s_name *s, \
218 struct genl_info *info) \
219{ \
220 return __ ## s_name ## _from_attrs(s, info, false); \
221} __attribute__((unused)) \
222static int s_name ## _from_attrs_for_change(struct s_name *s, \
223 struct genl_info *info) \
224{ \
225 return __ ## s_name ## _from_attrs(s, info, true); \
226} __attribute__((unused)) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100227
Lars Ellenbergf3990022011-03-23 14:31:09 +0100228#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100229 nla = ntb[__nla_type(attr_nr)]; \
230 if (nla) { \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100231 if (exclude_invariants && ((attr_flag) & GENLA_F_INVARIANT)) { \
232 pr_info("<< must not change invariant attr: %s\n", #name); \
233 return -EEXIST; \
234 } \
235 assignment; \
236 } else if (exclude_invariants && ((attr_flag) & GENLA_F_INVARIANT)) { \
237 /* attribute missing from payload, */ \
238 /* which was expected */ \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100239 } else if ((attr_flag) & GENLA_F_REQUIRED) { \
240 pr_info("<< missing attr: %s\n", #name); \
241 return -ENOMSG; \
242 }
243
Lars Ellenbergf3990022011-03-23 14:31:09 +0100244#undef __field
Andreas Gruenbacher509100e2011-05-17 13:29:46 +0200245#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
246 __is_signed) \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100247 __assign(attr_nr, attr_flag, name, nla_type, type, \
248 if (s) \
249 s->name = __get(nla); \
250 DPRINT_FIELD("<<", nla_type, name, s, nla))
251
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100252/* validate_nla() already checked nla_len <= maxlen appropriately. */
253#undef __array
Andreas Gruenbacher509100e2011-05-17 13:29:46 +0200254#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
255 __get, __put, __is_signed) \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100256 __assign(attr_nr, attr_flag, name, nla_type, type, \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100257 if (s) \
258 s->name ## _len = \
259 __get(s->name, nla, maxlen); \
Lars Ellenbergf3990022011-03-23 14:31:09 +0100260 DPRINT_ARRAY("<<", nla_type, name, s, nla))
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100261
262#include GENL_MAGIC_INCLUDE_FILE
263
264#undef GENL_struct
265#define GENL_struct(tag_name, tag_number, s_name, s_fields)
266
267/*
268 * Magic: define op number to op name mapping {{{1
269 * {{{2
270 */
271const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
272{
273 switch (cmd) {
274#undef GENL_op
275#define GENL_op(op_name, op_num, handler, tla_list) \
276 case op_num: return #op_name;
277#include GENL_MAGIC_INCLUDE_FILE
278 default:
279 return "unknown";
280 }
281}
282
283#ifdef __KERNEL__
284#include <linux/stringify.h>
285/*
286 * Magic: define genl_ops {{{1
287 * {{{2
288 */
289
290#undef GENL_op
291#define GENL_op(op_name, op_num, handler, tla_list) \
292{ \
293 handler \
294 .cmd = op_name, \
295 .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy), \
296},
297
298#define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops)
299static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
300#include GENL_MAGIC_INCLUDE_FILE
301};
302
303#undef GENL_op
304#define GENL_op(op_name, op_num, handler, tla_list)
305
306/*
307 * Define the genl_family, multicast groups, {{{1
308 * and provide register/unregister functions.
309 * {{{2
310 */
311#define ZZZ_genl_family CONCAT_(GENL_MAGIC_FAMILY, _genl_family)
312static struct genl_family ZZZ_genl_family __read_mostly = {
313 .id = GENL_ID_GENERATE,
314 .name = __stringify(GENL_MAGIC_FAMILY),
315 .version = GENL_MAGIC_VERSION,
316#ifdef GENL_MAGIC_FAMILY_HDRSZ
317 .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
318#endif
319 .maxattr = ARRAY_SIZE(drbd_tla_nl_policy)-1,
320};
321
322/*
323 * Magic: define multicast groups
324 * Magic: define multicast group registration helper
325 */
326#undef GENL_mc_group
327#define GENL_mc_group(group) \
328static struct genl_multicast_group \
329CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \
330 .name = #group, \
331}; \
332static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \
333 struct sk_buff *skb, gfp_t flags) \
334{ \
335 unsigned int group_id = \
336 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id; \
337 if (!group_id) \
338 return -EINVAL; \
339 return genlmsg_multicast(skb, 0, group_id, flags); \
340}
341
342#include GENL_MAGIC_INCLUDE_FILE
343
344int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
345{
346 int err = genl_register_family_with_ops(&ZZZ_genl_family,
347 ZZZ_genl_ops, ARRAY_SIZE(ZZZ_genl_ops));
348 if (err)
349 return err;
350#undef GENL_mc_group
351#define GENL_mc_group(group) \
352 err = genl_register_mc_group(&ZZZ_genl_family, \
353 &CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group)); \
354 if (err) \
355 goto fail; \
356 else \
357 pr_info("%s: mcg %s: %u\n", #group, \
358 __stringify(GENL_MAGIC_FAMILY), \
359 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id);
360
361#include GENL_MAGIC_INCLUDE_FILE
362
363#undef GENL_mc_group
364#define GENL_mc_group(group)
365 return 0;
366fail:
367 genl_unregister_family(&ZZZ_genl_family);
368 return err;
369}
370
371void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
372{
373 genl_unregister_family(&ZZZ_genl_family);
374}
375
376/*
377 * Magic: provide conversion functions {{{1
378 * populate skb from struct.
379 * {{{2
380 */
381
382#undef GENL_op
383#define GENL_op(op_name, op_num, handler, tla_list)
384
385#undef GENL_struct
386#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
387static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \
388 const bool exclude_sensitive) \
389{ \
390 struct nlattr *tla = nla_nest_start(skb, tag_number); \
391 if (!tla) \
392 goto nla_put_failure; \
393 DPRINT_TLA(#s_name, "-=>", #tag_name); \
394 s_fields \
395 nla_nest_end(skb, tla); \
396 return 0; \
397 \
398nla_put_failure: \
399 if (tla) \
400 nla_nest_cancel(skb, tla); \
401 return -EMSGSIZE; \
402} \
403static inline int s_name ## _to_priv_skb(struct sk_buff *skb, \
404 struct s_name *s) \
405{ \
406 return s_name ## _to_skb(skb, s, 0); \
407} \
408static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \
409 struct s_name *s) \
410{ \
411 return s_name ## _to_skb(skb, s, 1); \
412}
413
414
415#undef __field
Andreas Gruenbacher509100e2011-05-17 13:29:46 +0200416#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
417 __is_signed) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100418 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \
419 DPRINT_FIELD(">>", nla_type, name, s, NULL); \
420 __put(skb, attr_nr, s->name); \
421 }
422
423#undef __array
Andreas Gruenbacher509100e2011-05-17 13:29:46 +0200424#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
425 __get, __put, __is_signed) \
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100426 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \
427 DPRINT_ARRAY(">>",nla_type, name, s, NULL); \
428 __put(skb, attr_nr, min_t(int, maxlen, \
429 s->name ## _len + (nla_type == NLA_NUL_STRING)),\
430 s->name); \
431 }
432
433#include GENL_MAGIC_INCLUDE_FILE
434
Andreas Gruenbacherb966b5d2011-05-03 14:56:09 +0200435
436/* Functions for initializing structs to default values. */
437
438#undef __field
Andreas Gruenbacher509100e2011-05-17 13:29:46 +0200439#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
440 __is_signed)
Andreas Gruenbacherb966b5d2011-05-03 14:56:09 +0200441#undef __array
Andreas Gruenbacher509100e2011-05-17 13:29:46 +0200442#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
443 __get, __put, __is_signed)
Andreas Gruenbacherb966b5d2011-05-03 14:56:09 +0200444#undef __u32_field_def
445#define __u32_field_def(attr_nr, attr_flag, name, default) \
446 x->name = default;
Andreas Gruenbacher3a45abd2011-05-12 12:02:54 +0200447#undef __s32_field_def
448#define __s32_field_def(attr_nr, attr_flag, name, default) \
449 x->name = default;
Andreas Gruenbacherb966b5d2011-05-03 14:56:09 +0200450#undef __flg_field_def
451#define __flg_field_def(attr_nr, attr_flag, name, default) \
452 x->name = default;
453#undef __str_field_def
454#define __str_field_def(attr_nr, attr_flag, name, maxlen) \
455 memset(x->name, 0, sizeof(x->name)); \
456 x->name ## _len = 0;
457#undef GENL_struct
458#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
459static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
460static void set_ ## s_name ## _defaults(struct s_name *x) { \
461s_fields \
462}
463
464#include GENL_MAGIC_INCLUDE_FILE
465
Lars Ellenbergec2c35a2011-03-07 10:20:08 +0100466#endif /* __KERNEL__ */
467
468/* }}}1 */
469#endif /* GENL_MAGIC_FUNC_H */
470/* vim: set foldmethod=marker foldlevel=1 nofoldenable : */