Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 341865
b: refs/heads/master
c: 0360ae4
h: refs/heads/master
i:
  341863: 2d79aa3
v: v3
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Dec 3, 2012
1 parent da11c24 commit db29225
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 157 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d871befe357ccc262edbb0a4f9aeea650012edf5
refs/heads/master: 0360ae412d09bc6f4864c801effcb20bfd84520e
8 changes: 2 additions & 6 deletions trunk/include/net/netfilter/nf_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,10 @@ struct nf_queue_entry {
struct nf_queue_handler {
int (*outfn)(struct nf_queue_entry *entry,
unsigned int queuenum);
char *name;
};

extern int nf_register_queue_handler(u_int8_t pf,
const struct nf_queue_handler *qh);
extern int nf_unregister_queue_handler(u_int8_t pf,
const struct nf_queue_handler *qh);
extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
void nf_register_queue_handler(const struct nf_queue_handler *qh);
void nf_unregister_queue_handler(void);
extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);

#endif /* _NF_QUEUE_H */
2 changes: 0 additions & 2 deletions trunk/net/netfilter/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,6 @@ void __init netfilter_init(void)
panic("cannot create netfilter proc entry");
#endif

if (netfilter_queue_init() < 0)
panic("cannot initialize nf_queue");
if (netfilter_log_init() < 0)
panic("cannot initialize nf_log");
}
152 changes: 13 additions & 139 deletions trunk/net/netfilter/nf_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,84 +14,32 @@
#include "nf_internals.h"

/*
* A queue handler may be registered for each protocol. Each is protected by
* long term mutex. The handler must provide an an outfn() to accept packets
* for queueing and must reinject all packets it receives, no matter what.
* Hook for nfnetlink_queue to register its queue handler.
* We do this so that most of the NFQUEUE code can be modular.
*
* Once the queue is registered it must reinject all packets it
* receives, no matter what.
*/
static const struct nf_queue_handler __rcu *queue_handler[NFPROTO_NUMPROTO] __read_mostly;

static DEFINE_MUTEX(queue_handler_mutex);
static const struct nf_queue_handler __rcu *queue_handler __read_mostly;

/* return EBUSY when somebody else is registered, return EEXIST if the
* same handler is registered, return 0 in case of success. */
int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
void nf_register_queue_handler(const struct nf_queue_handler *qh)
{
int ret;
const struct nf_queue_handler *old;

if (pf >= ARRAY_SIZE(queue_handler))
return -EINVAL;

mutex_lock(&queue_handler_mutex);
old = rcu_dereference_protected(queue_handler[pf],
lockdep_is_held(&queue_handler_mutex));
if (old == qh)
ret = -EEXIST;
else if (old)
ret = -EBUSY;
else {
rcu_assign_pointer(queue_handler[pf], qh);
ret = 0;
}
mutex_unlock(&queue_handler_mutex);

return ret;
/* should never happen, we only have one queueing backend in kernel */
WARN_ON(rcu_access_pointer(queue_handler));
rcu_assign_pointer(queue_handler, qh);
}
EXPORT_SYMBOL(nf_register_queue_handler);

/* The caller must flush their queue before this */
int nf_unregister_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
void nf_unregister_queue_handler(void)
{
const struct nf_queue_handler *old;

if (pf >= ARRAY_SIZE(queue_handler))
return -EINVAL;

mutex_lock(&queue_handler_mutex);
old = rcu_dereference_protected(queue_handler[pf],
lockdep_is_held(&queue_handler_mutex));
if (old && old != qh) {
mutex_unlock(&queue_handler_mutex);
return -EINVAL;
}

RCU_INIT_POINTER(queue_handler[pf], NULL);
mutex_unlock(&queue_handler_mutex);

RCU_INIT_POINTER(queue_handler, NULL);
synchronize_rcu();

return 0;
}
EXPORT_SYMBOL(nf_unregister_queue_handler);

void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)
{
u_int8_t pf;

mutex_lock(&queue_handler_mutex);
for (pf = 0; pf < ARRAY_SIZE(queue_handler); pf++) {
if (rcu_dereference_protected(
queue_handler[pf],
lockdep_is_held(&queue_handler_mutex)
) == qh)
RCU_INIT_POINTER(queue_handler[pf], NULL);
}
mutex_unlock(&queue_handler_mutex);

synchronize_rcu();
}
EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);

static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
{
/* Release those devices we held, or Alexey will kill me. */
Expand Down Expand Up @@ -137,7 +85,7 @@ static int __nf_queue(struct sk_buff *skb,
/* QUEUE == DROP if no one is waiting, to be safe. */
rcu_read_lock();

qh = rcu_dereference(queue_handler[pf]);
qh = rcu_dereference(queue_handler);
if (!qh) {
status = -ESRCH;
goto err_unlock;
Expand Down Expand Up @@ -344,77 +292,3 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
kfree(entry);
}
EXPORT_SYMBOL(nf_reinject);

#ifdef CONFIG_PROC_FS
static void *seq_start(struct seq_file *seq, loff_t *pos)
{
if (*pos >= ARRAY_SIZE(queue_handler))
return NULL;

return pos;
}

static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
{
(*pos)++;

if (*pos >= ARRAY_SIZE(queue_handler))
return NULL;

return pos;
}

static void seq_stop(struct seq_file *s, void *v)
{

}

static int seq_show(struct seq_file *s, void *v)
{
int ret;
loff_t *pos = v;
const struct nf_queue_handler *qh;

rcu_read_lock();
qh = rcu_dereference(queue_handler[*pos]);
if (!qh)
ret = seq_printf(s, "%2lld NONE\n", *pos);
else
ret = seq_printf(s, "%2lld %s\n", *pos, qh->name);
rcu_read_unlock();

return ret;
}

static const struct seq_operations nfqueue_seq_ops = {
.start = seq_start,
.next = seq_next,
.stop = seq_stop,
.show = seq_show,
};

static int nfqueue_open(struct inode *inode, struct file *file)
{
return seq_open(file, &nfqueue_seq_ops);
}

static const struct file_operations nfqueue_file_ops = {
.owner = THIS_MODULE,
.open = nfqueue_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif /* PROC_FS */


int __init netfilter_queue_init(void)
{
#ifdef CONFIG_PROC_FS
if (!proc_create("nf_queue", S_IRUGO,
proc_net_netfilter, &nfqueue_file_ops))
return -1;
#endif
return 0;
}

14 changes: 5 additions & 9 deletions trunk/net/netfilter/nfnetlink_queue_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,6 @@ static const struct nla_policy nfqa_cfg_policy[NFQA_CFG_MAX+1] = {
};

static const struct nf_queue_handler nfqh = {
.name = "nf_queue",
.outfn = &nfqnl_enqueue_packet,
};

Expand All @@ -827,14 +826,10 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
if (nfqa[NFQA_CFG_CMD]) {
cmd = nla_data(nfqa[NFQA_CFG_CMD]);

/* Commands without queue context - might sleep */
/* Obsolete commands without queue context */
switch (cmd->command) {
case NFQNL_CFG_CMD_PF_BIND:
return nf_register_queue_handler(ntohs(cmd->pf),
&nfqh);
case NFQNL_CFG_CMD_PF_UNBIND:
return nf_unregister_queue_handler(ntohs(cmd->pf),
&nfqh);
case NFQNL_CFG_CMD_PF_BIND: return 0;
case NFQNL_CFG_CMD_PF_UNBIND: return 0;
}
}

Expand Down Expand Up @@ -1074,6 +1069,7 @@ static int __init nfnetlink_queue_init(void)
#endif

register_netdevice_notifier(&nfqnl_dev_notifier);
nf_register_queue_handler(&nfqh);
return status;

#ifdef CONFIG_PROC_FS
Expand All @@ -1087,7 +1083,7 @@ static int __init nfnetlink_queue_init(void)

static void __exit nfnetlink_queue_fini(void)
{
nf_unregister_queue_handlers(&nfqh);
nf_unregister_queue_handler();
unregister_netdevice_notifier(&nfqnl_dev_notifier);
#ifdef CONFIG_PROC_FS
remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
Expand Down

0 comments on commit db29225

Please sign in to comment.