18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __NET_GENERIC_NETLINK_H 38c2ecf20Sopenharmony_ci#define __NET_GENERIC_NETLINK_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/genetlink.h> 68c2ecf20Sopenharmony_ci#include <net/netlink.h> 78c2ecf20Sopenharmony_ci#include <net/net_namespace.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN) 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/** 128c2ecf20Sopenharmony_ci * struct genl_multicast_group - generic netlink multicast group 138c2ecf20Sopenharmony_ci * @name: name of the multicast group, names are per-family 148c2ecf20Sopenharmony_ci * @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_cistruct genl_multicast_group { 178c2ecf20Sopenharmony_ci char name[GENL_NAMSIZ]; 188c2ecf20Sopenharmony_ci u8 flags; 198c2ecf20Sopenharmony_ci u8 cap_sys_admin:1; 208c2ecf20Sopenharmony_ci}; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct genl_ops; 238c2ecf20Sopenharmony_cistruct genl_info; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/** 268c2ecf20Sopenharmony_ci * struct genl_family - generic netlink family 278c2ecf20Sopenharmony_ci * @id: protocol family identifier (private) 288c2ecf20Sopenharmony_ci * @hdrsize: length of user specific header in bytes 298c2ecf20Sopenharmony_ci * @name: name of family 308c2ecf20Sopenharmony_ci * @version: protocol version 318c2ecf20Sopenharmony_ci * @maxattr: maximum number of attributes supported 328c2ecf20Sopenharmony_ci * @policy: netlink policy 338c2ecf20Sopenharmony_ci * @netnsok: set to true if the family can handle network 348c2ecf20Sopenharmony_ci * namespaces and should be presented in all of them 358c2ecf20Sopenharmony_ci * @parallel_ops: operations can be called in parallel and aren't 368c2ecf20Sopenharmony_ci * synchronized by the core genetlink code 378c2ecf20Sopenharmony_ci * @pre_doit: called before an operation's doit callback, it may 388c2ecf20Sopenharmony_ci * do additional, common, filtering and return an error 398c2ecf20Sopenharmony_ci * @post_doit: called after an operation's doit callback, it may 408c2ecf20Sopenharmony_ci * undo operations done by pre_doit, for example release locks 418c2ecf20Sopenharmony_ci * @mcgrps: multicast groups used by this family 428c2ecf20Sopenharmony_ci * @n_mcgrps: number of multicast groups 438c2ecf20Sopenharmony_ci * @mcgrp_offset: starting number of multicast group IDs in this family 448c2ecf20Sopenharmony_ci * (private) 458c2ecf20Sopenharmony_ci * @ops: the operations supported by this family 468c2ecf20Sopenharmony_ci * @n_ops: number of operations supported by this family 478c2ecf20Sopenharmony_ci * @small_ops: the small-struct operations supported by this family 488c2ecf20Sopenharmony_ci * @n_small_ops: number of small-struct operations supported by this family 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_cistruct genl_family { 518c2ecf20Sopenharmony_ci int id; /* private */ 528c2ecf20Sopenharmony_ci unsigned int hdrsize; 538c2ecf20Sopenharmony_ci char name[GENL_NAMSIZ]; 548c2ecf20Sopenharmony_ci unsigned int version; 558c2ecf20Sopenharmony_ci unsigned int maxattr; 568c2ecf20Sopenharmony_ci unsigned int mcgrp_offset; /* private */ 578c2ecf20Sopenharmony_ci u8 netnsok:1; 588c2ecf20Sopenharmony_ci u8 parallel_ops:1; 598c2ecf20Sopenharmony_ci u8 n_ops; 608c2ecf20Sopenharmony_ci u8 n_small_ops; 618c2ecf20Sopenharmony_ci u8 n_mcgrps; 628c2ecf20Sopenharmony_ci const struct nla_policy *policy; 638c2ecf20Sopenharmony_ci int (*pre_doit)(const struct genl_ops *ops, 648c2ecf20Sopenharmony_ci struct sk_buff *skb, 658c2ecf20Sopenharmony_ci struct genl_info *info); 668c2ecf20Sopenharmony_ci void (*post_doit)(const struct genl_ops *ops, 678c2ecf20Sopenharmony_ci struct sk_buff *skb, 688c2ecf20Sopenharmony_ci struct genl_info *info); 698c2ecf20Sopenharmony_ci const struct genl_ops * ops; 708c2ecf20Sopenharmony_ci const struct genl_small_ops *small_ops; 718c2ecf20Sopenharmony_ci const struct genl_multicast_group *mcgrps; 728c2ecf20Sopenharmony_ci struct module *module; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci/** 768c2ecf20Sopenharmony_ci * struct genl_info - receiving information 778c2ecf20Sopenharmony_ci * @snd_seq: sending sequence number 788c2ecf20Sopenharmony_ci * @snd_portid: netlink portid of sender 798c2ecf20Sopenharmony_ci * @nlhdr: netlink message header 808c2ecf20Sopenharmony_ci * @genlhdr: generic netlink message header 818c2ecf20Sopenharmony_ci * @userhdr: user specific header 828c2ecf20Sopenharmony_ci * @attrs: netlink attributes 838c2ecf20Sopenharmony_ci * @_net: network namespace 848c2ecf20Sopenharmony_ci * @user_ptr: user pointers 858c2ecf20Sopenharmony_ci * @extack: extended ACK report struct 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_cistruct genl_info { 888c2ecf20Sopenharmony_ci u32 snd_seq; 898c2ecf20Sopenharmony_ci u32 snd_portid; 908c2ecf20Sopenharmony_ci struct nlmsghdr * nlhdr; 918c2ecf20Sopenharmony_ci struct genlmsghdr * genlhdr; 928c2ecf20Sopenharmony_ci void * userhdr; 938c2ecf20Sopenharmony_ci struct nlattr ** attrs; 948c2ecf20Sopenharmony_ci possible_net_t _net; 958c2ecf20Sopenharmony_ci void * user_ptr[2]; 968c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack; 978c2ecf20Sopenharmony_ci}; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic inline struct net *genl_info_net(struct genl_info *info) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci return read_pnet(&info->_net); 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic inline void genl_info_net_set(struct genl_info *info, struct net *net) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci write_pnet(&info->_net, net); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci#define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg) 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cienum genl_validate_flags { 1128c2ecf20Sopenharmony_ci GENL_DONT_VALIDATE_STRICT = BIT(0), 1138c2ecf20Sopenharmony_ci GENL_DONT_VALIDATE_DUMP = BIT(1), 1148c2ecf20Sopenharmony_ci GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2), 1158c2ecf20Sopenharmony_ci}; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/** 1188c2ecf20Sopenharmony_ci * struct genl_small_ops - generic netlink operations (small version) 1198c2ecf20Sopenharmony_ci * @cmd: command identifier 1208c2ecf20Sopenharmony_ci * @internal_flags: flags used by the family 1218c2ecf20Sopenharmony_ci * @flags: flags 1228c2ecf20Sopenharmony_ci * @validate: validation flags from enum genl_validate_flags 1238c2ecf20Sopenharmony_ci * @doit: standard command callback 1248c2ecf20Sopenharmony_ci * @dumpit: callback for dumpers 1258c2ecf20Sopenharmony_ci * 1268c2ecf20Sopenharmony_ci * This is a cut-down version of struct genl_ops for users who don't need 1278c2ecf20Sopenharmony_ci * most of the ancillary infra and want to save space. 1288c2ecf20Sopenharmony_ci */ 1298c2ecf20Sopenharmony_cistruct genl_small_ops { 1308c2ecf20Sopenharmony_ci int (*doit)(struct sk_buff *skb, struct genl_info *info); 1318c2ecf20Sopenharmony_ci int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); 1328c2ecf20Sopenharmony_ci u8 cmd; 1338c2ecf20Sopenharmony_ci u8 internal_flags; 1348c2ecf20Sopenharmony_ci u8 flags; 1358c2ecf20Sopenharmony_ci u8 validate; 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/** 1398c2ecf20Sopenharmony_ci * struct genl_ops - generic netlink operations 1408c2ecf20Sopenharmony_ci * @cmd: command identifier 1418c2ecf20Sopenharmony_ci * @internal_flags: flags used by the family 1428c2ecf20Sopenharmony_ci * @flags: flags 1438c2ecf20Sopenharmony_ci * @maxattr: maximum number of attributes supported 1448c2ecf20Sopenharmony_ci * @policy: netlink policy (takes precedence over family policy) 1458c2ecf20Sopenharmony_ci * @validate: validation flags from enum genl_validate_flags 1468c2ecf20Sopenharmony_ci * @doit: standard command callback 1478c2ecf20Sopenharmony_ci * @start: start callback for dumps 1488c2ecf20Sopenharmony_ci * @dumpit: callback for dumpers 1498c2ecf20Sopenharmony_ci * @done: completion callback for dumps 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_cistruct genl_ops { 1528c2ecf20Sopenharmony_ci int (*doit)(struct sk_buff *skb, 1538c2ecf20Sopenharmony_ci struct genl_info *info); 1548c2ecf20Sopenharmony_ci int (*start)(struct netlink_callback *cb); 1558c2ecf20Sopenharmony_ci int (*dumpit)(struct sk_buff *skb, 1568c2ecf20Sopenharmony_ci struct netlink_callback *cb); 1578c2ecf20Sopenharmony_ci int (*done)(struct netlink_callback *cb); 1588c2ecf20Sopenharmony_ci const struct nla_policy *policy; 1598c2ecf20Sopenharmony_ci unsigned int maxattr; 1608c2ecf20Sopenharmony_ci u8 cmd; 1618c2ecf20Sopenharmony_ci u8 internal_flags; 1628c2ecf20Sopenharmony_ci u8 flags; 1638c2ecf20Sopenharmony_ci u8 validate; 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci/** 1678c2ecf20Sopenharmony_ci * struct genl_info - info that is available during dumpit op call 1688c2ecf20Sopenharmony_ci * @family: generic netlink family - for internal genl code usage 1698c2ecf20Sopenharmony_ci * @ops: generic netlink ops - for internal genl code usage 1708c2ecf20Sopenharmony_ci * @attrs: netlink attributes 1718c2ecf20Sopenharmony_ci */ 1728c2ecf20Sopenharmony_cistruct genl_dumpit_info { 1738c2ecf20Sopenharmony_ci const struct genl_family *family; 1748c2ecf20Sopenharmony_ci struct genl_ops op; 1758c2ecf20Sopenharmony_ci struct nlattr **attrs; 1768c2ecf20Sopenharmony_ci}; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic inline const struct genl_dumpit_info * 1798c2ecf20Sopenharmony_cigenl_dumpit_info(struct netlink_callback *cb) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci return cb->data; 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ciint genl_register_family(struct genl_family *family); 1858c2ecf20Sopenharmony_ciint genl_unregister_family(const struct genl_family *family); 1868c2ecf20Sopenharmony_civoid genl_notify(const struct genl_family *family, struct sk_buff *skb, 1878c2ecf20Sopenharmony_ci struct genl_info *info, u32 group, gfp_t flags); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_civoid *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, 1908c2ecf20Sopenharmony_ci const struct genl_family *family, int flags, u8 cmd); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci/** 1938c2ecf20Sopenharmony_ci * genlmsg_nlhdr - Obtain netlink header from user specified header 1948c2ecf20Sopenharmony_ci * @user_hdr: user header as returned from genlmsg_put() 1958c2ecf20Sopenharmony_ci * 1968c2ecf20Sopenharmony_ci * Returns pointer to netlink header. 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_cistatic inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci return (struct nlmsghdr *)((char *)user_hdr - 2018c2ecf20Sopenharmony_ci GENL_HDRLEN - 2028c2ecf20Sopenharmony_ci NLMSG_HDRLEN); 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci/** 2068c2ecf20Sopenharmony_ci * genlmsg_parse_deprecated - parse attributes of a genetlink message 2078c2ecf20Sopenharmony_ci * @nlh: netlink message header 2088c2ecf20Sopenharmony_ci * @family: genetlink message family 2098c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements 2108c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected 2118c2ecf20Sopenharmony_ci * @policy: validation policy 2128c2ecf20Sopenharmony_ci * @extack: extended ACK report struct 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_cistatic inline int genlmsg_parse_deprecated(const struct nlmsghdr *nlh, 2158c2ecf20Sopenharmony_ci const struct genl_family *family, 2168c2ecf20Sopenharmony_ci struct nlattr *tb[], int maxtype, 2178c2ecf20Sopenharmony_ci const struct nla_policy *policy, 2188c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype, 2218c2ecf20Sopenharmony_ci policy, NL_VALIDATE_LIBERAL, extack); 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/** 2258c2ecf20Sopenharmony_ci * genlmsg_parse - parse attributes of a genetlink message 2268c2ecf20Sopenharmony_ci * @nlh: netlink message header 2278c2ecf20Sopenharmony_ci * @family: genetlink message family 2288c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements 2298c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected 2308c2ecf20Sopenharmony_ci * @policy: validation policy 2318c2ecf20Sopenharmony_ci * @extack: extended ACK report struct 2328c2ecf20Sopenharmony_ci */ 2338c2ecf20Sopenharmony_cistatic inline int genlmsg_parse(const struct nlmsghdr *nlh, 2348c2ecf20Sopenharmony_ci const struct genl_family *family, 2358c2ecf20Sopenharmony_ci struct nlattr *tb[], int maxtype, 2368c2ecf20Sopenharmony_ci const struct nla_policy *policy, 2378c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype, 2408c2ecf20Sopenharmony_ci policy, NL_VALIDATE_STRICT, extack); 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci/** 2448c2ecf20Sopenharmony_ci * genl_dump_check_consistent - check if sequence is consistent and advertise if not 2458c2ecf20Sopenharmony_ci * @cb: netlink callback structure that stores the sequence number 2468c2ecf20Sopenharmony_ci * @user_hdr: user header as returned from genlmsg_put() 2478c2ecf20Sopenharmony_ci * 2488c2ecf20Sopenharmony_ci * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it 2498c2ecf20Sopenharmony_ci * simpler to use with generic netlink. 2508c2ecf20Sopenharmony_ci */ 2518c2ecf20Sopenharmony_cistatic inline void genl_dump_check_consistent(struct netlink_callback *cb, 2528c2ecf20Sopenharmony_ci void *user_hdr) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr)); 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci/** 2588c2ecf20Sopenharmony_ci * genlmsg_put_reply - Add generic netlink header to a reply message 2598c2ecf20Sopenharmony_ci * @skb: socket buffer holding the message 2608c2ecf20Sopenharmony_ci * @info: receiver info 2618c2ecf20Sopenharmony_ci * @family: generic netlink family 2628c2ecf20Sopenharmony_ci * @flags: netlink message flags 2638c2ecf20Sopenharmony_ci * @cmd: generic netlink command 2648c2ecf20Sopenharmony_ci * 2658c2ecf20Sopenharmony_ci * Returns pointer to user specific header 2668c2ecf20Sopenharmony_ci */ 2678c2ecf20Sopenharmony_cistatic inline void *genlmsg_put_reply(struct sk_buff *skb, 2688c2ecf20Sopenharmony_ci struct genl_info *info, 2698c2ecf20Sopenharmony_ci const struct genl_family *family, 2708c2ecf20Sopenharmony_ci int flags, u8 cmd) 2718c2ecf20Sopenharmony_ci{ 2728c2ecf20Sopenharmony_ci return genlmsg_put(skb, info->snd_portid, info->snd_seq, family, 2738c2ecf20Sopenharmony_ci flags, cmd); 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci/** 2778c2ecf20Sopenharmony_ci * genlmsg_end - Finalize a generic netlink message 2788c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in 2798c2ecf20Sopenharmony_ci * @hdr: user specific header 2808c2ecf20Sopenharmony_ci */ 2818c2ecf20Sopenharmony_cistatic inline void genlmsg_end(struct sk_buff *skb, void *hdr) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN); 2848c2ecf20Sopenharmony_ci} 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci/** 2878c2ecf20Sopenharmony_ci * genlmsg_cancel - Cancel construction of a generic netlink message 2888c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in 2898c2ecf20Sopenharmony_ci * @hdr: generic netlink message header 2908c2ecf20Sopenharmony_ci */ 2918c2ecf20Sopenharmony_cistatic inline void genlmsg_cancel(struct sk_buff *skb, void *hdr) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci if (hdr) 2948c2ecf20Sopenharmony_ci nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN); 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci/** 2988c2ecf20Sopenharmony_ci * genlmsg_multicast_netns - multicast a netlink message to a specific netns 2998c2ecf20Sopenharmony_ci * @family: the generic netlink family 3008c2ecf20Sopenharmony_ci * @net: the net namespace 3018c2ecf20Sopenharmony_ci * @skb: netlink message as socket buffer 3028c2ecf20Sopenharmony_ci * @portid: own netlink portid to avoid sending to yourself 3038c2ecf20Sopenharmony_ci * @group: offset of multicast group in groups array 3048c2ecf20Sopenharmony_ci * @flags: allocation flags 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_cistatic inline int genlmsg_multicast_netns(const struct genl_family *family, 3078c2ecf20Sopenharmony_ci struct net *net, struct sk_buff *skb, 3088c2ecf20Sopenharmony_ci u32 portid, unsigned int group, gfp_t flags) 3098c2ecf20Sopenharmony_ci{ 3108c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(group >= family->n_mcgrps)) 3118c2ecf20Sopenharmony_ci return -EINVAL; 3128c2ecf20Sopenharmony_ci group = family->mcgrp_offset + group; 3138c2ecf20Sopenharmony_ci return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); 3148c2ecf20Sopenharmony_ci} 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci/** 3178c2ecf20Sopenharmony_ci * genlmsg_multicast - multicast a netlink message to the default netns 3188c2ecf20Sopenharmony_ci * @family: the generic netlink family 3198c2ecf20Sopenharmony_ci * @skb: netlink message as socket buffer 3208c2ecf20Sopenharmony_ci * @portid: own netlink portid to avoid sending to yourself 3218c2ecf20Sopenharmony_ci * @group: offset of multicast group in groups array 3228c2ecf20Sopenharmony_ci * @flags: allocation flags 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_cistatic inline int genlmsg_multicast(const struct genl_family *family, 3258c2ecf20Sopenharmony_ci struct sk_buff *skb, u32 portid, 3268c2ecf20Sopenharmony_ci unsigned int group, gfp_t flags) 3278c2ecf20Sopenharmony_ci{ 3288c2ecf20Sopenharmony_ci return genlmsg_multicast_netns(family, &init_net, skb, 3298c2ecf20Sopenharmony_ci portid, group, flags); 3308c2ecf20Sopenharmony_ci} 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci/** 3338c2ecf20Sopenharmony_ci * genlmsg_multicast_allns - multicast a netlink message to all net namespaces 3348c2ecf20Sopenharmony_ci * @family: the generic netlink family 3358c2ecf20Sopenharmony_ci * @skb: netlink message as socket buffer 3368c2ecf20Sopenharmony_ci * @portid: own netlink portid to avoid sending to yourself 3378c2ecf20Sopenharmony_ci * @group: offset of multicast group in groups array 3388c2ecf20Sopenharmony_ci * @flags: allocation flags 3398c2ecf20Sopenharmony_ci * 3408c2ecf20Sopenharmony_ci * This function must hold the RTNL or rcu_read_lock(). 3418c2ecf20Sopenharmony_ci */ 3428c2ecf20Sopenharmony_ciint genlmsg_multicast_allns(const struct genl_family *family, 3438c2ecf20Sopenharmony_ci struct sk_buff *skb, u32 portid, 3448c2ecf20Sopenharmony_ci unsigned int group, gfp_t flags); 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci/** 3478c2ecf20Sopenharmony_ci * genlmsg_unicast - unicast a netlink message 3488c2ecf20Sopenharmony_ci * @skb: netlink message as socket buffer 3498c2ecf20Sopenharmony_ci * @portid: netlink portid of the destination socket 3508c2ecf20Sopenharmony_ci */ 3518c2ecf20Sopenharmony_cistatic inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci return nlmsg_unicast(net->genl_sock, skb, portid); 3548c2ecf20Sopenharmony_ci} 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci/** 3578c2ecf20Sopenharmony_ci * genlmsg_reply - reply to a request 3588c2ecf20Sopenharmony_ci * @skb: netlink message to be sent back 3598c2ecf20Sopenharmony_ci * @info: receiver information 3608c2ecf20Sopenharmony_ci */ 3618c2ecf20Sopenharmony_cistatic inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) 3628c2ecf20Sopenharmony_ci{ 3638c2ecf20Sopenharmony_ci return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid); 3648c2ecf20Sopenharmony_ci} 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci/** 3678c2ecf20Sopenharmony_ci * gennlmsg_data - head of message payload 3688c2ecf20Sopenharmony_ci * @gnlh: genetlink message header 3698c2ecf20Sopenharmony_ci */ 3708c2ecf20Sopenharmony_cistatic inline void *genlmsg_data(const struct genlmsghdr *gnlh) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci return ((unsigned char *) gnlh + GENL_HDRLEN); 3738c2ecf20Sopenharmony_ci} 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci/** 3768c2ecf20Sopenharmony_ci * genlmsg_len - length of message payload 3778c2ecf20Sopenharmony_ci * @gnlh: genetlink message header 3788c2ecf20Sopenharmony_ci */ 3798c2ecf20Sopenharmony_cistatic inline int genlmsg_len(const struct genlmsghdr *gnlh) 3808c2ecf20Sopenharmony_ci{ 3818c2ecf20Sopenharmony_ci struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh - 3828c2ecf20Sopenharmony_ci NLMSG_HDRLEN); 3838c2ecf20Sopenharmony_ci return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN); 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci/** 3878c2ecf20Sopenharmony_ci * genlmsg_msg_size - length of genetlink message not including padding 3888c2ecf20Sopenharmony_ci * @payload: length of message payload 3898c2ecf20Sopenharmony_ci */ 3908c2ecf20Sopenharmony_cistatic inline int genlmsg_msg_size(int payload) 3918c2ecf20Sopenharmony_ci{ 3928c2ecf20Sopenharmony_ci return GENL_HDRLEN + payload; 3938c2ecf20Sopenharmony_ci} 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci/** 3968c2ecf20Sopenharmony_ci * genlmsg_total_size - length of genetlink message including padding 3978c2ecf20Sopenharmony_ci * @payload: length of message payload 3988c2ecf20Sopenharmony_ci */ 3998c2ecf20Sopenharmony_cistatic inline int genlmsg_total_size(int payload) 4008c2ecf20Sopenharmony_ci{ 4018c2ecf20Sopenharmony_ci return NLMSG_ALIGN(genlmsg_msg_size(payload)); 4028c2ecf20Sopenharmony_ci} 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci/** 4058c2ecf20Sopenharmony_ci * genlmsg_new - Allocate a new generic netlink message 4068c2ecf20Sopenharmony_ci * @payload: size of the message payload 4078c2ecf20Sopenharmony_ci * @flags: the type of memory to allocate. 4088c2ecf20Sopenharmony_ci */ 4098c2ecf20Sopenharmony_cistatic inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags) 4108c2ecf20Sopenharmony_ci{ 4118c2ecf20Sopenharmony_ci return nlmsg_new(genlmsg_total_size(payload), flags); 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci/** 4158c2ecf20Sopenharmony_ci * genl_set_err - report error to genetlink broadcast listeners 4168c2ecf20Sopenharmony_ci * @family: the generic netlink family 4178c2ecf20Sopenharmony_ci * @net: the network namespace to report the error to 4188c2ecf20Sopenharmony_ci * @portid: the PORTID of a process that we want to skip (if any) 4198c2ecf20Sopenharmony_ci * @group: the broadcast group that will notice the error 4208c2ecf20Sopenharmony_ci * (this is the offset of the multicast group in the groups array) 4218c2ecf20Sopenharmony_ci * @code: error code, must be negative (as usual in kernelspace) 4228c2ecf20Sopenharmony_ci * 4238c2ecf20Sopenharmony_ci * This function returns the number of broadcast listeners that have set the 4248c2ecf20Sopenharmony_ci * NETLINK_RECV_NO_ENOBUFS socket option. 4258c2ecf20Sopenharmony_ci */ 4268c2ecf20Sopenharmony_cistatic inline int genl_set_err(const struct genl_family *family, 4278c2ecf20Sopenharmony_ci struct net *net, u32 portid, 4288c2ecf20Sopenharmony_ci u32 group, int code) 4298c2ecf20Sopenharmony_ci{ 4308c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(group >= family->n_mcgrps)) 4318c2ecf20Sopenharmony_ci return -EINVAL; 4328c2ecf20Sopenharmony_ci group = family->mcgrp_offset + group; 4338c2ecf20Sopenharmony_ci return netlink_set_err(net->genl_sock, portid, group, code); 4348c2ecf20Sopenharmony_ci} 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_cistatic inline int genl_has_listeners(const struct genl_family *family, 4378c2ecf20Sopenharmony_ci struct net *net, unsigned int group) 4388c2ecf20Sopenharmony_ci{ 4398c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(group >= family->n_mcgrps)) 4408c2ecf20Sopenharmony_ci return -EINVAL; 4418c2ecf20Sopenharmony_ci group = family->mcgrp_offset + group; 4428c2ecf20Sopenharmony_ci return netlink_has_listeners(net->genl_sock, group); 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ci#endif /* __NET_GENERIC_NETLINK_H */ 445