]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - include/linux/genl_magic_func.h
drbd: Fix the upper limit of resync-after
[mirror_ubuntu-artful-kernel.git] / include / linux / genl_magic_func.h
CommitLineData
ec2c35ac
LE
1#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
81#define __field(attr_nr, attr_flag, name, nla_type, _type, __get, __put) \
82 [__nla_type(attr_nr)] = { .type = nla_type },
83
84#undef __array
85#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen, \
86 __get, __put) \
87 [__nla_type(attr_nr)] = { .type = nla_type, \
88 .len = maxlen - (nla_type == NLA_NUL_STRING) },
89
90#include GENL_MAGIC_INCLUDE_FILE
91
92#ifndef __KERNEL__
93#ifndef pr_info
94#define pr_info(args...) fprintf(stderr, args);
95#endif
96#endif
97
3b98c0c2 98#ifdef GENL_MAGIC_DEBUG
ec2c35ac
LE
99static void dprint_field(const char *dir, int nla_type,
100 const char *name, void *valp)
101{
102 __u64 val = valp ? *(__u32 *)valp : 1;
103 switch (nla_type) {
104 case NLA_U8: val = (__u8)val;
105 case NLA_U16: val = (__u16)val;
106 case NLA_U32: val = (__u32)val;
107 pr_info("%s attr %s: %d 0x%08x\n", dir,
108 name, (int)val, (unsigned)val);
109 break;
110 case NLA_U64:
111 val = *(__u64*)valp;
112 pr_info("%s attr %s: %lld 0x%08llx\n", dir,
113 name, (long long)val, (unsigned long long)val);
114 break;
115 case NLA_FLAG:
116 if (val)
117 pr_info("%s attr %s: set\n", dir, name);
118 break;
119 }
120}
121
122static void dprint_array(const char *dir, int nla_type,
123 const char *name, const char *val, unsigned len)
124{
125 switch (nla_type) {
126 case NLA_NUL_STRING:
127 if (len && val[len-1] == '\0')
128 len--;
129 pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
130 break;
131 default:
132 /* we can always show 4 byte,
133 * thats what nlattr are aligned to. */
134 pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
135 dir, name, len, val[0], val[1], val[2], val[3]);
136 }
137}
138
139#define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b);
140
141/* Name is a member field name of the struct s.
142 * If s is NULL (only parsing, no copy requested in *_from_attrs()),
143 * nla is supposed to point to the attribute containing the information
144 * corresponding to that struct member. */
145#define DPRINT_FIELD(dir, nla_type, name, s, nla) \
146 do { \
147 if (s) \
148 dprint_field(dir, nla_type, #name, &s->name); \
149 else if (nla) \
150 dprint_field(dir, nla_type, #name, \
151 (nla_type == NLA_FLAG) ? NULL \
152 : nla_data(nla)); \
153 } while (0)
154
155#define DPRINT_ARRAY(dir, nla_type, name, s, nla) \
156 do { \
157 if (s) \
158 dprint_array(dir, nla_type, #name, \
159 s->name, s->name ## _len); \
160 else if (nla) \
161 dprint_array(dir, nla_type, #name, \
162 nla_data(nla), nla_len(nla)); \
163 } while (0)
164#else
165#define DPRINT_TLA(a, op, b) do {} while (0)
166#define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0)
167#define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0)
168#endif
169
170/*
171 * Magic: provide conversion functions {{{1
172 * populate struct from attribute table:
173 * {{{2
174 */
175
176/* processing of generic netlink messages is serialized.
177 * use one static buffer for parsing of nested attributes */
178static struct nlattr *nested_attr_tb[128];
179
180#ifndef BUILD_BUG_ON
181/* Force a compilation error if condition is true */
182#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
183/* Force a compilation error if condition is true, but also produce a
184 result (of value 0 and type size_t), so the expression can be used
185 e.g. in a structure initializer (or where-ever else comma expressions
186 aren't permitted). */
187#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
188#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
189#endif
190
191#undef GENL_struct
192#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
f399002e
LE
193/* *_from_attrs functions are static, but potentially unused */ \
194static int __ ## s_name ## _from_attrs(struct s_name *s, \
195 struct genl_info *info, bool exclude_invariants) \
ec2c35ac
LE
196{ \
197 const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \
f399002e 198 struct nlattr *tla = info->attrs[tag_number]; \
ec2c35ac
LE
199 struct nlattr **ntb = nested_attr_tb; \
200 struct nlattr *nla; \
201 int err; \
202 BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb)); \
203 if (!tla) \
204 return -ENOMSG; \
205 DPRINT_TLA(#s_name, "<=-", #tag_name); \
206 err = nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy); \
207 if (err) \
208 return err; \
209 err = nla_check_unknown(maxtype, nla_data(tla), nla_len(tla)); \
210 if (err) \
211 return err; \
212 \
213 s_fields \
214 return 0; \
f399002e
LE
215} __attribute__((unused)) \
216static int s_name ## _from_attrs(struct s_name *s, \
217 struct genl_info *info) \
218{ \
219 return __ ## s_name ## _from_attrs(s, info, false); \
220} __attribute__((unused)) \
221static int s_name ## _from_attrs_for_change(struct s_name *s, \
222 struct genl_info *info) \
223{ \
224 return __ ## s_name ## _from_attrs(s, info, true); \
225} __attribute__((unused)) \
ec2c35ac 226
f399002e 227#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...) \
ec2c35ac
LE
228 nla = ntb[__nla_type(attr_nr)]; \
229 if (nla) { \
f399002e
LE
230 if (exclude_invariants && ((attr_flag) & GENLA_F_INVARIANT)) { \
231 pr_info("<< must not change invariant attr: %s\n", #name); \
232 return -EEXIST; \
233 } \
234 assignment; \
235 } else if (exclude_invariants && ((attr_flag) & GENLA_F_INVARIANT)) { \
236 /* attribute missing from payload, */ \
237 /* which was expected */ \
ec2c35ac
LE
238 } else if ((attr_flag) & GENLA_F_REQUIRED) { \
239 pr_info("<< missing attr: %s\n", #name); \
240 return -ENOMSG; \
241 }
242
f399002e
LE
243#undef __field
244#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \
245 __assign(attr_nr, attr_flag, name, nla_type, type, \
246 if (s) \
247 s->name = __get(nla); \
248 DPRINT_FIELD("<<", nla_type, name, s, nla))
249
ec2c35ac
LE
250/* validate_nla() already checked nla_len <= maxlen appropriately. */
251#undef __array
252#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \
f399002e 253 __assign(attr_nr, attr_flag, name, nla_type, type, \
ec2c35ac
LE
254 if (s) \
255 s->name ## _len = \
256 __get(s->name, nla, maxlen); \
f399002e 257 DPRINT_ARRAY("<<", nla_type, name, s, nla))
ec2c35ac
LE
258
259#include GENL_MAGIC_INCLUDE_FILE
260
261#undef GENL_struct
262#define GENL_struct(tag_name, tag_number, s_name, s_fields)
263
264/*
265 * Magic: define op number to op name mapping {{{1
266 * {{{2
267 */
268const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
269{
270 switch (cmd) {
271#undef GENL_op
272#define GENL_op(op_name, op_num, handler, tla_list) \
273 case op_num: return #op_name;
274#include GENL_MAGIC_INCLUDE_FILE
275 default:
276 return "unknown";
277 }
278}
279
280#ifdef __KERNEL__
281#include <linux/stringify.h>
282/*
283 * Magic: define genl_ops {{{1
284 * {{{2
285 */
286
287#undef GENL_op
288#define GENL_op(op_name, op_num, handler, tla_list) \
289{ \
290 handler \
291 .cmd = op_name, \
292 .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy), \
293},
294
295#define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops)
296static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
297#include GENL_MAGIC_INCLUDE_FILE
298};
299
300#undef GENL_op
301#define GENL_op(op_name, op_num, handler, tla_list)
302
303/*
304 * Define the genl_family, multicast groups, {{{1
305 * and provide register/unregister functions.
306 * {{{2
307 */
308#define ZZZ_genl_family CONCAT_(GENL_MAGIC_FAMILY, _genl_family)
309static struct genl_family ZZZ_genl_family __read_mostly = {
310 .id = GENL_ID_GENERATE,
311 .name = __stringify(GENL_MAGIC_FAMILY),
312 .version = GENL_MAGIC_VERSION,
313#ifdef GENL_MAGIC_FAMILY_HDRSZ
314 .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
315#endif
316 .maxattr = ARRAY_SIZE(drbd_tla_nl_policy)-1,
317};
318
319/*
320 * Magic: define multicast groups
321 * Magic: define multicast group registration helper
322 */
323#undef GENL_mc_group
324#define GENL_mc_group(group) \
325static struct genl_multicast_group \
326CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \
327 .name = #group, \
328}; \
329static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \
330 struct sk_buff *skb, gfp_t flags) \
331{ \
332 unsigned int group_id = \
333 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id; \
334 if (!group_id) \
335 return -EINVAL; \
336 return genlmsg_multicast(skb, 0, group_id, flags); \
337}
338
339#include GENL_MAGIC_INCLUDE_FILE
340
341int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
342{
343 int err = genl_register_family_with_ops(&ZZZ_genl_family,
344 ZZZ_genl_ops, ARRAY_SIZE(ZZZ_genl_ops));
345 if (err)
346 return err;
347#undef GENL_mc_group
348#define GENL_mc_group(group) \
349 err = genl_register_mc_group(&ZZZ_genl_family, \
350 &CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group)); \
351 if (err) \
352 goto fail; \
353 else \
354 pr_info("%s: mcg %s: %u\n", #group, \
355 __stringify(GENL_MAGIC_FAMILY), \
356 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id);
357
358#include GENL_MAGIC_INCLUDE_FILE
359
360#undef GENL_mc_group
361#define GENL_mc_group(group)
362 return 0;
363fail:
364 genl_unregister_family(&ZZZ_genl_family);
365 return err;
366}
367
368void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
369{
370 genl_unregister_family(&ZZZ_genl_family);
371}
372
373/*
374 * Magic: provide conversion functions {{{1
375 * populate skb from struct.
376 * {{{2
377 */
378
379#undef GENL_op
380#define GENL_op(op_name, op_num, handler, tla_list)
381
382#undef GENL_struct
383#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
384static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \
385 const bool exclude_sensitive) \
386{ \
387 struct nlattr *tla = nla_nest_start(skb, tag_number); \
388 if (!tla) \
389 goto nla_put_failure; \
390 DPRINT_TLA(#s_name, "-=>", #tag_name); \
391 s_fields \
392 nla_nest_end(skb, tla); \
393 return 0; \
394 \
395nla_put_failure: \
396 if (tla) \
397 nla_nest_cancel(skb, tla); \
398 return -EMSGSIZE; \
399} \
400static inline int s_name ## _to_priv_skb(struct sk_buff *skb, \
401 struct s_name *s) \
402{ \
403 return s_name ## _to_skb(skb, s, 0); \
404} \
405static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \
406 struct s_name *s) \
407{ \
408 return s_name ## _to_skb(skb, s, 1); \
409}
410
411
412#undef __field
413#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \
414 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \
415 DPRINT_FIELD(">>", nla_type, name, s, NULL); \
416 __put(skb, attr_nr, s->name); \
417 }
418
419#undef __array
420#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \
421 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \
422 DPRINT_ARRAY(">>",nla_type, name, s, NULL); \
423 __put(skb, attr_nr, min_t(int, maxlen, \
424 s->name ## _len + (nla_type == NLA_NUL_STRING)),\
425 s->name); \
426 }
427
428#include GENL_MAGIC_INCLUDE_FILE
429
b966b5dd
AG
430
431/* Functions for initializing structs to default values. */
432
433#undef __field
434#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put)
435#undef __array
436#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put)
437#undef __u32_field_def
438#define __u32_field_def(attr_nr, attr_flag, name, default) \
439 x->name = default;
440#undef __flg_field_def
441#define __flg_field_def(attr_nr, attr_flag, name, default) \
442 x->name = default;
443#undef __str_field_def
444#define __str_field_def(attr_nr, attr_flag, name, maxlen) \
445 memset(x->name, 0, sizeof(x->name)); \
446 x->name ## _len = 0;
447#undef GENL_struct
448#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
449static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
450static void set_ ## s_name ## _defaults(struct s_name *x) { \
451s_fields \
452}
453
454#include GENL_MAGIC_INCLUDE_FILE
455
ec2c35ac
LE
456#endif /* __KERNEL__ */
457
458/* }}}1 */
459#endif /* GENL_MAGIC_FUNC_H */
460/* vim: set foldmethod=marker foldlevel=1 nofoldenable : */