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 | /* Binding to multicast group requires %CAP_NET_ADMIN */ |
12 | #define GENL_MCAST_CAP_NET_ADMIN BIT(0) |
13 | /* Binding to multicast group requires %CAP_SYS_ADMIN */ |
14 | #define GENL_MCAST_CAP_SYS_ADMIN BIT(1) |
15 | |
16 | /** |
17 | * struct genl_multicast_group - generic netlink multicast group |
18 | * @name: name of the multicast group, names are per-family |
19 | * @flags: GENL_MCAST_* flags |
20 | */ |
21 | struct genl_multicast_group { |
22 | char name[GENL_NAMSIZ]; |
23 | u8 flags; |
24 | }; |
25 | |
26 | struct genl_split_ops; |
27 | struct genl_info; |
28 | |
29 | /** |
30 | * struct genl_family - generic netlink family |
31 | * @hdrsize: length of user specific header in bytes |
32 | * @name: name of family |
33 | * @version: protocol version |
34 | * @maxattr: maximum number of attributes supported |
35 | * @policy: netlink policy |
36 | * @netnsok: set to true if the family can handle network |
37 | * namespaces and should be presented in all of them |
38 | * @parallel_ops: operations can be called in parallel and aren't |
39 | * synchronized by the core genetlink code |
40 | * @pre_doit: called before an operation's doit callback, it may |
41 | * do additional, common, filtering and return an error |
42 | * @post_doit: called after an operation's doit callback, it may |
43 | * undo operations done by pre_doit, for example release locks |
44 | * @bind: called when family multicast group is added to a netlink socket |
45 | * @unbind: called when family multicast group is removed from a netlink socket |
46 | * @module: pointer to the owning module (set to THIS_MODULE) |
47 | * @mcgrps: multicast groups used by this family |
48 | * @n_mcgrps: number of multicast groups |
49 | * @resv_start_op: first operation for which reserved fields of the header |
50 | * can be validated and policies are required (see below); |
51 | * new families should leave this field at zero |
52 | * @ops: the operations supported by this family |
53 | * @n_ops: number of operations supported by this family |
54 | * @small_ops: the small-struct operations supported by this family |
55 | * @n_small_ops: number of small-struct operations supported by this family |
56 | * @split_ops: the split do/dump form of operation definition |
57 | * @n_split_ops: number of entries in @split_ops, not that with split do/dump |
58 | * ops the number of entries is not the same as number of commands |
59 | * @sock_priv_size: the size of per-socket private memory |
60 | * @sock_priv_init: the per-socket private memory initializer |
61 | * @sock_priv_destroy: the per-socket private memory destructor |
62 | * |
63 | * Attribute policies (the combination of @policy and @maxattr fields) |
64 | * can be attached at the family level or at the operation level. |
65 | * If both are present the per-operation policy takes precedence. |
66 | * For operations before @resv_start_op lack of policy means that the core |
67 | * will perform no attribute parsing or validation. For newer operations |
68 | * if policy is not provided core will reject all TLV attributes. |
69 | */ |
70 | struct genl_family { |
71 | unsigned int hdrsize; |
72 | char name[GENL_NAMSIZ]; |
73 | unsigned int version; |
74 | unsigned int maxattr; |
75 | u8 netnsok:1; |
76 | u8 parallel_ops:1; |
77 | u8 n_ops; |
78 | u8 n_small_ops; |
79 | u8 n_split_ops; |
80 | u8 n_mcgrps; |
81 | u8 resv_start_op; |
82 | const struct nla_policy *policy; |
83 | int (*pre_doit)(const struct genl_split_ops *ops, |
84 | struct sk_buff *skb, |
85 | struct genl_info *info); |
86 | void (*post_doit)(const struct genl_split_ops *ops, |
87 | struct sk_buff *skb, |
88 | struct genl_info *info); |
89 | int (*bind)(int mcgrp); |
90 | void (*unbind)(int mcgrp); |
91 | const struct genl_ops * ops; |
92 | const struct genl_small_ops *small_ops; |
93 | const struct genl_split_ops *split_ops; |
94 | const struct genl_multicast_group *mcgrps; |
95 | struct module *module; |
96 | |
97 | size_t sock_priv_size; |
98 | void (*sock_priv_init)(void *priv); |
99 | void (*sock_priv_destroy)(void *priv); |
100 | |
101 | /* private: internal use only */ |
102 | /* protocol family identifier */ |
103 | int id; |
104 | /* starting number of multicast group IDs in this family */ |
105 | unsigned int mcgrp_offset; |
106 | /* list of per-socket privs */ |
107 | struct xarray *sock_privs; |
108 | }; |
109 | |
110 | /** |
111 | * struct genl_info - receiving information |
112 | * @snd_seq: sending sequence number |
113 | * @snd_portid: netlink portid of sender |
114 | * @family: generic netlink family |
115 | * @nlhdr: netlink message header |
116 | * @genlhdr: generic netlink message header |
117 | * @attrs: netlink attributes |
118 | * @_net: network namespace |
119 | * @user_ptr: user pointers |
120 | * @extack: extended ACK report struct |
121 | */ |
122 | struct genl_info { |
123 | u32 snd_seq; |
124 | u32 snd_portid; |
125 | const struct genl_family *family; |
126 | const struct nlmsghdr * nlhdr; |
127 | struct genlmsghdr * genlhdr; |
128 | struct nlattr ** attrs; |
129 | possible_net_t _net; |
130 | void * user_ptr[2]; |
131 | struct netlink_ext_ack *extack; |
132 | }; |
133 | |
134 | static inline struct net *genl_info_net(const struct genl_info *info) |
135 | { |
136 | return read_pnet(pnet: &info->_net); |
137 | } |
138 | |
139 | static inline void genl_info_net_set(struct genl_info *info, struct net *net) |
140 | { |
141 | write_pnet(pnet: &info->_net, net); |
142 | } |
143 | |
144 | static inline void *genl_info_userhdr(const struct genl_info *info) |
145 | { |
146 | return (u8 *)info->genlhdr + GENL_HDRLEN; |
147 | } |
148 | |
149 | #define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg) |
150 | |
151 | #define GENL_SET_ERR_MSG_FMT(info, msg, args...) \ |
152 | NL_SET_ERR_MSG_FMT((info)->extack, msg, ##args) |
153 | |
154 | /* Report that a root attribute is missing */ |
155 | #define GENL_REQ_ATTR_CHECK(info, attr) ({ \ |
156 | const struct genl_info *__info = (info); \ |
157 | \ |
158 | NL_REQ_ATTR_CHECK(__info->extack, NULL, __info->attrs, (attr)); \ |
159 | }) |
160 | |
161 | enum genl_validate_flags { |
162 | GENL_DONT_VALIDATE_STRICT = BIT(0), |
163 | GENL_DONT_VALIDATE_DUMP = BIT(1), |
164 | GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2), |
165 | }; |
166 | |
167 | /** |
168 | * struct genl_small_ops - generic netlink operations (small version) |
169 | * @cmd: command identifier |
170 | * @internal_flags: flags used by the family |
171 | * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM) |
172 | * @validate: validation flags from enum genl_validate_flags |
173 | * @doit: standard command callback |
174 | * @dumpit: callback for dumpers |
175 | * |
176 | * This is a cut-down version of struct genl_ops for users who don't need |
177 | * most of the ancillary infra and want to save space. |
178 | */ |
179 | struct genl_small_ops { |
180 | int (*doit)(struct sk_buff *skb, struct genl_info *info); |
181 | int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); |
182 | u8 cmd; |
183 | u8 internal_flags; |
184 | u8 flags; |
185 | u8 validate; |
186 | }; |
187 | |
188 | /** |
189 | * struct genl_ops - generic netlink operations |
190 | * @cmd: command identifier |
191 | * @internal_flags: flags used by the family |
192 | * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM) |
193 | * @maxattr: maximum number of attributes supported |
194 | * @policy: netlink policy (takes precedence over family policy) |
195 | * @validate: validation flags from enum genl_validate_flags |
196 | * @doit: standard command callback |
197 | * @start: start callback for dumps |
198 | * @dumpit: callback for dumpers |
199 | * @done: completion callback for dumps |
200 | */ |
201 | struct genl_ops { |
202 | int (*doit)(struct sk_buff *skb, |
203 | struct genl_info *info); |
204 | int (*start)(struct netlink_callback *cb); |
205 | int (*dumpit)(struct sk_buff *skb, |
206 | struct netlink_callback *cb); |
207 | int (*done)(struct netlink_callback *cb); |
208 | const struct nla_policy *policy; |
209 | unsigned int maxattr; |
210 | u8 cmd; |
211 | u8 internal_flags; |
212 | u8 flags; |
213 | u8 validate; |
214 | }; |
215 | |
216 | /** |
217 | * struct genl_split_ops - generic netlink operations (do/dump split version) |
218 | * @cmd: command identifier |
219 | * @internal_flags: flags used by the family |
220 | * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM) |
221 | * @validate: validation flags from enum genl_validate_flags |
222 | * @policy: netlink policy (takes precedence over family policy) |
223 | * @maxattr: maximum number of attributes supported |
224 | * |
225 | * Do callbacks: |
226 | * @pre_doit: called before an operation's @doit callback, it may |
227 | * do additional, common, filtering and return an error |
228 | * @doit: standard command callback |
229 | * @post_doit: called after an operation's @doit callback, it may |
230 | * undo operations done by pre_doit, for example release locks |
231 | * |
232 | * Dump callbacks: |
233 | * @start: start callback for dumps |
234 | * @dumpit: callback for dumpers |
235 | * @done: completion callback for dumps |
236 | * |
237 | * Do callbacks can be used if %GENL_CMD_CAP_DO is set in @flags. |
238 | * Dump callbacks can be used if %GENL_CMD_CAP_DUMP is set in @flags. |
239 | * Exactly one of those flags must be set. |
240 | */ |
241 | struct genl_split_ops { |
242 | union { |
243 | struct { |
244 | int (*pre_doit)(const struct genl_split_ops *ops, |
245 | struct sk_buff *skb, |
246 | struct genl_info *info); |
247 | int (*doit)(struct sk_buff *skb, |
248 | struct genl_info *info); |
249 | void (*post_doit)(const struct genl_split_ops *ops, |
250 | struct sk_buff *skb, |
251 | struct genl_info *info); |
252 | }; |
253 | struct { |
254 | int (*start)(struct netlink_callback *cb); |
255 | int (*dumpit)(struct sk_buff *skb, |
256 | struct netlink_callback *cb); |
257 | int (*done)(struct netlink_callback *cb); |
258 | }; |
259 | }; |
260 | const struct nla_policy *policy; |
261 | unsigned int maxattr; |
262 | u8 cmd; |
263 | u8 internal_flags; |
264 | u8 flags; |
265 | u8 validate; |
266 | }; |
267 | |
268 | /** |
269 | * struct genl_dumpit_info - info that is available during dumpit op call |
270 | * @op: generic netlink ops - for internal genl code usage |
271 | * @attrs: netlink attributes |
272 | * @info: struct genl_info describing the request |
273 | */ |
274 | struct genl_dumpit_info { |
275 | struct genl_split_ops op; |
276 | struct genl_info info; |
277 | }; |
278 | |
279 | static inline const struct genl_dumpit_info * |
280 | genl_dumpit_info(struct netlink_callback *cb) |
281 | { |
282 | return cb->data; |
283 | } |
284 | |
285 | static inline const struct genl_info * |
286 | genl_info_dump(struct netlink_callback *cb) |
287 | { |
288 | return &genl_dumpit_info(cb)->info; |
289 | } |
290 | |
291 | /** |
292 | * genl_info_init_ntf() - initialize genl_info for notifications |
293 | * @info: genl_info struct to set up |
294 | * @family: pointer to the genetlink family |
295 | * @cmd: command to be used in the notification |
296 | * |
297 | * Initialize a locally declared struct genl_info to pass to various APIs. |
298 | * Intended to be used when creating notifications. |
299 | */ |
300 | static inline void |
301 | genl_info_init_ntf(struct genl_info *info, const struct genl_family *family, |
302 | u8 cmd) |
303 | { |
304 | struct genlmsghdr *hdr = (void *) &info->user_ptr[0]; |
305 | |
306 | memset(info, 0, sizeof(*info)); |
307 | info->family = family; |
308 | info->genlhdr = hdr; |
309 | hdr->cmd = cmd; |
310 | } |
311 | |
312 | static inline bool genl_info_is_ntf(const struct genl_info *info) |
313 | { |
314 | return !info->nlhdr; |
315 | } |
316 | |
317 | void *__genl_sk_priv_get(struct genl_family *family, struct sock *sk); |
318 | void *genl_sk_priv_get(struct genl_family *family, struct sock *sk); |
319 | int genl_register_family(struct genl_family *family); |
320 | int genl_unregister_family(const struct genl_family *family); |
321 | void genl_notify(const struct genl_family *family, struct sk_buff *skb, |
322 | struct genl_info *info, u32 group, gfp_t flags); |
323 | |
324 | void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, |
325 | const struct genl_family *family, int flags, u8 cmd); |
326 | |
327 | static inline void * |
328 | __genlmsg_iput(struct sk_buff *skb, const struct genl_info *info, int flags) |
329 | { |
330 | return genlmsg_put(skb, portid: info->snd_portid, seq: info->snd_seq, family: info->family, |
331 | flags, cmd: info->genlhdr->cmd); |
332 | } |
333 | |
334 | /** |
335 | * genlmsg_iput - start genetlink message based on genl_info |
336 | * @skb: skb in which message header will be placed |
337 | * @info: genl_info as provided to do/dump handlers |
338 | * |
339 | * Convenience wrapper which starts a genetlink message based on |
340 | * information in user request. @info should be either the struct passed |
341 | * by genetlink core to do/dump handlers (when constructing replies to |
342 | * such requests) or a struct initialized by genl_info_init_ntf() |
343 | * when constructing notifications. |
344 | * |
345 | * Returns pointer to new genetlink header. |
346 | */ |
347 | static inline void * |
348 | genlmsg_iput(struct sk_buff *skb, const struct genl_info *info) |
349 | { |
350 | return __genlmsg_iput(skb, info, flags: 0); |
351 | } |
352 | |
353 | /** |
354 | * genlmsg_nlhdr - Obtain netlink header from user specified header |
355 | * @user_hdr: user header as returned from genlmsg_put() |
356 | * |
357 | * Returns pointer to netlink header. |
358 | */ |
359 | static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr) |
360 | { |
361 | return (struct nlmsghdr *)((char *)user_hdr - |
362 | GENL_HDRLEN - |
363 | NLMSG_HDRLEN); |
364 | } |
365 | |
366 | /** |
367 | * genlmsg_parse_deprecated - parse attributes of a genetlink message |
368 | * @nlh: netlink message header |
369 | * @family: genetlink message family |
370 | * @tb: destination array with maxtype+1 elements |
371 | * @maxtype: maximum attribute type to be expected |
372 | * @policy: validation policy |
373 | * @extack: extended ACK report struct |
374 | */ |
375 | static inline int genlmsg_parse_deprecated(const struct nlmsghdr *nlh, |
376 | const struct genl_family *family, |
377 | struct nlattr *tb[], int maxtype, |
378 | const struct nla_policy *policy, |
379 | struct netlink_ext_ack *extack) |
380 | { |
381 | return __nlmsg_parse(nlh, hdrlen: family->hdrsize + GENL_HDRLEN, tb, maxtype, |
382 | policy, validate: NL_VALIDATE_LIBERAL, extack); |
383 | } |
384 | |
385 | /** |
386 | * genlmsg_parse - parse attributes of a genetlink message |
387 | * @nlh: netlink message header |
388 | * @family: genetlink message family |
389 | * @tb: destination array with maxtype+1 elements |
390 | * @maxtype: maximum attribute type to be expected |
391 | * @policy: validation policy |
392 | * @extack: extended ACK report struct |
393 | */ |
394 | static inline int genlmsg_parse(const struct nlmsghdr *nlh, |
395 | const struct genl_family *family, |
396 | struct nlattr *tb[], int maxtype, |
397 | const struct nla_policy *policy, |
398 | struct netlink_ext_ack *extack) |
399 | { |
400 | return __nlmsg_parse(nlh, hdrlen: family->hdrsize + GENL_HDRLEN, tb, maxtype, |
401 | policy, NL_VALIDATE_STRICT, extack); |
402 | } |
403 | |
404 | /** |
405 | * genl_dump_check_consistent - check if sequence is consistent and advertise if not |
406 | * @cb: netlink callback structure that stores the sequence number |
407 | * @user_hdr: user header as returned from genlmsg_put() |
408 | * |
409 | * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it |
410 | * simpler to use with generic netlink. |
411 | */ |
412 | static inline void genl_dump_check_consistent(struct netlink_callback *cb, |
413 | void *user_hdr) |
414 | { |
415 | nl_dump_check_consistent(cb, nlh: genlmsg_nlhdr(user_hdr)); |
416 | } |
417 | |
418 | /** |
419 | * genlmsg_put_reply - Add generic netlink header to a reply message |
420 | * @skb: socket buffer holding the message |
421 | * @info: receiver info |
422 | * @family: generic netlink family |
423 | * @flags: netlink message flags |
424 | * @cmd: generic netlink command |
425 | * |
426 | * Returns pointer to user specific header |
427 | */ |
428 | static inline void *genlmsg_put_reply(struct sk_buff *skb, |
429 | struct genl_info *info, |
430 | const struct genl_family *family, |
431 | int flags, u8 cmd) |
432 | { |
433 | return genlmsg_put(skb, portid: info->snd_portid, seq: info->snd_seq, family, |
434 | flags, cmd); |
435 | } |
436 | |
437 | /** |
438 | * genlmsg_end - Finalize a generic netlink message |
439 | * @skb: socket buffer the message is stored in |
440 | * @hdr: user specific header |
441 | */ |
442 | static inline void genlmsg_end(struct sk_buff *skb, void *hdr) |
443 | { |
444 | nlmsg_end(skb, nlh: hdr - GENL_HDRLEN - NLMSG_HDRLEN); |
445 | } |
446 | |
447 | /** |
448 | * genlmsg_cancel - Cancel construction of a generic netlink message |
449 | * @skb: socket buffer the message is stored in |
450 | * @hdr: generic netlink message header |
451 | */ |
452 | static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr) |
453 | { |
454 | if (hdr) |
455 | nlmsg_cancel(skb, nlh: hdr - GENL_HDRLEN - NLMSG_HDRLEN); |
456 | } |
457 | |
458 | /** |
459 | * genlmsg_multicast_netns_filtered - multicast a netlink message |
460 | * to a specific netns with filter |
461 | * function |
462 | * @family: the generic netlink family |
463 | * @net: the net namespace |
464 | * @skb: netlink message as socket buffer |
465 | * @portid: own netlink portid to avoid sending to yourself |
466 | * @group: offset of multicast group in groups array |
467 | * @flags: allocation flags |
468 | * @filter: filter function |
469 | * @filter_data: filter function private data |
470 | * |
471 | * Return: 0 on success, negative error code for failure. |
472 | */ |
473 | static inline int |
474 | genlmsg_multicast_netns_filtered(const struct genl_family *family, |
475 | struct net *net, struct sk_buff *skb, |
476 | u32 portid, unsigned int group, gfp_t flags, |
477 | netlink_filter_fn filter, |
478 | void *filter_data) |
479 | { |
480 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) |
481 | return -EINVAL; |
482 | group = family->mcgrp_offset + group; |
483 | return nlmsg_multicast_filtered(sk: net->genl_sock, skb, portid, group, |
484 | flags, filter, filter_data); |
485 | } |
486 | |
487 | /** |
488 | * genlmsg_multicast_netns - multicast a netlink message to a specific netns |
489 | * @family: the generic netlink family |
490 | * @net: the net namespace |
491 | * @skb: netlink message as socket buffer |
492 | * @portid: own netlink portid to avoid sending to yourself |
493 | * @group: offset of multicast group in groups array |
494 | * @flags: allocation flags |
495 | */ |
496 | static inline int genlmsg_multicast_netns(const struct genl_family *family, |
497 | struct net *net, struct sk_buff *skb, |
498 | u32 portid, unsigned int group, gfp_t flags) |
499 | { |
500 | return genlmsg_multicast_netns_filtered(family, net, skb, portid, |
501 | group, flags, NULL, NULL); |
502 | } |
503 | |
504 | /** |
505 | * genlmsg_multicast - multicast a netlink message to the default netns |
506 | * @family: the generic netlink family |
507 | * @skb: netlink message as socket buffer |
508 | * @portid: own netlink portid to avoid sending to yourself |
509 | * @group: offset of multicast group in groups array |
510 | * @flags: allocation flags |
511 | */ |
512 | static inline int genlmsg_multicast(const struct genl_family *family, |
513 | struct sk_buff *skb, u32 portid, |
514 | unsigned int group, gfp_t flags) |
515 | { |
516 | return genlmsg_multicast_netns(family, net: &init_net, skb, |
517 | portid, group, flags); |
518 | } |
519 | |
520 | /** |
521 | * genlmsg_multicast_allns - multicast a netlink message to all net namespaces |
522 | * @family: the generic netlink family |
523 | * @skb: netlink message as socket buffer |
524 | * @portid: own netlink portid to avoid sending to yourself |
525 | * @group: offset of multicast group in groups array |
526 | * @flags: allocation flags |
527 | * |
528 | * This function must hold the RTNL or rcu_read_lock(). |
529 | */ |
530 | int genlmsg_multicast_allns(const struct genl_family *family, |
531 | struct sk_buff *skb, u32 portid, |
532 | unsigned int group, gfp_t flags); |
533 | |
534 | /** |
535 | * genlmsg_unicast - unicast a netlink message |
536 | * @net: network namespace to look up @portid in |
537 | * @skb: netlink message as socket buffer |
538 | * @portid: netlink portid of the destination socket |
539 | */ |
540 | static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid) |
541 | { |
542 | return nlmsg_unicast(sk: net->genl_sock, skb, portid); |
543 | } |
544 | |
545 | /** |
546 | * genlmsg_reply - reply to a request |
547 | * @skb: netlink message to be sent back |
548 | * @info: receiver information |
549 | */ |
550 | static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) |
551 | { |
552 | return genlmsg_unicast(net: genl_info_net(info), skb, portid: info->snd_portid); |
553 | } |
554 | |
555 | /** |
556 | * genlmsg_data - head of message payload |
557 | * @gnlh: genetlink message header |
558 | */ |
559 | static inline void *genlmsg_data(const struct genlmsghdr *gnlh) |
560 | { |
561 | return ((unsigned char *) gnlh + GENL_HDRLEN); |
562 | } |
563 | |
564 | /** |
565 | * genlmsg_len - length of message payload |
566 | * @gnlh: genetlink message header |
567 | */ |
568 | static inline int genlmsg_len(const struct genlmsghdr *gnlh) |
569 | { |
570 | struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh - |
571 | NLMSG_HDRLEN); |
572 | return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN); |
573 | } |
574 | |
575 | /** |
576 | * genlmsg_msg_size - length of genetlink message not including padding |
577 | * @payload: length of message payload |
578 | */ |
579 | static inline int genlmsg_msg_size(int payload) |
580 | { |
581 | return GENL_HDRLEN + payload; |
582 | } |
583 | |
584 | /** |
585 | * genlmsg_total_size - length of genetlink message including padding |
586 | * @payload: length of message payload |
587 | */ |
588 | static inline int genlmsg_total_size(int payload) |
589 | { |
590 | return NLMSG_ALIGN(genlmsg_msg_size(payload)); |
591 | } |
592 | |
593 | /** |
594 | * genlmsg_new - Allocate a new generic netlink message |
595 | * @payload: size of the message payload |
596 | * @flags: the type of memory to allocate. |
597 | */ |
598 | static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags) |
599 | { |
600 | return nlmsg_new(payload: genlmsg_total_size(payload), flags); |
601 | } |
602 | |
603 | /** |
604 | * genl_set_err - report error to genetlink broadcast listeners |
605 | * @family: the generic netlink family |
606 | * @net: the network namespace to report the error to |
607 | * @portid: the PORTID of a process that we want to skip (if any) |
608 | * @group: the broadcast group that will notice the error |
609 | * (this is the offset of the multicast group in the groups array) |
610 | * @code: error code, must be negative (as usual in kernelspace) |
611 | * |
612 | * This function returns the number of broadcast listeners that have set the |
613 | * NETLINK_RECV_NO_ENOBUFS socket option. |
614 | */ |
615 | static inline int genl_set_err(const struct genl_family *family, |
616 | struct net *net, u32 portid, |
617 | u32 group, int code) |
618 | { |
619 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) |
620 | return -EINVAL; |
621 | group = family->mcgrp_offset + group; |
622 | return netlink_set_err(ssk: net->genl_sock, portid, group, code); |
623 | } |
624 | |
625 | static inline int genl_has_listeners(const struct genl_family *family, |
626 | struct net *net, unsigned int group) |
627 | { |
628 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) |
629 | return -EINVAL; |
630 | group = family->mcgrp_offset + group; |
631 | return netlink_has_listeners(sk: net->genl_sock, group); |
632 | } |
633 | #endif /* __NET_GENERIC_NETLINK_H */ |
634 | |