drbd: conn_khelper() for user mode callbacks for connections
[GitHub/mt8127/android_kernel_alcatel_ttab.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) \
193 /* static, potentially unused */ \
194int s_name ## _from_attrs(struct s_name *s, struct nlattr *tb[]) \
195{ \
196 const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \
197 struct nlattr *tla = tb[tag_number]; \
198 struct nlattr **ntb = nested_attr_tb; \
199 struct nlattr *nla; \
200 int err; \
201 BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb)); \
202 if (!tla) \
203 return -ENOMSG; \
204 DPRINT_TLA(#s_name, "<=-", #tag_name); \
205 err = nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy); \
206 if (err) \
207 return err; \
208 err = nla_check_unknown(maxtype, nla_data(tla), nla_len(tla)); \
209 if (err) \
210 return err; \
211 \
212 s_fields \
213 return 0; \
214}
215
216#undef __field
217#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \
218 nla = ntb[__nla_type(attr_nr)]; \
219 if (nla) { \
220 if (s) \
221 s->name = __get(nla); \
222 DPRINT_FIELD("<<", nla_type, name, s, nla); \
223 } else if ((attr_flag) & GENLA_F_REQUIRED) { \
224 pr_info("<< missing attr: %s\n", #name); \
225 return -ENOMSG; \
226 }
227
228/* validate_nla() already checked nla_len <= maxlen appropriately. */
229#undef __array
230#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \
231 nla = ntb[__nla_type(attr_nr)]; \
232 if (nla) { \
233 if (s) \
234 s->name ## _len = \
235 __get(s->name, nla, maxlen); \
236 DPRINT_ARRAY("<<", nla_type, name, s, nla); \
237 } else if ((attr_flag) & GENLA_F_REQUIRED) { \
238 pr_info("<< missing attr: %s\n", #name); \
239 return -ENOMSG; \
240 } \
241
242#include GENL_MAGIC_INCLUDE_FILE
243
244#undef GENL_struct
245#define GENL_struct(tag_name, tag_number, s_name, s_fields)
246
247/*
248 * Magic: define op number to op name mapping {{{1
249 * {{{2
250 */
251const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
252{
253 switch (cmd) {
254#undef GENL_op
255#define GENL_op(op_name, op_num, handler, tla_list) \
256 case op_num: return #op_name;
257#include GENL_MAGIC_INCLUDE_FILE
258 default:
259 return "unknown";
260 }
261}
262
263#ifdef __KERNEL__
264#include <linux/stringify.h>
265/*
266 * Magic: define genl_ops {{{1
267 * {{{2
268 */
269
270#undef GENL_op
271#define GENL_op(op_name, op_num, handler, tla_list) \
272{ \
273 handler \
274 .cmd = op_name, \
275 .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy), \
276},
277
278#define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops)
279static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
280#include GENL_MAGIC_INCLUDE_FILE
281};
282
283#undef GENL_op
284#define GENL_op(op_name, op_num, handler, tla_list)
285
286/*
287 * Define the genl_family, multicast groups, {{{1
288 * and provide register/unregister functions.
289 * {{{2
290 */
291#define ZZZ_genl_family CONCAT_(GENL_MAGIC_FAMILY, _genl_family)
292static struct genl_family ZZZ_genl_family __read_mostly = {
293 .id = GENL_ID_GENERATE,
294 .name = __stringify(GENL_MAGIC_FAMILY),
295 .version = GENL_MAGIC_VERSION,
296#ifdef GENL_MAGIC_FAMILY_HDRSZ
297 .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
298#endif
299 .maxattr = ARRAY_SIZE(drbd_tla_nl_policy)-1,
300};
301
302/*
303 * Magic: define multicast groups
304 * Magic: define multicast group registration helper
305 */
306#undef GENL_mc_group
307#define GENL_mc_group(group) \
308static struct genl_multicast_group \
309CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \
310 .name = #group, \
311}; \
312static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \
313 struct sk_buff *skb, gfp_t flags) \
314{ \
315 unsigned int group_id = \
316 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id; \
317 if (!group_id) \
318 return -EINVAL; \
319 return genlmsg_multicast(skb, 0, group_id, flags); \
320}
321
322#include GENL_MAGIC_INCLUDE_FILE
323
324int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
325{
326 int err = genl_register_family_with_ops(&ZZZ_genl_family,
327 ZZZ_genl_ops, ARRAY_SIZE(ZZZ_genl_ops));
328 if (err)
329 return err;
330#undef GENL_mc_group
331#define GENL_mc_group(group) \
332 err = genl_register_mc_group(&ZZZ_genl_family, \
333 &CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group)); \
334 if (err) \
335 goto fail; \
336 else \
337 pr_info("%s: mcg %s: %u\n", #group, \
338 __stringify(GENL_MAGIC_FAMILY), \
339 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id);
340
341#include GENL_MAGIC_INCLUDE_FILE
342
343#undef GENL_mc_group
344#define GENL_mc_group(group)
345 return 0;
346fail:
347 genl_unregister_family(&ZZZ_genl_family);
348 return err;
349}
350
351void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
352{
353 genl_unregister_family(&ZZZ_genl_family);
354}
355
356/*
357 * Magic: provide conversion functions {{{1
358 * populate skb from struct.
359 * {{{2
360 */
361
362#undef GENL_op
363#define GENL_op(op_name, op_num, handler, tla_list)
364
365#undef GENL_struct
366#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
367static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \
368 const bool exclude_sensitive) \
369{ \
370 struct nlattr *tla = nla_nest_start(skb, tag_number); \
371 if (!tla) \
372 goto nla_put_failure; \
373 DPRINT_TLA(#s_name, "-=>", #tag_name); \
374 s_fields \
375 nla_nest_end(skb, tla); \
376 return 0; \
377 \
378nla_put_failure: \
379 if (tla) \
380 nla_nest_cancel(skb, tla); \
381 return -EMSGSIZE; \
382} \
383static inline int s_name ## _to_priv_skb(struct sk_buff *skb, \
384 struct s_name *s) \
385{ \
386 return s_name ## _to_skb(skb, s, 0); \
387} \
388static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \
389 struct s_name *s) \
390{ \
391 return s_name ## _to_skb(skb, s, 1); \
392}
393
394
395#undef __field
396#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \
397 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \
398 DPRINT_FIELD(">>", nla_type, name, s, NULL); \
399 __put(skb, attr_nr, s->name); \
400 }
401
402#undef __array
403#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \
404 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \
405 DPRINT_ARRAY(">>",nla_type, name, s, NULL); \
406 __put(skb, attr_nr, min_t(int, maxlen, \
407 s->name ## _len + (nla_type == NLA_NUL_STRING)),\
408 s->name); \
409 }
410
411#include GENL_MAGIC_INCLUDE_FILE
412
413#endif /* __KERNEL__ */
414
415/* }}}1 */
416#endif /* GENL_MAGIC_FUNC_H */
417/* vim: set foldmethod=marker foldlevel=1 nofoldenable : */