diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/genl_magic_func.h | 49 | ||||
-rw-r--r-- | include/net/genetlink.h | 48 |
2 files changed, 51 insertions, 46 deletions
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h index 5b9b8ae6748b..c0894dd8827b 100644 --- a/include/linux/genl_magic_func.h +++ b/include/linux/genl_magic_func.h | |||
@@ -273,49 +273,40 @@ static struct genl_family ZZZ_genl_family __read_mostly = { | |||
273 | * Magic: define multicast groups | 273 | * Magic: define multicast groups |
274 | * Magic: define multicast group registration helper | 274 | * Magic: define multicast group registration helper |
275 | */ | 275 | */ |
276 | #define ZZZ_genl_mcgrps CONCAT_(GENL_MAGIC_FAMILY, _genl_mcgrps) | ||
277 | static const struct genl_multicast_group ZZZ_genl_mcgrps[] = { | ||
278 | #undef GENL_mc_group | ||
279 | #define GENL_mc_group(group) { .name = #group, }, | ||
280 | #include GENL_MAGIC_INCLUDE_FILE | ||
281 | }; | ||
282 | |||
283 | enum CONCAT_(GENL_MAGIC_FAMILY, group_ids) { | ||
284 | #undef GENL_mc_group | ||
285 | #define GENL_mc_group(group) CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group), | ||
286 | #include GENL_MAGIC_INCLUDE_FILE | ||
287 | }; | ||
288 | |||
276 | #undef GENL_mc_group | 289 | #undef GENL_mc_group |
277 | #define GENL_mc_group(group) \ | 290 | #define GENL_mc_group(group) \ |
278 | static struct genl_multicast_group \ | ||
279 | CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \ | ||
280 | .name = #group, \ | ||
281 | }; \ | ||
282 | static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ | 291 | static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ |
283 | struct sk_buff *skb, gfp_t flags) \ | 292 | struct sk_buff *skb, gfp_t flags) \ |
284 | { \ | 293 | { \ |
285 | unsigned int group_id = \ | 294 | unsigned int group_id = \ |
286 | CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id; \ | 295 | CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group); \ |
287 | if (!group_id) \ | ||
288 | return -EINVAL; \ | ||
289 | return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \ | 296 | return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \ |
290 | group_id, flags); \ | 297 | group_id, flags); \ |
291 | } | 298 | } |
292 | 299 | ||
293 | #include GENL_MAGIC_INCLUDE_FILE | 300 | #include GENL_MAGIC_INCLUDE_FILE |
294 | 301 | ||
295 | int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void) | ||
296 | { | ||
297 | int err = genl_register_family_with_ops(&ZZZ_genl_family, ZZZ_genl_ops); | ||
298 | if (err) | ||
299 | return err; | ||
300 | #undef GENL_mc_group | ||
301 | #define GENL_mc_group(group) \ | ||
302 | err = genl_register_mc_group(&ZZZ_genl_family, \ | ||
303 | &CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group)); \ | ||
304 | if (err) \ | ||
305 | goto fail; \ | ||
306 | else \ | ||
307 | pr_info("%s: mcg %s: %u\n", #group, \ | ||
308 | __stringify(GENL_MAGIC_FAMILY), \ | ||
309 | CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id); | ||
310 | |||
311 | #include GENL_MAGIC_INCLUDE_FILE | ||
312 | |||
313 | #undef GENL_mc_group | 302 | #undef GENL_mc_group |
314 | #define GENL_mc_group(group) | 303 | #define GENL_mc_group(group) |
315 | return 0; | 304 | |
316 | fail: | 305 | int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void) |
317 | genl_unregister_family(&ZZZ_genl_family); | 306 | { |
318 | return err; | 307 | return genl_register_family_with_ops_groups(&ZZZ_genl_family, \ |
308 | ZZZ_genl_ops, \ | ||
309 | ZZZ_genl_mcgrps); | ||
319 | } | 310 | } |
320 | 311 | ||
321 | void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) | 312 | void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) |
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 60aef0df386b..ace4abf118d7 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
@@ -10,14 +10,9 @@ | |||
10 | /** | 10 | /** |
11 | * struct genl_multicast_group - generic netlink multicast group | 11 | * struct genl_multicast_group - generic netlink multicast group |
12 | * @name: name of the multicast group, names are per-family | 12 | * @name: name of the multicast group, names are per-family |
13 | * @id: multicast group ID, assigned by the core, to use with | ||
14 | * genlmsg_multicast(). | ||
15 | * @list: list entry for linking | ||
16 | */ | 13 | */ |
17 | struct genl_multicast_group { | 14 | struct genl_multicast_group { |
18 | struct list_head list; /* private */ | ||
19 | char name[GENL_NAMSIZ]; | 15 | char name[GENL_NAMSIZ]; |
20 | u32 id; | ||
21 | }; | 16 | }; |
22 | 17 | ||
23 | struct genl_ops; | 18 | struct genl_ops; |
@@ -38,7 +33,9 @@ struct genl_info; | |||
38 | * undo operations done by pre_doit, for example release locks | 33 | * undo operations done by pre_doit, for example release locks |
39 | * @attrbuf: buffer to store parsed attributes | 34 | * @attrbuf: buffer to store parsed attributes |
40 | * @family_list: family list | 35 | * @family_list: family list |
41 | * @mcast_groups: multicast groups list | 36 | * @mcgrps: multicast groups used by this family (private) |
37 | * @n_mcgrps: number of multicast groups (private) | ||
38 | * @mcgrp_offset: starting number of multicast group IDs in this family | ||
42 | * @ops: the operations supported by this family (private) | 39 | * @ops: the operations supported by this family (private) |
43 | * @n_ops: number of operations supported by this family (private) | 40 | * @n_ops: number of operations supported by this family (private) |
44 | */ | 41 | */ |
@@ -58,9 +55,11 @@ struct genl_family { | |||
58 | struct genl_info *info); | 55 | struct genl_info *info); |
59 | struct nlattr ** attrbuf; /* private */ | 56 | struct nlattr ** attrbuf; /* private */ |
60 | const struct genl_ops * ops; /* private */ | 57 | const struct genl_ops * ops; /* private */ |
58 | const struct genl_multicast_group *mcgrps; /* private */ | ||
61 | unsigned int n_ops; /* private */ | 59 | unsigned int n_ops; /* private */ |
60 | unsigned int n_mcgrps; /* private */ | ||
61 | unsigned int mcgrp_offset; /* private */ | ||
62 | struct list_head family_list; /* private */ | 62 | struct list_head family_list; /* private */ |
63 | struct list_head mcast_groups; /* private */ | ||
64 | struct module *module; | 63 | struct module *module; |
65 | }; | 64 | }; |
66 | 65 | ||
@@ -150,22 +149,30 @@ static inline int genl_register_family(struct genl_family *family) | |||
150 | * | 149 | * |
151 | * Return 0 on success or a negative error code. | 150 | * Return 0 on success or a negative error code. |
152 | */ | 151 | */ |
153 | static inline int _genl_register_family_with_ops(struct genl_family *family, | 152 | static inline int |
154 | const struct genl_ops *ops, | 153 | _genl_register_family_with_ops_grps(struct genl_family *family, |
155 | size_t n_ops) | 154 | const struct genl_ops *ops, size_t n_ops, |
155 | const struct genl_multicast_group *mcgrps, | ||
156 | size_t n_mcgrps) | ||
156 | { | 157 | { |
157 | family->module = THIS_MODULE; | 158 | family->module = THIS_MODULE; |
158 | family->ops = ops; | 159 | family->ops = ops; |
159 | family->n_ops = n_ops; | 160 | family->n_ops = n_ops; |
161 | family->mcgrps = mcgrps; | ||
162 | family->n_mcgrps = n_mcgrps; | ||
160 | return __genl_register_family(family); | 163 | return __genl_register_family(family); |
161 | } | 164 | } |
162 | 165 | ||
163 | #define genl_register_family_with_ops(family, ops) \ | 166 | #define genl_register_family_with_ops(family, ops) \ |
164 | _genl_register_family_with_ops((family), (ops), ARRAY_SIZE(ops)) | 167 | _genl_register_family_with_ops_grps((family), \ |
168 | (ops), ARRAY_SIZE(ops), \ | ||
169 | NULL, 0) | ||
170 | #define genl_register_family_with_ops_groups(family, ops, grps) \ | ||
171 | _genl_register_family_with_ops_grps((family), \ | ||
172 | (ops), ARRAY_SIZE(ops), \ | ||
173 | (grps), ARRAY_SIZE(grps)) | ||
165 | 174 | ||
166 | int genl_unregister_family(struct genl_family *family); | 175 | int genl_unregister_family(struct genl_family *family); |
167 | int genl_register_mc_group(struct genl_family *family, | ||
168 | struct genl_multicast_group *grp); | ||
169 | void genl_notify(struct genl_family *family, | 176 | void genl_notify(struct genl_family *family, |
170 | struct sk_buff *skb, struct net *net, u32 portid, | 177 | struct sk_buff *skb, struct net *net, u32 portid, |
171 | u32 group, struct nlmsghdr *nlh, gfp_t flags); | 178 | u32 group, struct nlmsghdr *nlh, gfp_t flags); |
@@ -251,13 +258,16 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr) | |||
251 | * @net: the net namespace | 258 | * @net: the net namespace |
252 | * @skb: netlink message as socket buffer | 259 | * @skb: netlink message as socket buffer |
253 | * @portid: own netlink portid to avoid sending to yourself | 260 | * @portid: own netlink portid to avoid sending to yourself |
254 | * @group: multicast group id | 261 | * @group: offset of multicast group in groups array |
255 | * @flags: allocation flags | 262 | * @flags: allocation flags |
256 | */ | 263 | */ |
257 | static inline int genlmsg_multicast_netns(struct genl_family *family, | 264 | static inline int genlmsg_multicast_netns(struct genl_family *family, |
258 | struct net *net, struct sk_buff *skb, | 265 | struct net *net, struct sk_buff *skb, |
259 | u32 portid, unsigned int group, gfp_t flags) | 266 | u32 portid, unsigned int group, gfp_t flags) |
260 | { | 267 | { |
268 | if (group >= family->n_mcgrps) | ||
269 | return -EINVAL; | ||
270 | group = family->mcgrp_offset + group; | ||
261 | return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); | 271 | return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); |
262 | } | 272 | } |
263 | 273 | ||
@@ -266,13 +276,16 @@ static inline int genlmsg_multicast_netns(struct genl_family *family, | |||
266 | * @family: the generic netlink family | 276 | * @family: the generic netlink family |
267 | * @skb: netlink message as socket buffer | 277 | * @skb: netlink message as socket buffer |
268 | * @portid: own netlink portid to avoid sending to yourself | 278 | * @portid: own netlink portid to avoid sending to yourself |
269 | * @group: multicast group id | 279 | * @group: offset of multicast group in groups array |
270 | * @flags: allocation flags | 280 | * @flags: allocation flags |
271 | */ | 281 | */ |
272 | static inline int genlmsg_multicast(struct genl_family *family, | 282 | static inline int genlmsg_multicast(struct genl_family *family, |
273 | struct sk_buff *skb, u32 portid, | 283 | struct sk_buff *skb, u32 portid, |
274 | unsigned int group, gfp_t flags) | 284 | unsigned int group, gfp_t flags) |
275 | { | 285 | { |
286 | if (group >= family->n_mcgrps) | ||
287 | return -EINVAL; | ||
288 | group = family->mcgrp_offset + group; | ||
276 | return genlmsg_multicast_netns(family, &init_net, skb, | 289 | return genlmsg_multicast_netns(family, &init_net, skb, |
277 | portid, group, flags); | 290 | portid, group, flags); |
278 | } | 291 | } |
@@ -282,7 +295,7 @@ static inline int genlmsg_multicast(struct genl_family *family, | |||
282 | * @family: the generic netlink family | 295 | * @family: the generic netlink family |
283 | * @skb: netlink message as socket buffer | 296 | * @skb: netlink message as socket buffer |
284 | * @portid: own netlink portid to avoid sending to yourself | 297 | * @portid: own netlink portid to avoid sending to yourself |
285 | * @group: multicast group id | 298 | * @group: offset of multicast group in groups array |
286 | * @flags: allocation flags | 299 | * @flags: allocation flags |
287 | * | 300 | * |
288 | * This function must hold the RTNL or rcu_read_lock(). | 301 | * This function must hold the RTNL or rcu_read_lock(). |
@@ -365,6 +378,7 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags) | |||
365 | * @net: the network namespace to report the error to | 378 | * @net: the network namespace to report the error to |
366 | * @portid: the PORTID of a process that we want to skip (if any) | 379 | * @portid: the PORTID of a process that we want to skip (if any) |
367 | * @group: the broadcast group that will notice the error | 380 | * @group: the broadcast group that will notice the error |
381 | * (this is the offset of the multicast group in the groups array) | ||
368 | * @code: error code, must be negative (as usual in kernelspace) | 382 | * @code: error code, must be negative (as usual in kernelspace) |
369 | * | 383 | * |
370 | * This function returns the number of broadcast listeners that have set the | 384 | * This function returns the number of broadcast listeners that have set the |