diff options
Diffstat (limited to 'include/net/genetlink.h')
-rw-r--r-- | include/net/genetlink.h | 131 |
1 files changed, 94 insertions, 37 deletions
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 9b787b62cf16..ace4abf118d7 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
@@ -10,16 +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 | * @family: pointer to family, need not be set before registering | ||
17 | */ | 13 | */ |
18 | struct genl_multicast_group { | 14 | struct genl_multicast_group { |
19 | struct genl_family *family; /* private */ | ||
20 | struct list_head list; /* private */ | ||
21 | char name[GENL_NAMSIZ]; | 15 | char name[GENL_NAMSIZ]; |
22 | u32 id; | ||
23 | }; | 16 | }; |
24 | 17 | ||
25 | struct genl_ops; | 18 | struct genl_ops; |
@@ -39,9 +32,12 @@ struct genl_info; | |||
39 | * @post_doit: called after an operation's doit callback, it may | 32 | * @post_doit: called after an operation's doit callback, it may |
40 | * undo operations done by pre_doit, for example release locks | 33 | * undo operations done by pre_doit, for example release locks |
41 | * @attrbuf: buffer to store parsed attributes | 34 | * @attrbuf: buffer to store parsed attributes |
42 | * @ops_list: list of all assigned operations | ||
43 | * @family_list: family list | 35 | * @family_list: family list |
44 | * @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 | ||
39 | * @ops: the operations supported by this family (private) | ||
40 | * @n_ops: number of operations supported by this family (private) | ||
45 | */ | 41 | */ |
46 | struct genl_family { | 42 | struct genl_family { |
47 | unsigned int id; | 43 | unsigned int id; |
@@ -51,16 +47,19 @@ struct genl_family { | |||
51 | unsigned int maxattr; | 47 | unsigned int maxattr; |
52 | bool netnsok; | 48 | bool netnsok; |
53 | bool parallel_ops; | 49 | bool parallel_ops; |
54 | int (*pre_doit)(struct genl_ops *ops, | 50 | int (*pre_doit)(const struct genl_ops *ops, |
55 | struct sk_buff *skb, | 51 | struct sk_buff *skb, |
56 | struct genl_info *info); | 52 | struct genl_info *info); |
57 | void (*post_doit)(struct genl_ops *ops, | 53 | void (*post_doit)(const struct genl_ops *ops, |
58 | struct sk_buff *skb, | 54 | struct sk_buff *skb, |
59 | struct genl_info *info); | 55 | struct genl_info *info); |
60 | struct nlattr ** attrbuf; /* private */ | 56 | struct nlattr ** attrbuf; /* private */ |
61 | struct list_head ops_list; /* private */ | 57 | const struct genl_ops * ops; /* private */ |
58 | const struct genl_multicast_group *mcgrps; /* 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 | ||
@@ -110,16 +109,15 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) | |||
110 | * @ops_list: operations list | 109 | * @ops_list: operations list |
111 | */ | 110 | */ |
112 | struct genl_ops { | 111 | struct genl_ops { |
113 | u8 cmd; | ||
114 | u8 internal_flags; | ||
115 | unsigned int flags; | ||
116 | const struct nla_policy *policy; | 112 | const struct nla_policy *policy; |
117 | int (*doit)(struct sk_buff *skb, | 113 | int (*doit)(struct sk_buff *skb, |
118 | struct genl_info *info); | 114 | struct genl_info *info); |
119 | int (*dumpit)(struct sk_buff *skb, | 115 | int (*dumpit)(struct sk_buff *skb, |
120 | struct netlink_callback *cb); | 116 | struct netlink_callback *cb); |
121 | int (*done)(struct netlink_callback *cb); | 117 | int (*done)(struct netlink_callback *cb); |
122 | struct list_head ops_list; | 118 | u8 cmd; |
119 | u8 internal_flags; | ||
120 | u8 flags; | ||
123 | }; | 121 | }; |
124 | 122 | ||
125 | int __genl_register_family(struct genl_family *family); | 123 | int __genl_register_family(struct genl_family *family); |
@@ -130,24 +128,53 @@ static inline int genl_register_family(struct genl_family *family) | |||
130 | return __genl_register_family(family); | 128 | return __genl_register_family(family); |
131 | } | 129 | } |
132 | 130 | ||
133 | int __genl_register_family_with_ops(struct genl_family *family, | 131 | /** |
134 | struct genl_ops *ops, size_t n_ops); | 132 | * genl_register_family_with_ops - register a generic netlink family with ops |
135 | 133 | * @family: generic netlink family | |
136 | static inline int genl_register_family_with_ops(struct genl_family *family, | 134 | * @ops: operations to be registered |
137 | struct genl_ops *ops, size_t n_ops) | 135 | * @n_ops: number of elements to register |
136 | * | ||
137 | * Registers the specified family and operations from the specified table. | ||
138 | * Only one family may be registered with the same family name or identifier. | ||
139 | * | ||
140 | * The family id may equal GENL_ID_GENERATE causing an unique id to | ||
141 | * be automatically generated and assigned. | ||
142 | * | ||
143 | * Either a doit or dumpit callback must be specified for every registered | ||
144 | * operation or the function will fail. Only one operation structure per | ||
145 | * command identifier may be registered. | ||
146 | * | ||
147 | * See include/net/genetlink.h for more documenation on the operations | ||
148 | * structure. | ||
149 | * | ||
150 | * Return 0 on success or a negative error code. | ||
151 | */ | ||
152 | static inline int | ||
153 | _genl_register_family_with_ops_grps(struct genl_family *family, | ||
154 | const struct genl_ops *ops, size_t n_ops, | ||
155 | const struct genl_multicast_group *mcgrps, | ||
156 | size_t n_mcgrps) | ||
138 | { | 157 | { |
139 | family->module = THIS_MODULE; | 158 | family->module = THIS_MODULE; |
140 | return __genl_register_family_with_ops(family, ops, n_ops); | 159 | family->ops = ops; |
160 | family->n_ops = n_ops; | ||
161 | family->mcgrps = mcgrps; | ||
162 | family->n_mcgrps = n_mcgrps; | ||
163 | return __genl_register_family(family); | ||
141 | } | 164 | } |
142 | 165 | ||
166 | #define genl_register_family_with_ops(family, 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)) | ||
174 | |||
143 | int genl_unregister_family(struct genl_family *family); | 175 | int genl_unregister_family(struct genl_family *family); |
144 | int genl_register_ops(struct genl_family *, struct genl_ops *ops); | 176 | void genl_notify(struct genl_family *family, |
145 | int genl_unregister_ops(struct genl_family *, struct genl_ops *ops); | 177 | struct sk_buff *skb, struct net *net, u32 portid, |
146 | int genl_register_mc_group(struct genl_family *family, | ||
147 | struct genl_multicast_group *grp); | ||
148 | void genl_unregister_mc_group(struct genl_family *family, | ||
149 | struct genl_multicast_group *grp); | ||
150 | void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, | ||
151 | u32 group, struct nlmsghdr *nlh, gfp_t flags); | 178 | u32 group, struct nlmsghdr *nlh, gfp_t flags); |
152 | 179 | ||
153 | void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, | 180 | void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, |
@@ -227,41 +254,54 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr) | |||
227 | 254 | ||
228 | /** | 255 | /** |
229 | * genlmsg_multicast_netns - multicast a netlink message to a specific netns | 256 | * genlmsg_multicast_netns - multicast a netlink message to a specific netns |
257 | * @family: the generic netlink family | ||
230 | * @net: the net namespace | 258 | * @net: the net namespace |
231 | * @skb: netlink message as socket buffer | 259 | * @skb: netlink message as socket buffer |
232 | * @portid: own netlink portid to avoid sending to yourself | 260 | * @portid: own netlink portid to avoid sending to yourself |
233 | * @group: multicast group id | 261 | * @group: offset of multicast group in groups array |
234 | * @flags: allocation flags | 262 | * @flags: allocation flags |
235 | */ | 263 | */ |
236 | static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb, | 264 | static inline int genlmsg_multicast_netns(struct genl_family *family, |
265 | struct net *net, struct sk_buff *skb, | ||
237 | u32 portid, unsigned int group, gfp_t flags) | 266 | u32 portid, unsigned int group, gfp_t flags) |
238 | { | 267 | { |
268 | if (group >= family->n_mcgrps) | ||
269 | return -EINVAL; | ||
270 | group = family->mcgrp_offset + group; | ||
239 | return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); | 271 | return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); |
240 | } | 272 | } |
241 | 273 | ||
242 | /** | 274 | /** |
243 | * genlmsg_multicast - multicast a netlink message to the default netns | 275 | * genlmsg_multicast - multicast a netlink message to the default netns |
276 | * @family: the generic netlink family | ||
244 | * @skb: netlink message as socket buffer | 277 | * @skb: netlink message as socket buffer |
245 | * @portid: own netlink portid to avoid sending to yourself | 278 | * @portid: own netlink portid to avoid sending to yourself |
246 | * @group: multicast group id | 279 | * @group: offset of multicast group in groups array |
247 | * @flags: allocation flags | 280 | * @flags: allocation flags |
248 | */ | 281 | */ |
249 | static inline int genlmsg_multicast(struct sk_buff *skb, u32 portid, | 282 | static inline int genlmsg_multicast(struct genl_family *family, |
283 | struct sk_buff *skb, u32 portid, | ||
250 | unsigned int group, gfp_t flags) | 284 | unsigned int group, gfp_t flags) |
251 | { | 285 | { |
252 | return genlmsg_multicast_netns(&init_net, skb, portid, group, flags); | 286 | if (group >= family->n_mcgrps) |
287 | return -EINVAL; | ||
288 | group = family->mcgrp_offset + group; | ||
289 | return genlmsg_multicast_netns(family, &init_net, skb, | ||
290 | portid, group, flags); | ||
253 | } | 291 | } |
254 | 292 | ||
255 | /** | 293 | /** |
256 | * genlmsg_multicast_allns - multicast a netlink message to all net namespaces | 294 | * genlmsg_multicast_allns - multicast a netlink message to all net namespaces |
295 | * @family: the generic netlink family | ||
257 | * @skb: netlink message as socket buffer | 296 | * @skb: netlink message as socket buffer |
258 | * @portid: own netlink portid to avoid sending to yourself | 297 | * @portid: own netlink portid to avoid sending to yourself |
259 | * @group: multicast group id | 298 | * @group: offset of multicast group in groups array |
260 | * @flags: allocation flags | 299 | * @flags: allocation flags |
261 | * | 300 | * |
262 | * This function must hold the RTNL or rcu_read_lock(). | 301 | * This function must hold the RTNL or rcu_read_lock(). |
263 | */ | 302 | */ |
264 | int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, | 303 | int genlmsg_multicast_allns(struct genl_family *family, |
304 | struct sk_buff *skb, u32 portid, | ||
265 | unsigned int group, gfp_t flags); | 305 | unsigned int group, gfp_t flags); |
266 | 306 | ||
267 | /** | 307 | /** |
@@ -332,5 +372,22 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags) | |||
332 | return nlmsg_new(genlmsg_total_size(payload), flags); | 372 | return nlmsg_new(genlmsg_total_size(payload), flags); |
333 | } | 373 | } |
334 | 374 | ||
375 | /** | ||
376 | * genl_set_err - report error to genetlink broadcast listeners | ||
377 | * @family: the generic netlink family | ||
378 | * @net: the network namespace to report the error to | ||
379 | * @portid: the PORTID of a process that we want to skip (if any) | ||
380 | * @group: the broadcast group that will notice the error | ||
381 | * (this is the offset of the multicast group in the groups array) | ||
382 | * @code: error code, must be negative (as usual in kernelspace) | ||
383 | * | ||
384 | * This function returns the number of broadcast listeners that have set the | ||
385 | * NETLINK_RECV_NO_ENOBUFS socket option. | ||
386 | */ | ||
387 | static inline int genl_set_err(struct genl_family *family, struct net *net, | ||
388 | u32 portid, u32 group, int code) | ||
389 | { | ||
390 | return netlink_set_err(net->genl_sock, portid, group, code); | ||
391 | } | ||
335 | 392 | ||
336 | #endif /* __NET_GENERIC_NETLINK_H */ | 393 | #endif /* __NET_GENERIC_NETLINK_H */ |