mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	lwtunnel: Add destroy state operation
Users of lwt tunnels may set up some secondary state in build_state function. Add a corresponding destroy_state function to allow users to clean up state. This destroy state function is called from lwstate_free. Also, we now free lwstate using kfree_rcu so user can assume structure is not freed before rcu. Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									02dc7658c7
								
							
						
					
					
						commit
						1104d9ba44
					
				
					 2 changed files with 16 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -29,6 +29,7 @@ struct lwtunnel_state {
 | 
			
		|||
	int		(*orig_input)(struct sk_buff *);
 | 
			
		||||
	int             len;
 | 
			
		||||
	__u16		headroom;
 | 
			
		||||
	struct		rcu_head rcu;
 | 
			
		||||
	__u8            data[0];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +37,7 @@ struct lwtunnel_encap_ops {
 | 
			
		|||
	int (*build_state)(struct net_device *dev, struct nlattr *encap,
 | 
			
		||||
			   unsigned int family, const void *cfg,
 | 
			
		||||
			   struct lwtunnel_state **ts);
 | 
			
		||||
	void (*destroy_state)(struct lwtunnel_state *lws);
 | 
			
		||||
	int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
 | 
			
		||||
	int (*input)(struct sk_buff *skb);
 | 
			
		||||
	int (*fill_encap)(struct sk_buff *skb,
 | 
			
		||||
| 
						 | 
				
			
			@ -46,10 +48,7 @@ struct lwtunnel_encap_ops {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_LWTUNNEL
 | 
			
		||||
static inline void lwtstate_free(struct lwtunnel_state *lws)
 | 
			
		||||
{
 | 
			
		||||
	kfree(lws);
 | 
			
		||||
}
 | 
			
		||||
void lwtstate_free(struct lwtunnel_state *lws);
 | 
			
		||||
 | 
			
		||||
static inline struct lwtunnel_state *
 | 
			
		||||
lwtstate_get(struct lwtunnel_state *lws)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,6 +130,19 @@ int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(lwtunnel_build_state);
 | 
			
		||||
 | 
			
		||||
void lwtstate_free(struct lwtunnel_state *lws)
 | 
			
		||||
{
 | 
			
		||||
	const struct lwtunnel_encap_ops *ops = lwtun_encaps[lws->type];
 | 
			
		||||
 | 
			
		||||
	if (ops->destroy_state) {
 | 
			
		||||
		ops->destroy_state(lws);
 | 
			
		||||
		kfree_rcu(lws, rcu);
 | 
			
		||||
	} else {
 | 
			
		||||
		kfree(lws);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(lwtstate_free);
 | 
			
		||||
 | 
			
		||||
int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate)
 | 
			
		||||
{
 | 
			
		||||
	const struct lwtunnel_encap_ops *ops;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue