forked from mirrors/linux
		
	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
	
	 Mahesh Bandewar
						Mahesh Bandewar