Skip to content

Commit

Permalink
[NETFILTER]: nf_conntrack: automatic helper assignment for expectations
Browse files Browse the repository at this point in the history
Some helpers (namely H.323) manually assign further helpers to expected
connections. This is not possible with nf_conntrack anymore since we
need to know whether a helper is used at allocation time.

Handle the helper assignment centrally, which allows to perform the
correct allocation and as a nice side effect eliminates the need
for the H.323 helper to fiddle with nf_conntrack_lock.

Mid term the allocation scheme really needs to be redesigned since
we do both the helper and expectation lookup _twice_ for every new
connection.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Dec 3, 2006
1 parent bff9a89 commit 9457d85
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 6 deletions.
3 changes: 3 additions & 0 deletions include/net/netfilter/nf_conntrack_expect.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ struct nf_conntrack_expect
void (*expectfn)(struct nf_conn *new,
struct nf_conntrack_expect *this);

/* Helper to assign to new connection */
struct nf_conntrack_helper *helper;

/* The conntrack of the master connection */
struct nf_conn *master;

Expand Down
19 changes: 14 additions & 5 deletions net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,10 +545,10 @@ static int early_drop(struct list_head *chain)
static struct nf_conn *
__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
const struct nf_conntrack_tuple *repl,
const struct nf_conntrack_l3proto *l3proto)
const struct nf_conntrack_l3proto *l3proto,
u_int32_t features)
{
struct nf_conn *conntrack = NULL;
u_int32_t features = 0;
struct nf_conntrack_helper *helper;

if (unlikely(!nf_conntrack_hash_rnd_initted)) {
Expand All @@ -574,7 +574,7 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
}

/* find features needed by this conntrack. */
features = l3proto->get_features(orig);
features |= l3proto->get_features(orig);

/* FIXME: protect helper list per RCU */
read_lock_bh(&nf_conntrack_lock);
Expand Down Expand Up @@ -624,7 +624,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
struct nf_conntrack_l3proto *l3proto;

l3proto = __nf_ct_l3proto_find(orig->src.l3num);
return __nf_conntrack_alloc(orig, repl, l3proto);
return __nf_conntrack_alloc(orig, repl, l3proto, 0);
}

void nf_conntrack_free(struct nf_conn *conntrack)
Expand All @@ -649,13 +649,20 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
struct nf_conn *conntrack;
struct nf_conntrack_tuple repl_tuple;
struct nf_conntrack_expect *exp;
u_int32_t features = 0;

if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
DEBUGP("Can't invert tuple.\n");
return NULL;
}

conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto);
read_lock_bh(&nf_conntrack_lock);
exp = __nf_conntrack_expect_find(tuple);
if (exp && exp->helper)
features = NF_CT_F_HELP;
read_unlock_bh(&nf_conntrack_lock);

conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto, features);
if (conntrack == NULL || IS_ERR(conntrack)) {
DEBUGP("Can't allocate conntrack.\n");
return (struct nf_conntrack_tuple_hash *)conntrack;
Expand All @@ -676,6 +683,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
/* 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;
#ifdef CONFIG_NF_CONNTRACK_MARK
conntrack->mark = exp->master->mark;
#endif
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nf_conntrack_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ static int help(struct sk_buff **pskb,
}

exp->expectfn = NULL;
exp->helper = NULL;
exp->flags = 0;

/* Now, NAT might want to mangle the packet, and register the
Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/nf_conntrack_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
/* Get rid of expectations */
list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
struct nf_conn_help *help = nfct_help(exp->master);
if (help->helper == me && del_timer(&exp->timeout)) {
if ((help->helper == me || exp->helper == me) &&
del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_conntrack_expect_put(exp);
}
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
exp->expectfn = NULL;
exp->flags = 0;
exp->master = ct;
exp->helper = NULL;
memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));

Expand Down

0 comments on commit 9457d85

Please sign in to comment.