 9063e21fb0
			
		
	
	
	9063e21fb0
	
	
	
		
			
			One known problem with netlink is the fact that NLMSG_GOODSIZE is really small on PAGE_SIZE==4096 architectures, and it is difficult to know in advance what buffer size is used by the application. This patch adds an automatic learning of the size. First netlink message will still be limited to ~4K, but if user used bigger buffers, then following messages will be able to use up to 16KB. This speedups dump() operations by a large factor and should be safe for legacy applications. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Thomas Graf <tgraf@suug.ch> Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
		
			
				
	
	
		
			85 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef _AF_NETLINK_H
 | |
| #define _AF_NETLINK_H
 | |
| 
 | |
| #include <net/sock.h>
 | |
| 
 | |
| #define NLGRPSZ(x)	(ALIGN(x, sizeof(unsigned long) * 8) / 8)
 | |
| #define NLGRPLONGS(x)	(NLGRPSZ(x)/sizeof(unsigned long))
 | |
| 
 | |
| struct netlink_ring {
 | |
| 	void			**pg_vec;
 | |
| 	unsigned int		head;
 | |
| 	unsigned int		frames_per_block;
 | |
| 	unsigned int		frame_size;
 | |
| 	unsigned int		frame_max;
 | |
| 
 | |
| 	unsigned int		pg_vec_order;
 | |
| 	unsigned int		pg_vec_pages;
 | |
| 	unsigned int		pg_vec_len;
 | |
| 
 | |
| 	atomic_t		pending;
 | |
| };
 | |
| 
 | |
| struct netlink_sock {
 | |
| 	/* struct sock has to be the first member of netlink_sock */
 | |
| 	struct sock		sk;
 | |
| 	u32			portid;
 | |
| 	u32			dst_portid;
 | |
| 	u32			dst_group;
 | |
| 	u32			flags;
 | |
| 	u32			subscriptions;
 | |
| 	u32			ngroups;
 | |
| 	unsigned long		*groups;
 | |
| 	unsigned long		state;
 | |
| 	size_t			max_recvmsg_len;
 | |
| 	wait_queue_head_t	wait;
 | |
| 	bool			cb_running;
 | |
| 	struct netlink_callback	cb;
 | |
| 	struct mutex		*cb_mutex;
 | |
| 	struct mutex		cb_def_mutex;
 | |
| 	void			(*netlink_rcv)(struct sk_buff *skb);
 | |
| 	void			(*netlink_bind)(int group);
 | |
| 	struct module		*module;
 | |
| #ifdef CONFIG_NETLINK_MMAP
 | |
| 	struct mutex		pg_vec_lock;
 | |
| 	struct netlink_ring	rx_ring;
 | |
| 	struct netlink_ring	tx_ring;
 | |
| 	atomic_t		mapped;
 | |
| #endif /* CONFIG_NETLINK_MMAP */
 | |
| };
 | |
| 
 | |
| static inline struct netlink_sock *nlk_sk(struct sock *sk)
 | |
| {
 | |
| 	return container_of(sk, struct netlink_sock, sk);
 | |
| }
 | |
| 
 | |
| struct nl_portid_hash {
 | |
| 	struct hlist_head	*table;
 | |
| 	unsigned long		rehash_time;
 | |
| 
 | |
| 	unsigned int		mask;
 | |
| 	unsigned int		shift;
 | |
| 
 | |
| 	unsigned int		entries;
 | |
| 	unsigned int		max_shift;
 | |
| 
 | |
| 	u32			rnd;
 | |
| };
 | |
| 
 | |
| struct netlink_table {
 | |
| 	struct nl_portid_hash	hash;
 | |
| 	struct hlist_head	mc_list;
 | |
| 	struct listeners __rcu	*listeners;
 | |
| 	unsigned int		flags;
 | |
| 	unsigned int		groups;
 | |
| 	struct mutex		*cb_mutex;
 | |
| 	struct module		*module;
 | |
| 	void			(*bind)(int group);
 | |
| 	bool			(*compare)(struct net *net, struct sock *sock);
 | |
| 	int			registered;
 | |
| };
 | |
| 
 | |
| extern struct netlink_table *nl_table;
 | |
| extern rwlock_t nl_table_lock;
 | |
| 
 | |
| #endif
 |