Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122374
b: refs/heads/master
c: 226c0c0
h: refs/heads/master
v: v3
  • Loading branch information
Pablo Neira Ayuso authored and Patrick McHardy committed Nov 18, 2008
1 parent 878a4b5 commit b7e86b9
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 41 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: 4dc06f9633444f426ef9960c53426f2d2ded64ac
refs/heads/master: 226c0c0ef2abdf91b8d9cce1aaf7d4635a5e5926
5 changes: 2 additions & 3 deletions trunk/include/net/netfilter/nf_conntrack_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ struct nf_conntrack_helper
unsigned int expect_class_max;
};

extern struct nf_conntrack_helper *
__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple);

extern struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name);

Expand All @@ -49,6 +46,8 @@ extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);

extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);

extern int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags);

static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
{
return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
Expand Down
28 changes: 2 additions & 26 deletions trunk/net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,14 +588,7 @@ init_conntrack(struct net *net,
nf_conntrack_get(&ct->master->ct_general);
NF_CT_STAT_INC(net, expect_new);
} else {
struct nf_conntrack_helper *helper;

helper = __nf_ct_helper_find(&repl_tuple);
if (helper) {
help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help)
rcu_assign_pointer(help->helper, helper);
}
__nf_ct_try_assign_helper(ct, GFP_ATOMIC);
NF_CT_STAT_INC(net, new);
}

Expand Down Expand Up @@ -772,7 +765,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
const struct nf_conntrack_tuple *newreply)
{
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;

/* Should be unconfirmed, so not in hash table yet */
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
Expand All @@ -785,23 +777,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
return;

rcu_read_lock();
helper = __nf_ct_helper_find(newreply);
if (helper == NULL) {
if (help)
rcu_assign_pointer(help->helper, NULL);
goto out;
}

if (help == NULL) {
help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help == NULL)
goto out;
} else {
memset(&help->help, 0, sizeof(help->help));
}

rcu_assign_pointer(help->helper, helper);
out:
__nf_ct_try_assign_helper(ct, GFP_ATOMIC);
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
Expand Down
32 changes: 30 additions & 2 deletions trunk/net/netfilter/nf_conntrack_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
(__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
}

struct nf_conntrack_helper *
static struct nf_conntrack_helper *
__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_helper *helper;
Expand All @@ -62,7 +62,6 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
}
return NULL;
}
EXPORT_SYMBOL_GPL(__nf_ct_helper_find);

struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name)
Expand Down Expand Up @@ -94,6 +93,35 @@ struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
}
EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);

int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags)
{
int ret = 0;
struct nf_conntrack_helper *helper;
struct nf_conn_help *help = nfct_help(ct);

helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
if (helper == NULL) {
if (help)
rcu_assign_pointer(help->helper, NULL);
goto out;
}

if (help == NULL) {
help = nf_ct_helper_ext_add(ct, flags);
if (help == NULL) {
ret = -ENOMEM;
goto out;
}
} else {
memset(&help->help, 0, sizeof(help->help));
}

rcu_assign_pointer(help->helper, helper);
out:
return ret;
}
EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);

static inline int unhelp(struct nf_conntrack_tuple_hash *i,
const struct nf_conntrack_helper *me)
{
Expand Down
70 changes: 61 additions & 9 deletions trunk/net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,8 +917,22 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
}

helper = __nf_conntrack_helper_find_byname(helpname);
if (helper == NULL)
if (helper == NULL) {
#ifdef CONFIG_MODULES
spin_unlock_bh(&nf_conntrack_lock);

if (request_module("nfct-helper-%s", helpname) < 0) {
spin_lock_bh(&nf_conntrack_lock);
return -EOPNOTSUPP;
}

spin_lock_bh(&nf_conntrack_lock);
helper = __nf_conntrack_helper_find_byname(helpname);
if (helper)
return -EAGAIN;
#endif
return -EOPNOTSUPP;
}

if (help) {
if (help->helper == helper)
Expand Down Expand Up @@ -1082,7 +1096,6 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
{
struct nf_conn *ct;
int err = -EINVAL;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper;

ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_KERNEL);
Expand All @@ -1097,16 +1110,55 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
ct->status |= IPS_CONFIRMED;

rcu_read_lock();
helper = __nf_ct_helper_find(rtuple);
if (helper) {
help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help == NULL) {
if (cda[CTA_HELP]) {
char *helpname;

err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
if (err < 0) {
rcu_read_unlock();
goto err;
}

helper = __nf_conntrack_helper_find_byname(helpname);
if (helper == NULL) {
rcu_read_unlock();
#ifdef CONFIG_MODULES
if (request_module("nfct-helper-%s", helpname) < 0) {
err = -EOPNOTSUPP;
goto err;
}

rcu_read_lock();
helper = __nf_conntrack_helper_find_byname(helpname);
if (helper) {
rcu_read_unlock();
err = -EAGAIN;
goto err;
}
rcu_read_unlock();
#endif
err = -EOPNOTSUPP;
goto err;
} else {
struct nf_conn_help *help;

help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help == NULL) {
rcu_read_unlock();
err = -ENOMEM;
goto err;
}

/* not in hash table yet so not strictly necessary */
rcu_assign_pointer(help->helper, helper);
}
} else {
/* try an implicit helper assignation */
err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
if (err < 0) {
rcu_read_unlock();
err = -ENOMEM;
goto err;
}
/* not in hash table yet so not strictly necessary */
rcu_assign_pointer(help->helper, helper);
}

if (cda[CTA_STATUS]) {
Expand Down

0 comments on commit b7e86b9

Please sign in to comment.