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