| /* SPDX-License-Identifier: GPL-2.0 */ | 
 | #ifndef _AF_NETLINK_H | 
 | #define _AF_NETLINK_H | 
 |  | 
 | #include <linux/rhashtable.h> | 
 | #include <linux/atomic.h> | 
 | #include <net/sock.h> | 
 |  | 
 | /* flags */ | 
 | enum { | 
 | 	NETLINK_F_KERNEL_SOCKET, | 
 | 	NETLINK_F_RECV_PKTINFO, | 
 | 	NETLINK_F_BROADCAST_SEND_ERROR, | 
 | 	NETLINK_F_RECV_NO_ENOBUFS, | 
 | 	NETLINK_F_LISTEN_ALL_NSID, | 
 | 	NETLINK_F_CAP_ACK, | 
 | 	NETLINK_F_EXT_ACK, | 
 | 	NETLINK_F_STRICT_CHK, | 
 | }; | 
 |  | 
 | #define NLGRPSZ(x)	(ALIGN(x, sizeof(unsigned long) * 8) / 8) | 
 | #define NLGRPLONGS(x)	(NLGRPSZ(x)/sizeof(unsigned long)) | 
 |  | 
 | struct netlink_sock { | 
 | 	/* struct sock has to be the first member of netlink_sock */ | 
 | 	struct sock		sk; | 
 | 	unsigned long		flags; | 
 | 	u32			portid; | 
 | 	u32			dst_portid; | 
 | 	u32			dst_group; | 
 | 	u32			subscriptions; | 
 | 	u32			ngroups; | 
 | 	unsigned long		*groups; | 
 | 	unsigned long		state; | 
 | 	size_t			max_recvmsg_len; | 
 | 	wait_queue_head_t	wait; | 
 | 	bool			bound; | 
 | 	bool			cb_running; | 
 | 	int			dump_done_errno; | 
 | 	struct netlink_callback	cb; | 
 | 	struct mutex		nl_cb_mutex; | 
 |  | 
 | 	void			(*netlink_rcv)(struct sk_buff *skb); | 
 | 	int			(*netlink_bind)(struct net *net, int group); | 
 | 	void			(*netlink_unbind)(struct net *net, int group); | 
 | 	void			(*netlink_release)(struct sock *sk, | 
 | 						   unsigned long *groups); | 
 | 	struct module		*module; | 
 |  | 
 | 	struct rhash_head	node; | 
 | 	struct rcu_head		rcu; | 
 | }; | 
 |  | 
 | static inline struct netlink_sock *nlk_sk(struct sock *sk) | 
 | { | 
 | 	return container_of(sk, struct netlink_sock, sk); | 
 | } | 
 |  | 
 | #define nlk_test_bit(nr, sk) test_bit(NETLINK_F_##nr, &nlk_sk(sk)->flags) | 
 |  | 
 | struct netlink_table { | 
 | 	struct rhashtable	hash; | 
 | 	struct hlist_head	mc_list; | 
 | 	struct listeners __rcu	*listeners; | 
 | 	unsigned int		flags; | 
 | 	unsigned int		groups; | 
 | 	struct mutex		*cb_mutex; | 
 | 	struct module		*module; | 
 | 	int			(*bind)(struct net *net, int group); | 
 | 	void			(*unbind)(struct net *net, int group); | 
 | 	void                    (*release)(struct sock *sk, | 
 | 					   unsigned long *groups); | 
 | 	int			registered; | 
 | }; | 
 |  | 
 | extern struct netlink_table *nl_table; | 
 | extern rwlock_t nl_table_lock; | 
 |  | 
 | #endif |