aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter.h2
-rw-r--r--net/netfilter/core.c51
2 files changed, 48 insertions, 5 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 9230f9aee896..e82b76781bf6 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -133,6 +133,8 @@ int nf_register_hook(struct nf_hook_ops *reg);
133void nf_unregister_hook(struct nf_hook_ops *reg); 133void nf_unregister_hook(struct nf_hook_ops *reg);
134int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n); 134int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
135void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n); 135void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
136int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
137void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
136 138
137/* Functions to register get/setsockopt ranges (non-inclusive). You 139/* Functions to register get/setsockopt ranges (non-inclusive). You
138 need to check permissions yourself! */ 140 need to check permissions yourself! */
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index f39276d1c2d7..2c5327e43a88 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -188,19 +188,17 @@ EXPORT_SYMBOL(nf_unregister_net_hooks);
188 188
189static LIST_HEAD(nf_hook_list); 189static LIST_HEAD(nf_hook_list);
190 190
191int nf_register_hook(struct nf_hook_ops *reg) 191static int _nf_register_hook(struct nf_hook_ops *reg)
192{ 192{
193 struct net *net, *last; 193 struct net *net, *last;
194 int ret; 194 int ret;
195 195
196 rtnl_lock();
197 for_each_net(net) { 196 for_each_net(net) {
198 ret = nf_register_net_hook(net, reg); 197 ret = nf_register_net_hook(net, reg);
199 if (ret && ret != -ENOENT) 198 if (ret && ret != -ENOENT)
200 goto rollback; 199 goto rollback;
201 } 200 }
202 list_add_tail(&reg->list, &nf_hook_list); 201 list_add_tail(&reg->list, &nf_hook_list);
203 rtnl_unlock();
204 202
205 return 0; 203 return 0;
206rollback: 204rollback:
@@ -210,19 +208,34 @@ rollback:
210 break; 208 break;
211 nf_unregister_net_hook(net, reg); 209 nf_unregister_net_hook(net, reg);
212 } 210 }
211 return ret;
212}
213
214int nf_register_hook(struct nf_hook_ops *reg)
215{
216 int ret;
217
218 rtnl_lock();
219 ret = _nf_register_hook(reg);
213 rtnl_unlock(); 220 rtnl_unlock();
221
214 return ret; 222 return ret;
215} 223}
216EXPORT_SYMBOL(nf_register_hook); 224EXPORT_SYMBOL(nf_register_hook);
217 225
218void nf_unregister_hook(struct nf_hook_ops *reg) 226static void _nf_unregister_hook(struct nf_hook_ops *reg)
219{ 227{
220 struct net *net; 228 struct net *net;
221 229
222 rtnl_lock();
223 list_del(&reg->list); 230 list_del(&reg->list);
224 for_each_net(net) 231 for_each_net(net)
225 nf_unregister_net_hook(net, reg); 232 nf_unregister_net_hook(net, reg);
233}
234
235void nf_unregister_hook(struct nf_hook_ops *reg)
236{
237 rtnl_lock();
238 _nf_unregister_hook(reg);
226 rtnl_unlock(); 239 rtnl_unlock();
227} 240}
228EXPORT_SYMBOL(nf_unregister_hook); 241EXPORT_SYMBOL(nf_unregister_hook);
@@ -246,6 +259,26 @@ err:
246} 259}
247EXPORT_SYMBOL(nf_register_hooks); 260EXPORT_SYMBOL(nf_register_hooks);
248 261
262/* Caller MUST take rtnl_lock() */
263int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
264{
265 unsigned int i;
266 int err = 0;
267
268 for (i = 0; i < n; i++) {
269 err = _nf_register_hook(&reg[i]);
270 if (err)
271 goto err;
272 }
273 return err;
274
275err:
276 if (i > 0)
277 _nf_unregister_hooks(reg, i);
278 return err;
279}
280EXPORT_SYMBOL(_nf_register_hooks);
281
249void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) 282void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
250{ 283{
251 while (n-- > 0) 284 while (n-- > 0)
@@ -253,6 +286,14 @@ void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
253} 286}
254EXPORT_SYMBOL(nf_unregister_hooks); 287EXPORT_SYMBOL(nf_unregister_hooks);
255 288
289/* Caller MUST take rtnl_lock */
290void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
291{
292 while (n-- > 0)
293 _nf_unregister_hook(&reg[n]);
294}
295EXPORT_SYMBOL(_nf_unregister_hooks);
296
256unsigned int nf_iterate(struct list_head *head, 297unsigned int nf_iterate(struct list_head *head,
257 struct sk_buff *skb, 298 struct sk_buff *skb,
258 struct nf_hook_state *state, 299 struct nf_hook_state *state,