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  */
15 static 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  */
25 static 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. */
41 static 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 
71 static 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)		\
77 static 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 
98 #ifdef GENL_MAGIC_DEBUG
99 static 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 
122 static 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 */
178 static 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 /* *_from_attrs functions are static, but potentially unused */		\
194 static int __ ## s_name ## _from_attrs(struct s_name *s,		\
195 		struct genl_info *info, bool exclude_invariants)	\
196 {									\
197 	const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1;		\
198 	struct nlattr *tla = info->attrs[tag_number];			\
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;							\
215 }					__attribute__((unused))		\
216 static 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))		\
221 static 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))		\
226 
227 #define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...)	\
228 		nla = ntb[__nla_type(attr_nr)];				\
229 		if (nla) {						\
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 */			\
238 		} else if ((attr_flag) & GENLA_F_REQUIRED) {		\
239 			pr_info("<< missing attr: %s\n", #name);	\
240 			return -ENOMSG;					\
241 		}
242 
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 
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) \
253 	__assign(attr_nr, attr_flag, name, nla_type, type,		\
254 			if (s)						\
255 				s->name ## _len =			\
256 					__get(s->name, nla, maxlen);	\
257 			DPRINT_ARRAY("<<", nla_type, name, s, nla))
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  */
268 const 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)
296 static 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)
309 static 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)						\
325 static struct genl_multicast_group					\
326 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = {		\
327 	.name = #group,							\
328 };									\
329 static 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 
341 int 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;
363 fail:
364 	genl_unregister_family(&ZZZ_genl_family);
365 	return err;
366 }
367 
368 void 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)		\
384 static 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 									\
395 nla_put_failure:							\
396 	if (tla)							\
397 		nla_nest_cancel(skb, tla);				\
398         return -EMSGSIZE;						\
399 }									\
400 static 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 }									\
405 static 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 
430 #endif /* __KERNEL__ */
431 
432 /* }}}1 */
433 #endif /* GENL_MAGIC_FUNC_H */
434 /* vim: set foldmethod=marker foldlevel=1 nofoldenable : */
435