aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/genl_magic_func.h49
-rw-r--r--include/net/genetlink.h48
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)
277static 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
283enum 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) \
278static struct genl_multicast_group \
279CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \
280 .name = #group, \
281}; \
282static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ 291static 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
295int 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
316fail: 305int 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
321void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) 312void 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 */
17struct genl_multicast_group { 14struct 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
23struct genl_ops; 18struct 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 */
153static inline int _genl_register_family_with_ops(struct genl_family *family, 152static 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
166int genl_unregister_family(struct genl_family *family); 175int genl_unregister_family(struct genl_family *family);
167int genl_register_mc_group(struct genl_family *family,
168 struct genl_multicast_group *grp);
169void genl_notify(struct genl_family *family, 176void 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 */
257static inline int genlmsg_multicast_netns(struct genl_family *family, 264static 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 */
272static inline int genlmsg_multicast(struct genl_family *family, 282static 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