Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 57433
b: refs/heads/master
c: 3c158f7
h: refs/heads/master
i:
  57431: 86ea249
v: v3
  • Loading branch information
Patrick McHarrdy authored and David S. Miller committed Jun 7, 2007
1 parent 806fd40 commit c06a110
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 30 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: 51055be81c3cb14d0165a7432b787098b817fd35
refs/heads/master: 3c158f7f57601bc27eab82f0dc4fd3fad314d845
13 changes: 8 additions & 5 deletions trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,22 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper;

/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(*pskb, &ctinfo);
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
return NF_ACCEPT;

help = nfct_help(ct);
if (!help || !help->helper)
if (!help)
return NF_ACCEPT;

return help->helper->help(pskb,
skb_network_offset(*pskb) + ip_hdrlen(*pskb),
ct, ctinfo);
/* rcu_read_lock()ed by nf_hook_slow */
helper = rcu_dereference(help->helper);
if (!helper)
return NF_ACCEPT;
return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
ct, ctinfo);
}

static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
Expand Down
9 changes: 7 additions & 2 deletions trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
{
struct nf_conn *ct;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper;
enum ip_conntrack_info ctinfo;
unsigned int ret, protoff;
unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
Expand All @@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
goto out;

help = nfct_help(ct);
if (!help || !help->helper)
if (!help)
goto out;
/* rcu_read_lock()ed by nf_hook_slow */
helper = rcu_dereference(help->helper);
if (!helper)
goto out;

protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
Expand All @@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
return NF_ACCEPT;
}

ret = help->helper->help(pskb, protoff, ct, ctinfo);
ret = helper->help(pskb, protoff, ct, ctinfo);
if (ret != NF_ACCEPT)
return ret;
out:
Expand Down
26 changes: 18 additions & 8 deletions trunk/net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack)
{
struct nf_conn *ct = (void *)ul_conntrack;
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;

if (help && help->helper && help->helper->destroy)
help->helper->destroy(ct);
if (help) {
rcu_read_lock();
helper = rcu_dereference(help->helper);
if (helper && helper->destroy)
helper->destroy(ct);
rcu_read_unlock();
}

write_lock_bh(&nf_conntrack_lock);
/* Inside lock so preempt is disabled on module removal path.
Expand Down Expand Up @@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
unsigned int dataoff)
{
struct nf_conn *conntrack;
struct nf_conn_help *help;
struct nf_conntrack_tuple repl_tuple;
struct nf_conntrack_expect *exp;
u_int32_t features = 0;
Expand Down Expand Up @@ -691,14 +698,15 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
write_lock_bh(&nf_conntrack_lock);
exp = find_expectation(tuple);

help = nfct_help(conntrack);
if (exp) {
DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
conntrack, exp);
/* Welcome, Mr. Bond. We've been expecting you... */
__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = exp->master;
if (exp->helper)
nfct_help(conntrack)->helper = exp->helper;
rcu_assign_pointer(help->helper, exp->helper);
#ifdef CONFIG_NF_CONNTRACK_MARK
conntrack->mark = exp->master->mark;
#endif
Expand All @@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
nf_conntrack_get(&conntrack->master->ct_general);
NF_CT_STAT_INC(expect_new);
} else {
struct nf_conn_help *help = nfct_help(conntrack);

if (help)
help->helper = __nf_ct_helper_find(&repl_tuple);
if (help) {
/* not in hash table yet, so not strictly necessary */
rcu_assign_pointer(help->helper,
__nf_ct_helper_find(&repl_tuple));
}
NF_CT_STAT_INC(new);
}

Expand Down Expand Up @@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
helper = __nf_ct_helper_find(newreply);
if (helper)
memset(&help->help, 0, sizeof(help->help));
help->helper = helper;
/* not in hash table yet, so not strictly necessary */
rcu_assign_pointer(help->helper, helper);
}
write_unlock_bh(&nf_conntrack_lock);
}
Expand Down
4 changes: 4 additions & 0 deletions trunk/net/netfilter/nf_conntrack_expect.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
NF_CT_ASSERT(master_help);

write_lock_bh(&nf_conntrack_lock);
if (!master_help->helper) {
ret = -ESHUTDOWN;
goto out;
}
list_for_each_entry(i, &nf_conntrack_expect_list, list) {
if (expect_matches(i, expect)) {
/* Refresh timer: if it's dying, ignore.. */
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/netfilter/nf_conntrack_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,

if (help && help->helper == me) {
nf_conntrack_event(IPCT_HELPER, ct);
help->helper = NULL;
rcu_assign_pointer(help->helper, NULL);
}
return 0;
}
Expand Down
34 changes: 23 additions & 11 deletions trunk/net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
{
struct nfattr *nest_helper;
const struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;

if (!help || !help->helper)
if (!help)
return 0;

rcu_read_lock();
helper = rcu_dereference(help->helper);
if (!helper)
goto out;

nest_helper = NFA_NEST(skb, CTA_HELP);
NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);

if (help->helper->to_nfattr)
help->helper->to_nfattr(skb, ct);
if (helper->to_nfattr)
helper->to_nfattr(skb, ct);

NFA_NEST_END(skb, nest_helper);

out:
rcu_read_unlock();
return 0;

nfattr_failure:
rcu_read_unlock();
return -1;
}

Expand Down Expand Up @@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
if (help && help->helper) {
/* we had a helper before ... */
nf_ct_remove_expectations(ct);
help->helper = NULL;
rcu_assign_pointer(help->helper, NULL);
}

return 0;
Expand All @@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])

/* need to zero data of old helper */
memset(&help->help, 0, sizeof(help->help));
help->helper = helper;
rcu_assign_pointer(help->helper, helper);

return 0;
}
Expand Down Expand Up @@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
struct nf_conn *ct;
int err = -EINVAL;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper = NULL;

ct = nf_conntrack_alloc(otuple, rtuple);
if (ct == NULL || IS_ERR(ct))
Expand Down Expand Up @@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
#endif

help = nfct_help(ct);
if (help)
help->helper = nf_ct_helper_find_get(rtuple);
if (help) {
helper = nf_ct_helper_find_get(rtuple);
/* not in hash table yet so not strictly necessary */
rcu_assign_pointer(help->helper, helper);
}

add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);

if (help && help->helper)
nf_ct_helper_put(help->helper);
if (helper)
nf_ct_helper_put(helper);

return 0;

Expand Down
2 changes: 0 additions & 2 deletions trunk/net/netfilter/nf_conntrack_proto_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
struct nf_conn_help *help = nfct_help(ct);
struct nf_ct_gre_keymap **kmp, *km;

BUG_ON(strcmp(help->helper->name, "pptp"));
kmp = &help->help.ct_pptp_info.keymap[dir];
if (*kmp) {
/* check whether it's a retransmission */
Expand Down Expand Up @@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
enum ip_conntrack_dir dir;

DEBUGP("entering for ct %p\n", ct);
BUG_ON(strcmp(help->helper->name, "pptp"));

write_lock_bh(&nf_ct_gre_lock);
for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
Expand Down

0 comments on commit c06a110

Please sign in to comment.