Skip to content

Commit

Permalink
net: Add _nf_(un)register_hooks symbols
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mahesh Bandewar authored and David S. Miller committed Sep 19, 2016
1 parent d409b84 commit e8bffe0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ int nf_register_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);
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
need to check permissions yourself! */
Expand Down
51 changes: 46 additions & 5 deletions net/netfilter/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,19 +188,17 @@ EXPORT_SYMBOL(nf_unregister_net_hooks);

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;
int ret;

rtnl_lock();
for_each_net(net) {
ret = nf_register_net_hook(net, reg);
if (ret && ret != -ENOENT)
goto rollback;
}
list_add_tail(&reg->list, &nf_hook_list);
rtnl_unlock();

return 0;
rollback:
Expand All @@ -210,19 +208,34 @@ int nf_register_hook(struct nf_hook_ops *reg)
break;
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();

return ret;
}
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;

rtnl_lock();
list_del(&reg->list);
for_each_net(net)
nf_unregister_net_hook(net, reg);
}

void nf_unregister_hook(struct nf_hook_ops *reg)
{
rtnl_lock();
_nf_unregister_hook(reg);
rtnl_unlock();
}
EXPORT_SYMBOL(nf_unregister_hook);
Expand All @@ -246,13 +259,41 @@ int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
}
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(&reg[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)
{
while (n-- > 0)
nf_unregister_hook(&reg[n]);
}
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(&reg[n]);
}
EXPORT_SYMBOL(_nf_unregister_hooks);

unsigned int nf_iterate(struct list_head *head,
struct sk_buff *skb,
struct nf_hook_state *state,
Expand Down

0 comments on commit e8bffe0

Please sign in to comment.