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