mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: Add _nf_(un)register_hooks symbols
Add _nf_register_hooks() and _nf_unregister_hooks() calls which allow caller to hold RTNL mutex. Signed-off-by: Mahesh Bandewar <maheshb@google.com> CC: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									d409b84768
								
							
						
					
					
						commit
						e8bffe0cf9
					
				
					 2 changed files with 48 additions and 5 deletions
				
			
		| 
						 | 
					@ -133,6 +133,8 @@ int nf_register_hook(struct nf_hook_ops *reg);
 | 
				
			||||||
void nf_unregister_hook(struct nf_hook_ops *reg);
 | 
					void nf_unregister_hook(struct nf_hook_ops *reg);
 | 
				
			||||||
int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
 | 
					int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
 | 
				
			||||||
void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
 | 
					void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
 | 
				
			||||||
 | 
					int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
 | 
				
			||||||
 | 
					void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Functions to register get/setsockopt ranges (non-inclusive).  You
 | 
					/* Functions to register get/setsockopt ranges (non-inclusive).  You
 | 
				
			||||||
   need to check permissions yourself! */
 | 
					   need to check permissions yourself! */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,19 +188,17 @@ EXPORT_SYMBOL(nf_unregister_net_hooks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static LIST_HEAD(nf_hook_list);
 | 
					static LIST_HEAD(nf_hook_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int nf_register_hook(struct nf_hook_ops *reg)
 | 
					static int _nf_register_hook(struct nf_hook_ops *reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net *net, *last;
 | 
						struct net *net, *last;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_lock();
 | 
					 | 
				
			||||||
	for_each_net(net) {
 | 
						for_each_net(net) {
 | 
				
			||||||
		ret = nf_register_net_hook(net, reg);
 | 
							ret = nf_register_net_hook(net, reg);
 | 
				
			||||||
		if (ret && ret != -ENOENT)
 | 
							if (ret && ret != -ENOENT)
 | 
				
			||||||
			goto rollback;
 | 
								goto rollback;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	list_add_tail(®->list, &nf_hook_list);
 | 
						list_add_tail(®->list, &nf_hook_list);
 | 
				
			||||||
	rtnl_unlock();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
rollback:
 | 
					rollback:
 | 
				
			||||||
| 
						 | 
					@ -210,19 +208,34 @@ int nf_register_hook(struct nf_hook_ops *reg)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		nf_unregister_net_hook(net, reg);
 | 
							nf_unregister_net_hook(net, reg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int nf_register_hook(struct nf_hook_ops *reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rtnl_lock();
 | 
				
			||||||
 | 
						ret = _nf_register_hook(reg);
 | 
				
			||||||
	rtnl_unlock();
 | 
						rtnl_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(nf_register_hook);
 | 
					EXPORT_SYMBOL(nf_register_hook);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nf_unregister_hook(struct nf_hook_ops *reg)
 | 
					static void _nf_unregister_hook(struct nf_hook_ops *reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net *net;
 | 
						struct net *net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_lock();
 | 
					 | 
				
			||||||
	list_del(®->list);
 | 
						list_del(®->list);
 | 
				
			||||||
	for_each_net(net)
 | 
						for_each_net(net)
 | 
				
			||||||
		nf_unregister_net_hook(net, reg);
 | 
							nf_unregister_net_hook(net, reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void nf_unregister_hook(struct nf_hook_ops *reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						rtnl_lock();
 | 
				
			||||||
 | 
						_nf_unregister_hook(reg);
 | 
				
			||||||
	rtnl_unlock();
 | 
						rtnl_unlock();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(nf_unregister_hook);
 | 
					EXPORT_SYMBOL(nf_unregister_hook);
 | 
				
			||||||
| 
						 | 
					@ -246,6 +259,26 @@ int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(nf_register_hooks);
 | 
					EXPORT_SYMBOL(nf_register_hooks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Caller MUST take rtnl_lock() */
 | 
				
			||||||
 | 
					int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < n; i++) {
 | 
				
			||||||
 | 
							err = _nf_register_hook(®[i]);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						if (i > 0)
 | 
				
			||||||
 | 
							_nf_unregister_hooks(reg, i);
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(_nf_register_hooks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
 | 
					void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while (n-- > 0)
 | 
						while (n-- > 0)
 | 
				
			||||||
| 
						 | 
					@ -253,6 +286,14 @@ void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(nf_unregister_hooks);
 | 
					EXPORT_SYMBOL(nf_unregister_hooks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Caller MUST take rtnl_lock */
 | 
				
			||||||
 | 
					void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (n-- > 0)
 | 
				
			||||||
 | 
							_nf_unregister_hook(®[n]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(_nf_unregister_hooks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int nf_iterate(struct list_head *head,
 | 
					unsigned int nf_iterate(struct list_head *head,
 | 
				
			||||||
			struct sk_buff *skb,
 | 
								struct sk_buff *skb,
 | 
				
			||||||
			struct nf_hook_state *state,
 | 
								struct nf_hook_state *state,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue