Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 279067
b: refs/heads/master
c: 3d058d7
h: refs/heads/master
i:
  279065: de5a845
  279063: a8c6d3c
v: v3
  • Loading branch information
Pablo Neira Ayuso committed Dec 23, 2011
1 parent 70db49d commit a1a3a5c
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 49 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: c4042a339f40fe00d85e31055b1c0808dd025539
refs/heads/master: 3d058d7bc2c5671ae630e0b463be8a69b5783fb9
4 changes: 4 additions & 0 deletions trunk/include/linux/netfilter/nf_conntrack_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ enum ip_conntrack_status {
/* Conntrack is a fake untracked entry */
IPS_UNTRACKED_BIT = 12,
IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),

/* Conntrack has a userspace helper. */
IPS_USERSPACE_HELPER_BIT = 13,
IPS_USERSPACE_HELPER = (1 << IPS_USERSPACE_HELPER_BIT),
};

/* Connection tracking event types */
Expand Down
3 changes: 2 additions & 1 deletion trunk/include/linux/netfilter/xt_CT.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

#include <linux/types.h>

#define XT_CT_NOTRACK 0x1
#define XT_CT_NOTRACK 0x1
#define XT_CT_USERSPACE_HELPER 0x2

struct xt_ct_target_info {
__u16 flags;
Expand Down
1 change: 0 additions & 1 deletion trunk/include/net/netfilter/nf_conntrack_expect.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)

void nf_ct_remove_expectations(struct nf_conn *ct);
void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
void nf_ct_remove_userspace_expectations(void);

/* Allocate space for an expectation: this is mandatory before calling
nf_ct_expect_related. You will have to call put afterwards. */
Expand Down
63 changes: 21 additions & 42 deletions trunk/net/netfilter/nf_conntrack_expect.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,21 @@ unsigned int nf_ct_expect_max __read_mostly;

static struct kmem_cache *nf_ct_expect_cachep __read_mostly;

static HLIST_HEAD(nf_ct_userspace_expect_list);

/* nf_conntrack_expect helper functions */
void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
u32 pid, int report)
{
struct nf_conn_help *master_help = nfct_help(exp->master);
struct net *net = nf_ct_exp_net(exp);

NF_CT_ASSERT(master_help);
NF_CT_ASSERT(!timer_pending(&exp->timeout));

hlist_del_rcu(&exp->hnode);
net->ct.expect_count--;

hlist_del(&exp->lnode);
if (!(exp->flags & NF_CT_EXPECT_USERSPACE))
master_help->expecting[exp->class]--;
master_help->expecting[exp->class]--;

nf_ct_expect_event_report(IPEXP_DESTROY, exp, pid, report);
nf_ct_expect_put(exp);
Expand Down Expand Up @@ -314,37 +312,34 @@ void nf_ct_expect_put(struct nf_conntrack_expect *exp)
}
EXPORT_SYMBOL_GPL(nf_ct_expect_put);

static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
static int nf_ct_expect_insert(struct nf_conntrack_expect *exp)
{
struct nf_conn_help *master_help = nfct_help(exp->master);
struct nf_conntrack_helper *helper;
struct net *net = nf_ct_exp_net(exp);
const struct nf_conntrack_expect_policy *p;
unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);

/* two references : one for hash insert, one for the timer */
atomic_add(2, &exp->use);

if (master_help) {
hlist_add_head(&exp->lnode, &master_help->expectations);
master_help->expecting[exp->class]++;
} else if (exp->flags & NF_CT_EXPECT_USERSPACE)
hlist_add_head(&exp->lnode, &nf_ct_userspace_expect_list);
hlist_add_head(&exp->lnode, &master_help->expectations);
master_help->expecting[exp->class]++;

hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]);
net->ct.expect_count++;

setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
(unsigned long)exp);
if (master_help) {
p = &rcu_dereference_protected(
master_help->helper,
lockdep_is_held(&nf_conntrack_lock)
)->expect_policy[exp->class];
exp->timeout.expires = jiffies + p->timeout * HZ;
helper = rcu_dereference_protected(master_help->helper,
lockdep_is_held(&nf_conntrack_lock));
if (helper) {
exp->timeout.expires = jiffies +
helper->expect_policy[exp->class].timeout * HZ;
}
add_timer(&exp->timeout);

NF_CT_STAT_INC(net, expect_create);
return 0;
}

/* Race with expectations being used means we could have none to find; OK. */
Expand Down Expand Up @@ -389,14 +384,13 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
struct nf_conntrack_expect *i;
struct nf_conn *master = expect->master;
struct nf_conn_help *master_help = nfct_help(master);
struct nf_conntrack_helper *helper;
struct net *net = nf_ct_exp_net(expect);
struct hlist_node *n;
unsigned int h;
int ret = 1;

/* Don't allow expectations created from kernel-space with no helper */
if (!(expect->flags & NF_CT_EXPECT_USERSPACE) &&
(!master_help || (master_help && !master_help->helper))) {
if (!master_help) {
ret = -ESHUTDOWN;
goto out;
}
Expand All @@ -414,11 +408,10 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
}
}
/* Will be over limit? */
if (master_help) {
p = &rcu_dereference_protected(
master_help->helper,
lockdep_is_held(&nf_conntrack_lock)
)->expect_policy[expect->class];
helper = rcu_dereference_protected(master_help->helper,
lockdep_is_held(&nf_conntrack_lock));
if (helper) {
p = &helper->expect_policy[expect->class];
if (p->max_expected &&
master_help->expecting[expect->class] >= p->max_expected) {
evict_oldest_expect(master, expect);
Expand Down Expand Up @@ -450,8 +443,9 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
if (ret <= 0)
goto out;

ret = 0;
nf_ct_expect_insert(expect);
ret = nf_ct_expect_insert(expect);
if (ret < 0)
goto out;
spin_unlock_bh(&nf_conntrack_lock);
nf_ct_expect_event_report(IPEXP_NEW, expect, pid, report);
return ret;
Expand All @@ -461,21 +455,6 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);

void nf_ct_remove_userspace_expectations(void)
{
struct nf_conntrack_expect *exp;
struct hlist_node *n, *next;

hlist_for_each_entry_safe(exp, n, next,
&nf_ct_userspace_expect_list, lnode) {
if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
}
}
}
EXPORT_SYMBOL_GPL(nf_ct_remove_userspace_expectations);

#ifdef CONFIG_PROC_FS
struct ct_expect_iter_state {
struct seq_net_private p;
Expand Down
12 changes: 12 additions & 0 deletions trunk/net/netfilter/nf_conntrack_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
int ret = 0;

if (tmpl != NULL) {
/* we've got a userspace helper. */
if (tmpl->status & IPS_USERSPACE_HELPER) {
help = nf_ct_helper_ext_add(ct, flags);
if (help == NULL) {
ret = -ENOMEM;
goto out;
}
rcu_assign_pointer(help->helper, NULL);
__set_bit(IPS_USERSPACE_HELPER_BIT, &ct->status);
ret = 0;
goto out;
}
help = nfct_help(tmpl);
if (help != NULL)
helper = help->helper;
Expand Down
5 changes: 4 additions & 1 deletion trunk/net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2040,6 +2040,10 @@ ctnetlink_create_expect(struct net *net, u16 zone,
}
help = nfct_help(ct);
if (!help) {
err = -EOPNOTSUPP;
goto out;
}
if (test_bit(IPS_USERSPACE_HELPER_BIT, &ct->status)) {
if (!cda[CTA_EXPECT_TIMEOUT]) {
err = -EINVAL;
goto out;
Expand Down Expand Up @@ -2264,7 +2268,6 @@ static void __exit ctnetlink_exit(void)
{
pr_info("ctnetlink: unregistering from nfnetlink.\n");

nf_ct_remove_userspace_expectations();
unregister_pernet_subsys(&ctnetlink_net_ops);
nfnetlink_subsys_unregister(&ctnl_exp_subsys);
nfnetlink_subsys_unregister(&ctnl_subsys);
Expand Down
8 changes: 5 additions & 3 deletions trunk/net/netfilter/xt_CT.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par)
int ret = 0;
u8 proto;

if (info->flags & ~XT_CT_NOTRACK)
return -EINVAL;
if (info->flags & ~(XT_CT_NOTRACK | XT_CT_USERSPACE_HELPER))
return -EOPNOTSUPP;

if (info->flags & XT_CT_NOTRACK) {
ct = nf_ct_untracked_get();
Expand Down Expand Up @@ -92,7 +92,9 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par)
GFP_KERNEL))
goto err3;

if (info->helper[0]) {
if (info->flags & XT_CT_USERSPACE_HELPER) {
__set_bit(IPS_USERSPACE_HELPER_BIT, &ct->status);
} else if (info->helper[0]) {
ret = -ENOENT;
proto = xt_ct_find_proto(par);
if (!proto) {
Expand Down

0 comments on commit a1a3a5c

Please sign in to comment.