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 #if 1
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 	/* static, potentially unused */				\
194 int 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  */
251 const 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)
279 static 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)
292 static 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)						\
308 static struct genl_multicast_group					\
309 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = {		\
310 	.name = #group,							\
311 };									\
312 static 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 
324 int 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;
346 fail:
347 	genl_unregister_family(&ZZZ_genl_family);
348 	return err;
349 }
350 
351 void 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)		\
367 static 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 									\
378 nla_put_failure:							\
379 	if (tla)							\
380 		nla_nest_cancel(skb, tla);				\
381         return -EMSGSIZE;						\
382 }									\
383 static 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 }									\
388 static 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 : */
418