162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _AF_NETLINK_H 362306a36Sopenharmony_ci#define _AF_NETLINK_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/rhashtable.h> 662306a36Sopenharmony_ci#include <linux/atomic.h> 762306a36Sopenharmony_ci#include <linux/workqueue.h> 862306a36Sopenharmony_ci#include <net/sock.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* flags */ 1162306a36Sopenharmony_cienum { 1262306a36Sopenharmony_ci NETLINK_F_KERNEL_SOCKET, 1362306a36Sopenharmony_ci NETLINK_F_RECV_PKTINFO, 1462306a36Sopenharmony_ci NETLINK_F_BROADCAST_SEND_ERROR, 1562306a36Sopenharmony_ci NETLINK_F_RECV_NO_ENOBUFS, 1662306a36Sopenharmony_ci NETLINK_F_LISTEN_ALL_NSID, 1762306a36Sopenharmony_ci NETLINK_F_CAP_ACK, 1862306a36Sopenharmony_ci NETLINK_F_EXT_ACK, 1962306a36Sopenharmony_ci NETLINK_F_STRICT_CHK, 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) 2362306a36Sopenharmony_ci#define NLGRPLONGS(x) (NLGRPSZ(x)/sizeof(unsigned long)) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistruct netlink_sock { 2662306a36Sopenharmony_ci /* struct sock has to be the first member of netlink_sock */ 2762306a36Sopenharmony_ci struct sock sk; 2862306a36Sopenharmony_ci unsigned long flags; 2962306a36Sopenharmony_ci u32 portid; 3062306a36Sopenharmony_ci u32 dst_portid; 3162306a36Sopenharmony_ci u32 dst_group; 3262306a36Sopenharmony_ci u32 subscriptions; 3362306a36Sopenharmony_ci u32 ngroups; 3462306a36Sopenharmony_ci unsigned long *groups; 3562306a36Sopenharmony_ci unsigned long state; 3662306a36Sopenharmony_ci size_t max_recvmsg_len; 3762306a36Sopenharmony_ci wait_queue_head_t wait; 3862306a36Sopenharmony_ci bool bound; 3962306a36Sopenharmony_ci bool cb_running; 4062306a36Sopenharmony_ci int dump_done_errno; 4162306a36Sopenharmony_ci struct netlink_callback cb; 4262306a36Sopenharmony_ci struct mutex *cb_mutex; 4362306a36Sopenharmony_ci struct mutex cb_def_mutex; 4462306a36Sopenharmony_ci void (*netlink_rcv)(struct sk_buff *skb); 4562306a36Sopenharmony_ci int (*netlink_bind)(struct net *net, int group); 4662306a36Sopenharmony_ci void (*netlink_unbind)(struct net *net, int group); 4762306a36Sopenharmony_ci void (*netlink_release)(struct sock *sk, 4862306a36Sopenharmony_ci unsigned long *groups); 4962306a36Sopenharmony_ci struct module *module; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci struct rhash_head node; 5262306a36Sopenharmony_ci struct rcu_head rcu; 5362306a36Sopenharmony_ci struct work_struct work; 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic inline struct netlink_sock *nlk_sk(struct sock *sk) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci return container_of(sk, struct netlink_sock, sk); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define nlk_test_bit(nr, sk) test_bit(NETLINK_F_##nr, &nlk_sk(sk)->flags) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct netlink_table { 6462306a36Sopenharmony_ci struct rhashtable hash; 6562306a36Sopenharmony_ci struct hlist_head mc_list; 6662306a36Sopenharmony_ci struct listeners __rcu *listeners; 6762306a36Sopenharmony_ci unsigned int flags; 6862306a36Sopenharmony_ci unsigned int groups; 6962306a36Sopenharmony_ci struct mutex *cb_mutex; 7062306a36Sopenharmony_ci struct module *module; 7162306a36Sopenharmony_ci int (*bind)(struct net *net, int group); 7262306a36Sopenharmony_ci void (*unbind)(struct net *net, int group); 7362306a36Sopenharmony_ci void (*release)(struct sock *sk, 7462306a36Sopenharmony_ci unsigned long *groups); 7562306a36Sopenharmony_ci int registered; 7662306a36Sopenharmony_ci}; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciextern struct netlink_table *nl_table; 7962306a36Sopenharmony_ciextern rwlock_t nl_table_lock; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci#endif 82