diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2011-03-07 04:20:08 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-10-14 10:48:08 -0400 |
commit | ec2c35ac1ea288f5c931e32452ecea50068e8450 (patch) | |
tree | 0f21d21aab56f188c21109fc38305d17dcce6df3 /include/linux/genl_magic_struct.h | |
parent | 3cb7a2a90fe35eb3059e8860d0c6917eb414f791 (diff) |
drbd: prepare the transition from connector to genetlink
This adds the new API header and helper files.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'include/linux/genl_magic_struct.h')
-rw-r--r-- | include/linux/genl_magic_struct.h | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h new file mode 100644 index 000000000000..745ebfd6c7e5 --- /dev/null +++ b/include/linux/genl_magic_struct.h | |||
@@ -0,0 +1,260 @@ | |||
1 | #ifndef GENL_MAGIC_STRUCT_H | ||
2 | #define GENL_MAGIC_STRUCT_H | ||
3 | |||
4 | #ifndef GENL_MAGIC_FAMILY | ||
5 | # error "you need to define GENL_MAGIC_FAMILY before inclusion" | ||
6 | #endif | ||
7 | |||
8 | #ifndef GENL_MAGIC_VERSION | ||
9 | # error "you need to define GENL_MAGIC_VERSION before inclusion" | ||
10 | #endif | ||
11 | |||
12 | #ifndef GENL_MAGIC_INCLUDE_FILE | ||
13 | # error "you need to define GENL_MAGIC_INCLUDE_FILE before inclusion" | ||
14 | #endif | ||
15 | |||
16 | #include <linux/genetlink.h> | ||
17 | #include <linux/types.h> | ||
18 | |||
19 | #define CONCAT__(a,b) a ## b | ||
20 | #define CONCAT_(a,b) CONCAT__(a,b) | ||
21 | |||
22 | extern int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void); | ||
23 | extern void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void); | ||
24 | |||
25 | /* | ||
26 | * Extension of genl attribute validation policies {{{2 | ||
27 | */ | ||
28 | |||
29 | /** | ||
30 | * GENLA_F_FLAGS - policy type flags to ease compatible ABI evolvement | ||
31 | * | ||
32 | * @GENLA_F_REQUIRED: attribute has to be present, or message is considered invalid. | ||
33 | * Adding new REQUIRED attributes breaks ABI compatibility, so don't do that. | ||
34 | * | ||
35 | * @GENLA_F_MANDATORY: if present, receiver _must_ understand it. | ||
36 | * Without this, unknown attributes (> maxtype) are _silently_ ignored | ||
37 | * by validate_nla(). | ||
38 | * | ||
39 | * To be used for API extensions, so older kernel can reject requests for not | ||
40 | * yet implemented features, if newer userland tries to use them even though | ||
41 | * the genl_family version clearly indicates they are not available. | ||
42 | * | ||
43 | * @GENLA_F_MAY_IGNORE: To clearly document the fact, for good measure. | ||
44 | * To be used for API extensions for things that have sane defaults, | ||
45 | * so newer userland can still talk to older kernel, knowing it will | ||
46 | * silently ignore these attributes if not yet known. | ||
47 | * | ||
48 | * NOTE: These flags overload | ||
49 | * NLA_F_NESTED (1 << 15) | ||
50 | * NLA_F_NET_BYTEORDER (1 << 14) | ||
51 | * from linux/netlink.h, which are not useful for validate_nla(): | ||
52 | * NET_BYTEORDER is not used anywhere, and NESTED would be specified by setting | ||
53 | * .type = NLA_NESTED in the appropriate policy. | ||
54 | * | ||
55 | * See also: nla_type() | ||
56 | */ | ||
57 | enum { | ||
58 | GENLA_F_MAY_IGNORE = 0, | ||
59 | GENLA_F_MANDATORY = 1 << 14, | ||
60 | GENLA_F_REQUIRED = 1 << 15, | ||
61 | |||
62 | /* This will not be present in the __u16 .nla_type, but can be | ||
63 | * triggered on in <struct>_to_skb, to exclude "sensitive" | ||
64 | * information from broadcasts, or on unpriviledged get requests. | ||
65 | * This is useful because genetlink multicast groups can be listened in | ||
66 | * on by anyone. */ | ||
67 | GENLA_F_SENSITIVE = 1 << 16, | ||
68 | }; | ||
69 | |||
70 | #define __nla_type(x) ((__u16)((__u16)(x) & (__u16)NLA_TYPE_MASK)) | ||
71 | |||
72 | /* }}}1 | ||
73 | * MAGIC | ||
74 | * multi-include macro expansion magic starts here | ||
75 | */ | ||
76 | |||
77 | /* MAGIC helpers {{{2 */ | ||
78 | |||
79 | /* possible field types */ | ||
80 | #define __flg_field(attr_nr, attr_flag, name) \ | ||
81 | __field(attr_nr, attr_flag, name, NLA_FLAG, char, \ | ||
82 | nla_get_flag, __nla_put_flag) | ||
83 | #define __u8_field(attr_nr, attr_flag, name) \ | ||
84 | __field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \ | ||
85 | nla_get_u8, NLA_PUT_U8) | ||
86 | #define __u16_field(attr_nr, attr_flag, name) \ | ||
87 | __field(attr_nr, attr_flag, name, NLA_U16, __u16, \ | ||
88 | nla_get_u16, NLA_PUT_U16) | ||
89 | #define __u32_field(attr_nr, attr_flag, name) \ | ||
90 | __field(attr_nr, attr_flag, name, NLA_U32, __u32, \ | ||
91 | nla_get_u32, NLA_PUT_U32) | ||
92 | #define __u64_field(attr_nr, attr_flag, name) \ | ||
93 | __field(attr_nr, attr_flag, name, NLA_U64, __u64, \ | ||
94 | nla_get_u64, NLA_PUT_U64) | ||
95 | #define __str_field(attr_nr, attr_flag, name, maxlen) \ | ||
96 | __array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \ | ||
97 | nla_strlcpy, NLA_PUT) | ||
98 | #define __bin_field(attr_nr, attr_flag, name, maxlen) \ | ||
99 | __array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \ | ||
100 | nla_memcpy, NLA_PUT) | ||
101 | |||
102 | #define __nla_put_flag(skb, attrtype, value) \ | ||
103 | do { \ | ||
104 | if (value) \ | ||
105 | NLA_PUT_FLAG(skb, attrtype); \ | ||
106 | } while (0) | ||
107 | |||
108 | #define GENL_op_init(args...) args | ||
109 | #define GENL_doit(handler) \ | ||
110 | .doit = handler, \ | ||
111 | .flags = GENL_ADMIN_PERM, | ||
112 | #define GENL_dumpit(handler) \ | ||
113 | .dumpit = handler, \ | ||
114 | .flags = GENL_ADMIN_PERM, | ||
115 | |||
116 | /* }}}1 | ||
117 | * Magic: define the enum symbols for genl_ops | ||
118 | * Magic: define the enum symbols for top level attributes | ||
119 | * Magic: define the enum symbols for nested attributes | ||
120 | * {{{2 | ||
121 | */ | ||
122 | |||
123 | #undef GENL_struct | ||
124 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) | ||
125 | |||
126 | #undef GENL_mc_group | ||
127 | #define GENL_mc_group(group) | ||
128 | |||
129 | #undef GENL_notification | ||
130 | #define GENL_notification(op_name, op_num, mcast_group, tla_list) \ | ||
131 | op_name = op_num, | ||
132 | |||
133 | #undef GENL_op | ||
134 | #define GENL_op(op_name, op_num, handler, tla_list) \ | ||
135 | op_name = op_num, | ||
136 | |||
137 | enum { | ||
138 | #include GENL_MAGIC_INCLUDE_FILE | ||
139 | }; | ||
140 | |||
141 | #undef GENL_notification | ||
142 | #define GENL_notification(op_name, op_num, mcast_group, tla_list) | ||
143 | |||
144 | #undef GENL_op | ||
145 | #define GENL_op(op_name, op_num, handler, attr_list) | ||
146 | |||
147 | #undef GENL_struct | ||
148 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ | ||
149 | tag_name = tag_number, | ||
150 | |||
151 | enum { | ||
152 | #include GENL_MAGIC_INCLUDE_FILE | ||
153 | }; | ||
154 | |||
155 | #undef GENL_struct | ||
156 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ | ||
157 | enum { \ | ||
158 | s_fields \ | ||
159 | }; | ||
160 | |||
161 | #undef __field | ||
162 | #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \ | ||
163 | T_ ## name = (__u16)(attr_nr | attr_flag), | ||
164 | |||
165 | #undef __array | ||
166 | #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \ | ||
167 | T_ ## name = (__u16)(attr_nr | attr_flag), | ||
168 | |||
169 | #include GENL_MAGIC_INCLUDE_FILE | ||
170 | |||
171 | /* }}}1 | ||
172 | * Magic: compile time assert unique numbers for operations | ||
173 | * Magic: -"- unique numbers for top level attributes | ||
174 | * Magic: -"- unique numbers for nested attributes | ||
175 | * {{{2 | ||
176 | */ | ||
177 | |||
178 | #undef GENL_struct | ||
179 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) | ||
180 | |||
181 | #undef GENL_op | ||
182 | #define GENL_op(op_name, op_num, handler, attr_list) \ | ||
183 | case op_name: | ||
184 | |||
185 | #undef GENL_notification | ||
186 | #define GENL_notification(op_name, op_num, mcast_group, tla_list) \ | ||
187 | case op_name: | ||
188 | |||
189 | static inline void ct_assert_unique_operations(void) | ||
190 | { | ||
191 | switch (0) { | ||
192 | #include GENL_MAGIC_INCLUDE_FILE | ||
193 | ; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | #undef GENL_op | ||
198 | #define GENL_op(op_name, op_num, handler, attr_list) | ||
199 | |||
200 | #undef GENL_notification | ||
201 | #define GENL_notification(op_name, op_num, mcast_group, tla_list) | ||
202 | |||
203 | #undef GENL_struct | ||
204 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ | ||
205 | case tag_number: | ||
206 | |||
207 | static inline void ct_assert_unique_top_level_attributes(void) | ||
208 | { | ||
209 | switch (0) { | ||
210 | #include GENL_MAGIC_INCLUDE_FILE | ||
211 | ; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | #undef GENL_struct | ||
216 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ | ||
217 | static inline void ct_assert_unique_ ## s_name ## _attributes(void) \ | ||
218 | { \ | ||
219 | switch (0) { \ | ||
220 | s_fields \ | ||
221 | ; \ | ||
222 | } \ | ||
223 | } | ||
224 | |||
225 | #undef __field | ||
226 | #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \ | ||
227 | case attr_nr: | ||
228 | |||
229 | #undef __array | ||
230 | #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \ | ||
231 | case attr_nr: | ||
232 | |||
233 | #include GENL_MAGIC_INCLUDE_FILE | ||
234 | |||
235 | /* }}}1 | ||
236 | * Magic: declare structs | ||
237 | * struct <name> { | ||
238 | * fields | ||
239 | * }; | ||
240 | * {{{2 | ||
241 | */ | ||
242 | |||
243 | #undef GENL_struct | ||
244 | #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ | ||
245 | struct s_name { s_fields }; | ||
246 | |||
247 | #undef __field | ||
248 | #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put) \ | ||
249 | type name; | ||
250 | |||
251 | #undef __array | ||
252 | #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put) \ | ||
253 | type name[maxlen]; \ | ||
254 | __u32 name ## _len; | ||
255 | |||
256 | #include GENL_MAGIC_INCLUDE_FILE | ||
257 | |||
258 | /* }}}1 */ | ||
259 | #endif /* GENL_MAGIC_STRUCT_H */ | ||
260 | /* vim: set foldmethod=marker nofoldenable : */ | ||