aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2011-03-07 04:20:08 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-10-14 10:48:08 -0400
commitec2c35ac1ea288f5c931e32452ecea50068e8450 (patch)
tree0f21d21aab56f188c21109fc38305d17dcce6df3
parent3cb7a2a90fe35eb3059e8860d0c6917eb414f791 (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>
-rw-r--r--include/linux/drbd_genl.h349
-rw-r--r--include/linux/drbd_genl_api.h55
-rw-r--r--include/linux/genl_magic_func.h417
-rw-r--r--include/linux/genl_magic_struct.h260
4 files changed, 1081 insertions, 0 deletions
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
new file mode 100644
index 000000000000..84e16848f7a1
--- /dev/null
+++ b/include/linux/drbd_genl.h
@@ -0,0 +1,349 @@
1/*
2 * General overview:
3 * full generic netlink message:
4 * |nlmsghdr|genlmsghdr|<payload>
5 *
6 * payload:
7 * |optional fixed size family header|<sequence of netlink attributes>
8 *
9 * sequence of netlink attributes:
10 * I chose to have all "top level" attributes NLA_NESTED,
11 * corresponding to some real struct.
12 * So we have a sequence of |tla, len|<nested nla sequence>
13 *
14 * nested nla sequence:
15 * may be empty, or contain a sequence of netlink attributes
16 * representing the struct fields.
17 *
18 * The tag number of any field (regardless of containing struct)
19 * will be available as T_ ## field_name,
20 * so you cannot have the same field name in two differnt structs.
21 *
22 * The tag numbers themselves are per struct, though,
23 * so should always begin at 1 (not 0, that is the special "NLA_UNSPEC" type,
24 * which we won't use here).
25 * The tag numbers are used as index in the respective nla_policy array.
26 *
27 * GENL_struct(tag_name, tag_number, struct name, struct fields) - struct and policy
28 * genl_magic_struct.h
29 * generates the struct declaration,
30 * generates an entry in the tla enum,
31 * genl_magic_func.h
32 * generates an entry in the static tla policy
33 * with .type = NLA_NESTED
34 * generates the static <struct_name>_nl_policy definition,
35 * and static conversion functions
36 *
37 * genl_magic_func.h
38 *
39 * GENL_mc_group(group)
40 * genl_magic_struct.h
41 * does nothing
42 * genl_magic_func.h
43 * defines and registers the mcast group,
44 * and provides a send helper
45 *
46 * GENL_notification(op_name, op_num, mcast_group, tla list)
47 * These are notifications to userspace.
48 *
49 * genl_magic_struct.h
50 * generates an entry in the genl_ops enum,
51 * genl_magic_func.h
52 * does nothing
53 *
54 * mcast group: the name of the mcast group this notification should be
55 * expected on
56 * tla list: the list of expected top level attributes,
57 * for documentation and sanity checking.
58 *
59 * GENL_op(op_name, op_num, flags and handler, tla list) - "genl operations"
60 * These are requests from userspace.
61 *
62 * _op and _notification share the same "number space",
63 * op_nr will be assigned to "genlmsghdr->cmd"
64 *
65 * genl_magic_struct.h
66 * generates an entry in the genl_ops enum,
67 * genl_magic_func.h
68 * generates an entry in the static genl_ops array,
69 * and static register/unregister functions to
70 * genl_register_family_with_ops().
71 *
72 * flags and handler:
73 * GENL_op_init( .doit = x, .dumpit = y, .flags = something)
74 * GENL_doit(x) => .dumpit = NULL, .flags = GENL_ADMIN_PERM
75 * tla list: the list of expected top level attributes,
76 * for documentation and sanity checking.
77 */
78
79/*
80 * STRUCTS
81 */
82
83/* this is sent kernel -> userland on various error conditions, and contains
84 * informational textual info, which is supposedly human readable.
85 * The computer relevant return code is in the drbd_genlmsghdr.
86 */
87GENL_struct(DRBD_NLA_CFG_REPLY, 1, drbd_cfg_reply,
88 /* "arbitrary" size strings, nla_policy.len = 0 */
89 __str_field(1, GENLA_F_MANDATORY, info_text, 0)
90)
91
92/* Configuration requests typically need a context to operate on.
93 * Possible keys are device minor (fits in the drbd_genlmsghdr),
94 * the replication link (aka connection) name,
95 * and/or the replication group (aka resource) name,
96 * and the volume id within the resource. */
97GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context,
98 /* currently only 256 volumes per group,
99 * but maybe we still change that */
100 __u32_field(1, GENLA_F_MANDATORY, ctx_volume)
101 __str_field(2, GENLA_F_MANDATORY, ctx_conn_name, 128)
102)
103
104GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
105 __u64_field(1, GENLA_F_MANDATORY, disk_size)
106 __str_field(2, GENLA_F_REQUIRED, backing_dev, 128)
107 __str_field(3, GENLA_F_REQUIRED, meta_dev, 128)
108 __u32_field(4, GENLA_F_REQUIRED, meta_dev_idx)
109 __u32_field(5, GENLA_F_MANDATORY, max_bio_bvecs)
110 __u32_field(6, GENLA_F_MANDATORY, on_io_error)
111 __u32_field(7, GENLA_F_MANDATORY, fencing)
112 __flg_field(8, GENLA_F_MANDATORY, no_disk_barrier)
113 __flg_field(9, GENLA_F_MANDATORY, no_disk_flush)
114 __flg_field(10, GENLA_F_MANDATORY, no_disk_drain)
115 __flg_field(11, GENLA_F_MANDATORY, no_md_flush)
116 __flg_field(12, GENLA_F_MANDATORY, use_bmbv)
117)
118
119GENL_struct(DRBD_NLA_SYNCER_CONF, 4, syncer_conf,
120 __u32_field(1, GENLA_F_MANDATORY, rate)
121 __u32_field(2, GENLA_F_MANDATORY, after)
122 __u32_field(3, GENLA_F_MANDATORY, al_extents)
123 __str_field(4, GENLA_F_MANDATORY, cpu_mask, 32)
124 __str_field(5, GENLA_F_MANDATORY, verify_alg, SHARED_SECRET_MAX)
125 __str_field(6, GENLA_F_MANDATORY, csums_alg, SHARED_SECRET_MAX)
126 __flg_field(7, GENLA_F_MANDATORY, use_rle)
127 __u32_field(8, GENLA_F_MANDATORY, on_no_data)
128 __u32_field(9, GENLA_F_MANDATORY, c_plan_ahead)
129 __u32_field(10, GENLA_F_MANDATORY, c_delay_target)
130 __u32_field(11, GENLA_F_MANDATORY, c_fill_target)
131 __u32_field(12, GENLA_F_MANDATORY, c_max_rate)
132 __u32_field(13, GENLA_F_MANDATORY, c_min_rate)
133)
134
135GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf,
136 __str_field(1, GENLA_F_MANDATORY | GENLA_F_SENSITIVE,
137 shared_secret, SHARED_SECRET_MAX)
138 __str_field(2, GENLA_F_MANDATORY, cram_hmac_alg, SHARED_SECRET_MAX)
139 __str_field(3, GENLA_F_MANDATORY, integrity_alg, SHARED_SECRET_MAX)
140 __str_field(4, GENLA_F_REQUIRED, my_addr, 128)
141 __str_field(5, GENLA_F_REQUIRED, peer_addr, 128)
142 __u32_field(6, GENLA_F_REQUIRED, wire_protocol)
143 __u32_field(7, GENLA_F_MANDATORY, try_connect_int)
144 __u32_field(8, GENLA_F_MANDATORY, timeout)
145 __u32_field(9, GENLA_F_MANDATORY, ping_int)
146 __u32_field(10, GENLA_F_MANDATORY, ping_timeo)
147 __u32_field(11, GENLA_F_MANDATORY, sndbuf_size)
148 __u32_field(12, GENLA_F_MANDATORY, rcvbuf_size)
149 __u32_field(13, GENLA_F_MANDATORY, ko_count)
150 __u32_field(14, GENLA_F_MANDATORY, max_buffers)
151 __u32_field(15, GENLA_F_MANDATORY, max_epoch_size)
152 __u32_field(16, GENLA_F_MANDATORY, unplug_watermark)
153 __u32_field(17, GENLA_F_MANDATORY, after_sb_0p)
154 __u32_field(18, GENLA_F_MANDATORY, after_sb_1p)
155 __u32_field(19, GENLA_F_MANDATORY, after_sb_2p)
156 __u32_field(20, GENLA_F_MANDATORY, rr_conflict)
157 __u32_field(21, GENLA_F_MANDATORY, on_congestion)
158 __u32_field(22, GENLA_F_MANDATORY, cong_fill)
159 __u32_field(23, GENLA_F_MANDATORY, cong_extents)
160 __flg_field(24, GENLA_F_MANDATORY, two_primaries)
161 __flg_field(25, GENLA_F_MANDATORY, want_lose)
162 __flg_field(26, GENLA_F_MANDATORY, no_cork)
163 __flg_field(27, GENLA_F_MANDATORY, always_asbp)
164 __flg_field(28, GENLA_F_MANDATORY, dry_run)
165)
166
167GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms,
168 __flg_field(1, GENLA_F_MANDATORY, assume_uptodate)
169)
170
171GENL_struct(DRBD_NLA_RESIZE_PARMS, 7, resize_parms,
172 __u64_field(1, GENLA_F_MANDATORY, resize_size)
173 __flg_field(2, GENLA_F_MANDATORY, resize_force)
174 __flg_field(3, GENLA_F_MANDATORY, no_resync)
175)
176
177GENL_struct(DRBD_NLA_STATE_INFO, 8, state_info,
178 /* the reason of the broadcast,
179 * if this is an event triggered broadcast. */
180 __u32_field(1, GENLA_F_MANDATORY, sib_reason)
181 __u32_field(2, GENLA_F_REQUIRED, current_state)
182 __u64_field(3, GENLA_F_MANDATORY, capacity)
183 __u64_field(4, GENLA_F_MANDATORY, ed_uuid)
184
185 /* These are for broadcast from after state change work.
186 * prev_state and new_state are from the moment the state change took
187 * place, new_state is not neccessarily the same as current_state,
188 * there may have been more state changes since. Which will be
189 * broadcasted soon, in their respective after state change work. */
190 __u32_field(5, GENLA_F_MANDATORY, prev_state)
191 __u32_field(6, GENLA_F_MANDATORY, new_state)
192
193 /* if we have a local disk: */
194 __bin_field(7, GENLA_F_MANDATORY, uuids, (UI_SIZE*sizeof(__u64)))
195 __u32_field(8, GENLA_F_MANDATORY, disk_flags)
196 __u64_field(9, GENLA_F_MANDATORY, bits_total)
197 __u64_field(10, GENLA_F_MANDATORY, bits_oos)
198 /* and in case resync or online verify is active */
199 __u64_field(11, GENLA_F_MANDATORY, bits_rs_total)
200 __u64_field(12, GENLA_F_MANDATORY, bits_rs_failed)
201
202 /* for pre and post notifications of helper execution */
203 __str_field(13, GENLA_F_MANDATORY, helper, 32)
204 __u32_field(14, GENLA_F_MANDATORY, helper_exit_code)
205)
206
207GENL_struct(DRBD_NLA_START_OV_PARMS, 9, start_ov_parms,
208 __u64_field(1, GENLA_F_MANDATORY, ov_start_sector)
209)
210
211GENL_struct(DRBD_NLA_NEW_C_UUID_PARMS, 10, new_c_uuid_parms,
212 __flg_field(1, GENLA_F_MANDATORY, clear_bm)
213)
214
215GENL_struct(DRBD_NLA_TIMEOUT_PARMS, 11, timeout_parms,
216 __u32_field(1, GENLA_F_REQUIRED, timeout_type)
217)
218
219GENL_struct(DRBD_NLA_DISCONNECT_PARMS, 12, disconnect_parms,
220 __flg_field(1, GENLA_F_MANDATORY, force_disconnect)
221)
222
223/*
224 * Notifications and commands (genlmsghdr->cmd)
225 */
226GENL_mc_group(events)
227
228 /* kernel -> userspace announcement of changes */
229GENL_notification(
230 DRBD_EVENT, 1, events,
231 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
232 GENL_tla_expected(DRBD_NLA_STATE_INFO, GENLA_F_REQUIRED)
233 GENL_tla_expected(DRBD_NLA_NET_CONF, GENLA_F_MANDATORY)
234 GENL_tla_expected(DRBD_NLA_DISK_CONF, GENLA_F_MANDATORY)
235 GENL_tla_expected(DRBD_NLA_SYNCER_CONF, GENLA_F_MANDATORY)
236)
237
238 /* query kernel for specific or all info */
239GENL_op(
240 DRBD_ADM_GET_STATUS, 2,
241 GENL_op_init(
242 .doit = drbd_adm_get_status,
243 .dumpit = drbd_adm_get_status_all,
244 /* anyone may ask for the status,
245 * it is broadcasted anyways */
246 ),
247 /* To select the object .doit.
248 * Or a subset of objects in .dumpit. */
249 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_MANDATORY)
250)
251
252#if 0
253 /* TO BE DONE */
254 /* create or destroy resources, aka replication groups */
255GENL_op(DRBD_ADM_CREATE_RESOURCE, 3, GENL_doit(drbd_adm_create_resource),
256 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
257GENL_op(DRBD_ADM_DELETE_RESOURCE, 4, GENL_doit(drbd_adm_delete_resource),
258 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
259#endif
260
261 /* add DRBD minor devices as volumes to resources */
262GENL_op(DRBD_ADM_ADD_MINOR, 5, GENL_doit(drbd_adm_add_minor),
263 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
264GENL_op(DRBD_ADM_DEL_MINOR, 6, GENL_doit(drbd_adm_delete_minor),
265 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
266
267 /* add or delete replication links to resources */
268GENL_op(DRBD_ADM_ADD_LINK, 7, GENL_doit(drbd_adm_create_connection),
269 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
270GENL_op(DRBD_ADM_DEL_LINK, 8, GENL_doit(drbd_adm_delete_connection),
271 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
272
273 /* operates on replication links */
274GENL_op(DRBD_ADM_SYNCER, 9,
275 GENL_doit(drbd_adm_syncer),
276 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
277 GENL_tla_expected(DRBD_NLA_SYNCER_CONF, GENLA_F_MANDATORY)
278)
279
280GENL_op(
281 DRBD_ADM_CONNECT, 10,
282 GENL_doit(drbd_adm_connect),
283 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
284 GENL_tla_expected(DRBD_NLA_NET_CONF, GENLA_F_REQUIRED)
285)
286
287GENL_op(DRBD_ADM_DISCONNECT, 11, GENL_doit(drbd_adm_disconnect),
288 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
289
290 /* operates on minors */
291GENL_op(DRBD_ADM_ATTACH, 12,
292 GENL_doit(drbd_adm_attach),
293 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
294 GENL_tla_expected(DRBD_NLA_DISK_CONF, GENLA_F_REQUIRED)
295)
296
297GENL_op(
298 DRBD_ADM_RESIZE, 13,
299 GENL_doit(drbd_adm_resize),
300 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
301 GENL_tla_expected(DRBD_NLA_RESIZE_PARMS, GENLA_F_MANDATORY)
302)
303
304 /* operates on all volumes within a resource */
305GENL_op(
306 DRBD_ADM_PRIMARY, 14,
307 GENL_doit(drbd_adm_set_role),
308 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
309 GENL_tla_expected(DRBD_NLA_SET_ROLE_PARMS, GENLA_F_REQUIRED)
310)
311
312GENL_op(
313 DRBD_ADM_SECONDARY, 15,
314 GENL_doit(drbd_adm_set_role),
315 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
316 GENL_tla_expected(DRBD_NLA_SET_ROLE_PARMS, GENLA_F_REQUIRED)
317)
318
319GENL_op(
320 DRBD_ADM_NEW_C_UUID, 16,
321 GENL_doit(drbd_adm_new_c_uuid),
322 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED)
323 GENL_tla_expected(DRBD_NLA_NEW_C_UUID_PARMS, GENLA_F_MANDATORY)
324)
325
326GENL_op(
327 DRBD_ADM_START_OV, 17,
328 GENL_doit(drbd_adm_start_ov),
329 GENL_tla_expected(DRBD_NLA_START_OV_PARMS, GENLA_F_MANDATORY)
330)
331
332GENL_op(DRBD_ADM_DETACH, 18, GENL_doit(drbd_adm_detach),
333 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
334GENL_op(DRBD_ADM_INVALIDATE, 19, GENL_doit(drbd_adm_invalidate),
335 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
336GENL_op(DRBD_ADM_INVAL_PEER, 20, GENL_doit(drbd_adm_invalidate_peer),
337 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
338GENL_op(DRBD_ADM_PAUSE_SYNC, 21, GENL_doit(drbd_adm_pause_sync),
339 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
340GENL_op(DRBD_ADM_RESUME_SYNC, 22, GENL_doit(drbd_adm_resume_sync),
341 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
342GENL_op(DRBD_ADM_SUSPEND_IO, 23, GENL_doit(drbd_adm_suspend_io),
343 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
344GENL_op(DRBD_ADM_RESUME_IO, 24, GENL_doit(drbd_adm_resume_io),
345 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
346GENL_op(DRBD_ADM_OUTDATE, 25, GENL_doit(drbd_adm_outdate),
347 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
348GENL_op(DRBD_ADM_GET_TIMEOUT_TYPE, 26, GENL_doit(drbd_adm_get_timeout_type),
349 GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, GENLA_F_REQUIRED))
diff --git a/include/linux/drbd_genl_api.h b/include/linux/drbd_genl_api.h
new file mode 100644
index 000000000000..9ef50d51e34e
--- /dev/null
+++ b/include/linux/drbd_genl_api.h
@@ -0,0 +1,55 @@
1#ifndef DRBD_GENL_STRUCT_H
2#define DRBD_GENL_STRUCT_H
3
4/**
5 * struct drbd_genlmsghdr - DRBD specific header used in NETLINK_GENERIC requests
6 * @minor:
7 * For admin requests (user -> kernel): which minor device to operate on.
8 * For (unicast) replies or informational (broadcast) messages
9 * (kernel -> user): which minor device the information is about.
10 * If we do not operate on minors, but on connections or resources,
11 * the minor value shall be (~0), and the attribute DRBD_NLA_CFG_CONTEXT
12 * is used instead.
13 * @flags: possible operation modifiers (relevant only for user->kernel):
14 * DRBD_GENL_F_SET_DEFAULTS
15 * @volume:
16 * When creating a new minor (adding it to a resource), the resource needs
17 * to know which volume number within the resource this is supposed to be.
18 * The volume number corresponds to the same volume number on the remote side,
19 * whereas the minor number on the remote side may be different
20 * (union with flags).
21 * @ret_code: kernel->userland unicast cfg reply return code (union with flags);
22 */
23struct drbd_genlmsghdr {
24 __u32 minor;
25 union {
26 __u32 flags;
27 __s32 ret_code;
28 };
29};
30
31/* To be used in drbd_genlmsghdr.flags */
32enum {
33 DRBD_GENL_F_SET_DEFAULTS = 1,
34};
35
36enum drbd_state_info_bcast_reason {
37 SIB_GET_STATUS_REPLY = 1,
38 SIB_STATE_CHANGE = 2,
39 SIB_HELPER_PRE = 3,
40 SIB_HELPER_POST = 4,
41 SIB_SYNC_PROGRESS = 5,
42};
43
44/* hack around predefined gcc/cpp "linux=1",
45 * we cannot possibly include <1/drbd_genl.h> */
46#undef linux
47
48#include <linux/drbd.h>
49#define GENL_MAGIC_VERSION API_VERSION
50#define GENL_MAGIC_FAMILY drbd
51#define GENL_MAGIC_FAMILY_HDRSZ sizeof(struct drbd_genlmsghdr)
52#define GENL_MAGIC_INCLUDE_FILE <linux/drbd_genl.h>
53#include <linux/genl_magic_struct.h>
54
55#endif
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
new file mode 100644
index 000000000000..8a86f659d363
--- /dev/null
+++ b/include/linux/genl_magic_func.h
@@ -0,0 +1,417 @@
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
98#if 1
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 : */
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
22extern int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void);
23extern 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 */
57enum {
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
137enum {
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
151enum {
152#include GENL_MAGIC_INCLUDE_FILE
153};
154
155#undef GENL_struct
156#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
157enum { \
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
189static 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
207static 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) \
217static 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) \
245struct 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 : */