Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef __NET_GENERIC_NETLINK_H
3 : : #define __NET_GENERIC_NETLINK_H
4 : :
5 : : #include <linux/genetlink.h>
6 : : #include <net/netlink.h>
7 : : #include <net/net_namespace.h>
8 : :
9 : : #define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
10 : :
11 : : /**
12 : : * struct genl_multicast_group - generic netlink multicast group
13 : : * @name: name of the multicast group, names are per-family
14 : : */
15 : : struct genl_multicast_group {
16 : : char name[GENL_NAMSIZ];
17 : : };
18 : :
19 : : struct genl_ops;
20 : : struct genl_info;
21 : :
22 : : /**
23 : : * struct genl_family - generic netlink family
24 : : * @id: protocol family identifier (private)
25 : : * @hdrsize: length of user specific header in bytes
26 : : * @name: name of family
27 : : * @version: protocol version
28 : : * @maxattr: maximum number of attributes supported
29 : : * @policy: netlink policy
30 : : * @netnsok: set to true if the family can handle network
31 : : * namespaces and should be presented in all of them
32 : : * @parallel_ops: operations can be called in parallel and aren't
33 : : * synchronized by the core genetlink code
34 : : * @pre_doit: called before an operation's doit callback, it may
35 : : * do additional, common, filtering and return an error
36 : : * @post_doit: called after an operation's doit callback, it may
37 : : * undo operations done by pre_doit, for example release locks
38 : : * @mcast_bind: a socket bound to the given multicast group (which
39 : : * is given as the offset into the groups array)
40 : : * @mcast_unbind: a socket was unbound from the given multicast group.
41 : : * Note that unbind() will not be called symmetrically if the
42 : : * generic netlink family is removed while there are still open
43 : : * sockets.
44 : : * @attrbuf: buffer to store parsed attributes (private)
45 : : * @mcgrps: multicast groups used by this family
46 : : * @n_mcgrps: number of multicast groups
47 : : * @mcgrp_offset: starting number of multicast group IDs in this family
48 : : * (private)
49 : : * @ops: the operations supported by this family
50 : : * @n_ops: number of operations supported by this family
51 : : */
52 : : struct genl_family {
53 : : int id; /* private */
54 : : unsigned int hdrsize;
55 : : char name[GENL_NAMSIZ];
56 : : unsigned int version;
57 : : unsigned int maxattr;
58 : : bool netnsok;
59 : : bool parallel_ops;
60 : : const struct nla_policy *policy;
61 : : int (*pre_doit)(const struct genl_ops *ops,
62 : : struct sk_buff *skb,
63 : : struct genl_info *info);
64 : : void (*post_doit)(const struct genl_ops *ops,
65 : : struct sk_buff *skb,
66 : : struct genl_info *info);
67 : : int (*mcast_bind)(struct net *net, int group);
68 : : void (*mcast_unbind)(struct net *net, int group);
69 : : struct nlattr ** attrbuf; /* private */
70 : : const struct genl_ops * ops;
71 : : const struct genl_multicast_group *mcgrps;
72 : : unsigned int n_ops;
73 : : unsigned int n_mcgrps;
74 : : unsigned int mcgrp_offset; /* private */
75 : : struct module *module;
76 : : };
77 : :
78 : : /**
79 : : * struct genl_info - receiving information
80 : : * @snd_seq: sending sequence number
81 : : * @snd_portid: netlink portid of sender
82 : : * @nlhdr: netlink message header
83 : : * @genlhdr: generic netlink message header
84 : : * @userhdr: user specific header
85 : : * @attrs: netlink attributes
86 : : * @_net: network namespace
87 : : * @user_ptr: user pointers
88 : : * @extack: extended ACK report struct
89 : : */
90 : : struct genl_info {
91 : : u32 snd_seq;
92 : : u32 snd_portid;
93 : : struct nlmsghdr * nlhdr;
94 : : struct genlmsghdr * genlhdr;
95 : : void * userhdr;
96 : : struct nlattr ** attrs;
97 : : possible_net_t _net;
98 : : void * user_ptr[2];
99 : : struct netlink_ext_ack *extack;
100 : : };
101 : :
102 : 0 : static inline struct net *genl_info_net(struct genl_info *info)
103 : : {
104 [ # # # # ]: 0 : return read_pnet(&info->_net);
105 : : }
106 : :
107 : 0 : static inline void genl_info_net_set(struct genl_info *info, struct net *net)
108 : : {
109 [ # # ]: 0 : write_pnet(&info->_net, net);
110 : : }
111 : :
112 : : #define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg)
113 : :
114 : : static inline int genl_err_attr(struct genl_info *info, int err,
115 : : const struct nlattr *attr)
116 : : {
117 : : info->extack->bad_attr = attr;
118 : :
119 : : return err;
120 : : }
121 : :
122 : : enum genl_validate_flags {
123 : : GENL_DONT_VALIDATE_STRICT = BIT(0),
124 : : GENL_DONT_VALIDATE_DUMP = BIT(1),
125 : : GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2),
126 : : };
127 : :
128 : : /**
129 : : * struct genl_info - info that is available during dumpit op call
130 : : * @family: generic netlink family - for internal genl code usage
131 : : * @ops: generic netlink ops - for internal genl code usage
132 : : * @attrs: netlink attributes
133 : : */
134 : : struct genl_dumpit_info {
135 : : const struct genl_family *family;
136 : : const struct genl_ops *ops;
137 : : struct nlattr **attrs;
138 : : };
139 : :
140 : : static inline const struct genl_dumpit_info *
141 : 0 : genl_dumpit_info(struct netlink_callback *cb)
142 : : {
143 [ # # # # : 0 : return cb->data;
# # ]
144 : : }
145 : :
146 : : /**
147 : : * struct genl_ops - generic netlink operations
148 : : * @cmd: command identifier
149 : : * @internal_flags: flags used by the family
150 : : * @flags: flags
151 : : * @doit: standard command callback
152 : : * @start: start callback for dumps
153 : : * @dumpit: callback for dumpers
154 : : * @done: completion callback for dumps
155 : : */
156 : : struct genl_ops {
157 : : int (*doit)(struct sk_buff *skb,
158 : : struct genl_info *info);
159 : : int (*start)(struct netlink_callback *cb);
160 : : int (*dumpit)(struct sk_buff *skb,
161 : : struct netlink_callback *cb);
162 : : int (*done)(struct netlink_callback *cb);
163 : : u8 cmd;
164 : : u8 internal_flags;
165 : : u8 flags;
166 : : u8 validate;
167 : : };
168 : :
169 : : int genl_register_family(struct genl_family *family);
170 : : int genl_unregister_family(const struct genl_family *family);
171 : : void genl_notify(const struct genl_family *family, struct sk_buff *skb,
172 : : struct genl_info *info, u32 group, gfp_t flags);
173 : :
174 : : void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
175 : : const struct genl_family *family, int flags, u8 cmd);
176 : :
177 : : /**
178 : : * genlmsg_nlhdr - Obtain netlink header from user specified header
179 : : * @user_hdr: user header as returned from genlmsg_put()
180 : : *
181 : : * Returns pointer to netlink header.
182 : : */
183 : 0 : static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr)
184 : : {
185 : 0 : return (struct nlmsghdr *)((char *)user_hdr -
186 : : GENL_HDRLEN -
187 : : NLMSG_HDRLEN);
188 : : }
189 : :
190 : : /**
191 : : * genlmsg_parse_deprecated - parse attributes of a genetlink message
192 : : * @nlh: netlink message header
193 : : * @family: genetlink message family
194 : : * @tb: destination array with maxtype+1 elements
195 : : * @maxtype: maximum attribute type to be expected
196 : : * @policy: validation policy
197 : : * @extack: extended ACK report struct
198 : : */
199 : : static inline int genlmsg_parse_deprecated(const struct nlmsghdr *nlh,
200 : : const struct genl_family *family,
201 : : struct nlattr *tb[], int maxtype,
202 : : const struct nla_policy *policy,
203 : : struct netlink_ext_ack *extack)
204 : : {
205 : : return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
206 : : policy, NL_VALIDATE_LIBERAL, extack);
207 : : }
208 : :
209 : : /**
210 : : * genlmsg_parse - parse attributes of a genetlink message
211 : : * @nlh: netlink message header
212 : : * @family: genetlink message family
213 : : * @tb: destination array with maxtype+1 elements
214 : : * @maxtype: maximum attribute type to be expected
215 : : * @policy: validation policy
216 : : * @extack: extended ACK report struct
217 : : */
218 : : static inline int genlmsg_parse(const struct nlmsghdr *nlh,
219 : : const struct genl_family *family,
220 : : struct nlattr *tb[], int maxtype,
221 : : const struct nla_policy *policy,
222 : : struct netlink_ext_ack *extack)
223 : : {
224 : : return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
225 : : policy, NL_VALIDATE_STRICT, extack);
226 : : }
227 : :
228 : : /**
229 : : * genl_dump_check_consistent - check if sequence is consistent and advertise if not
230 : : * @cb: netlink callback structure that stores the sequence number
231 : : * @user_hdr: user header as returned from genlmsg_put()
232 : : *
233 : : * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it
234 : : * simpler to use with generic netlink.
235 : : */
236 : 0 : static inline void genl_dump_check_consistent(struct netlink_callback *cb,
237 : : void *user_hdr)
238 : : {
239 [ # # ]: 0 : nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr));
240 : : }
241 : :
242 : : /**
243 : : * genlmsg_put_reply - Add generic netlink header to a reply message
244 : : * @skb: socket buffer holding the message
245 : : * @info: receiver info
246 : : * @family: generic netlink family
247 : : * @flags: netlink message flags
248 : : * @cmd: generic netlink command
249 : : *
250 : : * Returns pointer to user specific header
251 : : */
252 : 0 : static inline void *genlmsg_put_reply(struct sk_buff *skb,
253 : : struct genl_info *info,
254 : : const struct genl_family *family,
255 : : int flags, u8 cmd)
256 : : {
257 : 0 : return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
258 : : flags, cmd);
259 : : }
260 : :
261 : : /**
262 : : * genlmsg_end - Finalize a generic netlink message
263 : : * @skb: socket buffer the message is stored in
264 : : * @hdr: user specific header
265 : : */
266 : 560 : static inline void genlmsg_end(struct sk_buff *skb, void *hdr)
267 : : {
268 [ # # # # : 560 : nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
# # ]
269 : 0 : }
270 : :
271 : : /**
272 : : * genlmsg_cancel - Cancel construction of a generic netlink message
273 : : * @skb: socket buffer the message is stored in
274 : : * @hdr: generic netlink message header
275 : : */
276 : 0 : static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
277 : : {
278 [ # # ]: 0 : if (hdr)
279 : 0 : nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
280 : 0 : }
281 : :
282 : : /**
283 : : * genlmsg_multicast_netns - multicast a netlink message to a specific netns
284 : : * @family: the generic netlink family
285 : : * @net: the net namespace
286 : : * @skb: netlink message as socket buffer
287 : : * @portid: own netlink portid to avoid sending to yourself
288 : : * @group: offset of multicast group in groups array
289 : : * @flags: allocation flags
290 : : */
291 : : static inline int genlmsg_multicast_netns(const struct genl_family *family,
292 : : struct net *net, struct sk_buff *skb,
293 : : u32 portid, unsigned int group, gfp_t flags)
294 : : {
295 : : if (WARN_ON_ONCE(group >= family->n_mcgrps))
296 : : return -EINVAL;
297 : : group = family->mcgrp_offset + group;
298 : : return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
299 : : }
300 : :
301 : : /**
302 : : * genlmsg_multicast - multicast a netlink message to the default netns
303 : : * @family: the generic netlink family
304 : : * @skb: netlink message as socket buffer
305 : : * @portid: own netlink portid to avoid sending to yourself
306 : : * @group: offset of multicast group in groups array
307 : : * @flags: allocation flags
308 : : */
309 : 0 : static inline int genlmsg_multicast(const struct genl_family *family,
310 : : struct sk_buff *skb, u32 portid,
311 : : unsigned int group, gfp_t flags)
312 : : {
313 : 0 : return genlmsg_multicast_netns(family, &init_net, skb,
314 : : portid, group, flags);
315 : : }
316 : :
317 : : /**
318 : : * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
319 : : * @family: the generic netlink family
320 : : * @skb: netlink message as socket buffer
321 : : * @portid: own netlink portid to avoid sending to yourself
322 : : * @group: offset of multicast group in groups array
323 : : * @flags: allocation flags
324 : : *
325 : : * This function must hold the RTNL or rcu_read_lock().
326 : : */
327 : : int genlmsg_multicast_allns(const struct genl_family *family,
328 : : struct sk_buff *skb, u32 portid,
329 : : unsigned int group, gfp_t flags);
330 : :
331 : : /**
332 : : * genlmsg_unicast - unicast a netlink message
333 : : * @skb: netlink message as socket buffer
334 : : * @portid: netlink portid of the destination socket
335 : : */
336 : 0 : static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
337 : : {
338 : 0 : return nlmsg_unicast(net->genl_sock, skb, portid);
339 : : }
340 : :
341 : : /**
342 : : * genlmsg_reply - reply to a request
343 : : * @skb: netlink message to be sent back
344 : : * @info: receiver information
345 : : */
346 : 0 : static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
347 : : {
348 : 0 : return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
349 : : }
350 : :
351 : : /**
352 : : * gennlmsg_data - head of message payload
353 : : * @gnlh: genetlink message header
354 : : */
355 : 0 : static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
356 : : {
357 : 0 : return ((unsigned char *) gnlh + GENL_HDRLEN);
358 : : }
359 : :
360 : : /**
361 : : * genlmsg_len - length of message payload
362 : : * @gnlh: genetlink message header
363 : : */
364 : : static inline int genlmsg_len(const struct genlmsghdr *gnlh)
365 : : {
366 : : struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
367 : : NLMSG_HDRLEN);
368 : : return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
369 : : }
370 : :
371 : : /**
372 : : * genlmsg_msg_size - length of genetlink message not including padding
373 : : * @payload: length of message payload
374 : : */
375 : 0 : static inline int genlmsg_msg_size(int payload)
376 : : {
377 : 0 : return GENL_HDRLEN + payload;
378 : : }
379 : :
380 : : /**
381 : : * genlmsg_total_size - length of genetlink message including padding
382 : : * @payload: length of message payload
383 : : */
384 : 0 : static inline int genlmsg_total_size(int payload)
385 : : {
386 : 0 : return NLMSG_ALIGN(genlmsg_msg_size(payload));
387 : : }
388 : :
389 : : /**
390 : : * genlmsg_new - Allocate a new generic netlink message
391 : : * @payload: size of the message payload
392 : : * @flags: the type of memory to allocate.
393 : : */
394 : 0 : static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
395 : : {
396 : 0 : return nlmsg_new(genlmsg_total_size(payload), flags);
397 : : }
398 : :
399 : : /**
400 : : * genl_set_err - report error to genetlink broadcast listeners
401 : : * @family: the generic netlink family
402 : : * @net: the network namespace to report the error to
403 : : * @portid: the PORTID of a process that we want to skip (if any)
404 : : * @group: the broadcast group that will notice the error
405 : : * (this is the offset of the multicast group in the groups array)
406 : : * @code: error code, must be negative (as usual in kernelspace)
407 : : *
408 : : * This function returns the number of broadcast listeners that have set the
409 : : * NETLINK_RECV_NO_ENOBUFS socket option.
410 : : */
411 : : static inline int genl_set_err(const struct genl_family *family,
412 : : struct net *net, u32 portid,
413 : : u32 group, int code)
414 : : {
415 : : if (WARN_ON_ONCE(group >= family->n_mcgrps))
416 : : return -EINVAL;
417 : : group = family->mcgrp_offset + group;
418 : : return netlink_set_err(net->genl_sock, portid, group, code);
419 : : }
420 : :
421 : : static inline int genl_has_listeners(const struct genl_family *family,
422 : : struct net *net, unsigned int group)
423 : : {
424 : : if (WARN_ON_ONCE(group >= family->n_mcgrps))
425 : : return -EINVAL;
426 : : group = family->mcgrp_offset + group;
427 : : return netlink_has_listeners(net->genl_sock, group);
428 : : }
429 : : #endif /* __NET_GENERIC_NETLINK_H */
|