Branch data Line data Source code
1 : : #ifndef __NET_GENERIC_NETLINK_H
2 : : #define __NET_GENERIC_NETLINK_H
3 : :
4 : : #include <linux/genetlink.h>
5 : : #include <net/netlink.h>
6 : : #include <net/net_namespace.h>
7 : :
8 : : #define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
9 : :
10 : : /**
11 : : * struct genl_multicast_group - generic netlink multicast group
12 : : * @name: name of the multicast group, names are per-family
13 : : */
14 : : struct genl_multicast_group {
15 : : char name[GENL_NAMSIZ];
16 : : };
17 : :
18 : : struct genl_ops;
19 : : struct genl_info;
20 : :
21 : : /**
22 : : * struct genl_family - generic netlink family
23 : : * @id: protocol family idenfitier
24 : : * @hdrsize: length of user specific header in bytes
25 : : * @name: name of family
26 : : * @version: protocol version
27 : : * @maxattr: maximum number of attributes supported
28 : : * @netnsok: set to true if the family can handle network
29 : : * namespaces and should be presented in all of them
30 : : * @pre_doit: called before an operation's doit callback, it may
31 : : * do additional, common, filtering and return an error
32 : : * @post_doit: called after an operation's doit callback, it may
33 : : * undo operations done by pre_doit, for example release locks
34 : : * @attrbuf: buffer to store parsed attributes
35 : : * @family_list: family 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)
41 : : */
42 : : struct genl_family {
43 : : unsigned int id;
44 : : unsigned int hdrsize;
45 : : char name[GENL_NAMSIZ];
46 : : unsigned int version;
47 : : unsigned int maxattr;
48 : : bool netnsok;
49 : : bool parallel_ops;
50 : : int (*pre_doit)(const struct genl_ops *ops,
51 : : struct sk_buff *skb,
52 : : struct genl_info *info);
53 : : void (*post_doit)(const struct genl_ops *ops,
54 : : struct sk_buff *skb,
55 : : struct genl_info *info);
56 : : struct nlattr ** attrbuf; /* 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 */
63 : : struct module *module;
64 : : };
65 : :
66 : : /**
67 : : * struct genl_info - receiving information
68 : : * @snd_seq: sending sequence number
69 : : * @snd_portid: netlink portid of sender
70 : : * @nlhdr: netlink message header
71 : : * @genlhdr: generic netlink message header
72 : : * @userhdr: user specific header
73 : : * @attrs: netlink attributes
74 : : * @_net: network namespace
75 : : * @user_ptr: user pointers
76 : : */
77 : : struct genl_info {
78 : : u32 snd_seq;
79 : : u32 snd_portid;
80 : : struct nlmsghdr * nlhdr;
81 : : struct genlmsghdr * genlhdr;
82 : : void * userhdr;
83 : : struct nlattr ** attrs;
84 : : #ifdef CONFIG_NET_NS
85 : : struct net * _net;
86 : : #endif
87 : : void * user_ptr[2];
88 : : };
89 : :
90 : : static inline struct net *genl_info_net(struct genl_info *info)
91 : : {
92 : : return read_pnet(&info->_net);
93 : : }
94 : :
95 : : static inline void genl_info_net_set(struct genl_info *info, struct net *net)
96 : : {
97 : : write_pnet(&info->_net, net);
98 : : }
99 : :
100 : : /**
101 : : * struct genl_ops - generic netlink operations
102 : : * @cmd: command identifier
103 : : * @internal_flags: flags used by the family
104 : : * @flags: flags
105 : : * @policy: attribute validation policy
106 : : * @doit: standard command callback
107 : : * @dumpit: callback for dumpers
108 : : * @done: completion callback for dumps
109 : : * @ops_list: operations list
110 : : */
111 : : struct genl_ops {
112 : : const struct nla_policy *policy;
113 : : int (*doit)(struct sk_buff *skb,
114 : : struct genl_info *info);
115 : : int (*dumpit)(struct sk_buff *skb,
116 : : struct netlink_callback *cb);
117 : : int (*done)(struct netlink_callback *cb);
118 : : u8 cmd;
119 : : u8 internal_flags;
120 : : u8 flags;
121 : : };
122 : :
123 : : int __genl_register_family(struct genl_family *family);
124 : :
125 : : static inline int genl_register_family(struct genl_family *family)
126 : : {
127 : : family->module = THIS_MODULE;
128 : : return __genl_register_family(family);
129 : : }
130 : :
131 : : /**
132 : : * genl_register_family_with_ops - register a generic netlink family with ops
133 : : * @family: generic netlink family
134 : : * @ops: operations to be registered
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)
157 : : {
158 : 0 : family->module = THIS_MODULE;
159 : 0 : family->ops = ops;
160 : 0 : family->n_ops = n_ops;
161 : 0 : family->mcgrps = mcgrps;
162 : 0 : family->n_mcgrps = n_mcgrps;
163 : 0 : return __genl_register_family(family);
164 : : }
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 : :
175 : : int genl_unregister_family(struct genl_family *family);
176 : : void genl_notify(struct genl_family *family,
177 : : struct sk_buff *skb, struct net *net, u32 portid,
178 : : u32 group, struct nlmsghdr *nlh, gfp_t flags);
179 : :
180 : : void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
181 : : struct genl_family *family, int flags, u8 cmd);
182 : :
183 : : /**
184 : : * genlmsg_nlhdr - Obtain netlink header from user specified header
185 : : * @user_hdr: user header as returned from genlmsg_put()
186 : : * @family: generic netlink family
187 : : *
188 : : * Returns pointer to netlink header.
189 : : */
190 : : static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr,
191 : : struct genl_family *family)
192 : : {
193 : : return (struct nlmsghdr *)((char *)user_hdr -
194 : : family->hdrsize -
195 : : GENL_HDRLEN -
196 : : NLMSG_HDRLEN);
197 : : }
198 : :
199 : : /**
200 : : * genl_dump_check_consistent - check if sequence is consistent and advertise if not
201 : : * @cb: netlink callback structure that stores the sequence number
202 : : * @user_hdr: user header as returned from genlmsg_put()
203 : : * @family: generic netlink family
204 : : *
205 : : * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it
206 : : * simpler to use with generic netlink.
207 : : */
208 : : static inline void genl_dump_check_consistent(struct netlink_callback *cb,
209 : : void *user_hdr,
210 : : struct genl_family *family)
211 : : {
212 : : nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr, family));
213 : : }
214 : :
215 : : /**
216 : : * genlmsg_put_reply - Add generic netlink header to a reply message
217 : : * @skb: socket buffer holding the message
218 : : * @info: receiver info
219 : : * @family: generic netlink family
220 : : * @flags: netlink message flags
221 : : * @cmd: generic netlink command
222 : : *
223 : : * Returns pointer to user specific header
224 : : */
225 : : static inline void *genlmsg_put_reply(struct sk_buff *skb,
226 : : struct genl_info *info,
227 : : struct genl_family *family,
228 : : int flags, u8 cmd)
229 : : {
230 : 0 : return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
231 : : flags, cmd);
232 : : }
233 : :
234 : : /**
235 : : * genlmsg_end - Finalize a generic netlink message
236 : : * @skb: socket buffer the message is stored in
237 : : * @hdr: user specific header
238 : : */
239 : : static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
240 : : {
241 : 0 : return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
242 : : }
243 : :
244 : : /**
245 : : * genlmsg_cancel - Cancel construction of a generic netlink message
246 : : * @skb: socket buffer the message is stored in
247 : : * @hdr: generic netlink message header
248 : : */
249 : : static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
250 : : {
251 [ # # ][ # # ]: 0 : if (hdr)
252 : 0 : nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
253 : : }
254 : :
255 : : /**
256 : : * genlmsg_multicast_netns - multicast a netlink message to a specific netns
257 : : * @family: the generic netlink family
258 : : * @net: the net namespace
259 : : * @skb: netlink message as socket buffer
260 : : * @portid: own netlink portid to avoid sending to yourself
261 : : * @group: offset of multicast group in groups array
262 : : * @flags: allocation flags
263 : : */
264 : : static inline int genlmsg_multicast_netns(struct genl_family *family,
265 : : struct net *net, struct sk_buff *skb,
266 : : u32 portid, unsigned int group, gfp_t flags)
267 : : {
268 [ # # ][ # # ]: 0 : if (WARN_ON_ONCE(group >= family->n_mcgrps))
[ # # ][ # # ]
269 : : return -EINVAL;
270 : 0 : group = family->mcgrp_offset + group;
271 : 0 : return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
272 : : }
273 : :
274 : : /**
275 : : * genlmsg_multicast - multicast a netlink message to the default netns
276 : : * @family: the generic netlink family
277 : : * @skb: netlink message as socket buffer
278 : : * @portid: own netlink portid to avoid sending to yourself
279 : : * @group: offset of multicast group in groups array
280 : : * @flags: allocation flags
281 : : */
282 : : static inline int genlmsg_multicast(struct genl_family *family,
283 : : struct sk_buff *skb, u32 portid,
284 : : unsigned int group, gfp_t flags)
285 : : {
286 : : return genlmsg_multicast_netns(family, &init_net, skb,
287 : : portid, group, flags);
288 : : }
289 : :
290 : : /**
291 : : * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
292 : : * @family: the generic netlink family
293 : : * @skb: netlink message as socket buffer
294 : : * @portid: own netlink portid to avoid sending to yourself
295 : : * @group: offset of multicast group in groups array
296 : : * @flags: allocation flags
297 : : *
298 : : * This function must hold the RTNL or rcu_read_lock().
299 : : */
300 : : int genlmsg_multicast_allns(struct genl_family *family,
301 : : struct sk_buff *skb, u32 portid,
302 : : unsigned int group, gfp_t flags);
303 : :
304 : : /**
305 : : * genlmsg_unicast - unicast a netlink message
306 : : * @skb: netlink message as socket buffer
307 : : * @portid: netlink portid of the destination socket
308 : : */
309 : : static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
310 : : {
311 : : return nlmsg_unicast(net->genl_sock, skb, portid);
312 : : }
313 : :
314 : : /**
315 : : * genlmsg_reply - reply to a request
316 : : * @skb: netlink message to be sent back
317 : : * @info: receiver information
318 : : */
319 : : static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
320 : : {
321 : 0 : return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
322 : : }
323 : :
324 : : /**
325 : : * gennlmsg_data - head of message payload
326 : : * @gnlh: genetlink message header
327 : : */
328 : : static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
329 : : {
330 : : return ((unsigned char *) gnlh + GENL_HDRLEN);
331 : : }
332 : :
333 : : /**
334 : : * genlmsg_len - length of message payload
335 : : * @gnlh: genetlink message header
336 : : */
337 : : static inline int genlmsg_len(const struct genlmsghdr *gnlh)
338 : : {
339 : : struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
340 : : NLMSG_HDRLEN);
341 : : return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
342 : : }
343 : :
344 : : /**
345 : : * genlmsg_msg_size - length of genetlink message not including padding
346 : : * @payload: length of message payload
347 : : */
348 : : static inline int genlmsg_msg_size(int payload)
349 : : {
350 : : return GENL_HDRLEN + payload;
351 : : }
352 : :
353 : : /**
354 : : * genlmsg_total_size - length of genetlink message including padding
355 : : * @payload: length of message payload
356 : : */
357 : : static inline int genlmsg_total_size(int payload)
358 : : {
359 : : return NLMSG_ALIGN(genlmsg_msg_size(payload));
360 : : }
361 : :
362 : : /**
363 : : * genlmsg_new - Allocate a new generic netlink message
364 : : * @payload: size of the message payload
365 : : * @flags: the type of memory to allocate.
366 : : */
367 : : static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
368 : : {
369 : : return nlmsg_new(genlmsg_total_size(payload), flags);
370 : : }
371 : :
372 : : /**
373 : : * genl_set_err - report error to genetlink broadcast listeners
374 : : * @family: the generic netlink family
375 : : * @net: the network namespace to report the error to
376 : : * @portid: the PORTID of a process that we want to skip (if any)
377 : : * @group: the broadcast group that will notice the error
378 : : * (this is the offset of the multicast group in the groups array)
379 : : * @code: error code, must be negative (as usual in kernelspace)
380 : : *
381 : : * This function returns the number of broadcast listeners that have set the
382 : : * NETLINK_RECV_NO_ENOBUFS socket option.
383 : : */
384 : : static inline int genl_set_err(struct genl_family *family, struct net *net,
385 : : u32 portid, u32 group, int code)
386 : : {
387 : : if (WARN_ON_ONCE(group >= family->n_mcgrps))
388 : : return -EINVAL;
389 : : group = family->mcgrp_offset + group;
390 : : return netlink_set_err(net->genl_sock, portid, group, code);
391 : : }
392 : :
393 : : #endif /* __NET_GENERIC_NETLINK_H */
|