Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 4928
b: refs/heads/master
c: 4acdbdb
h: refs/heads/master
v: v3
  • Loading branch information
Rusty Russell authored and David S. Miller committed Jul 21, 2005
1 parent acc10e9 commit fd3591e
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 61 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: 4aa49d130df9209707a97786a55a3f584b7345e9
refs/heads/master: 4acdbdbe5089c06d5e0c7e96783fcc4414ded00a
3 changes: 3 additions & 0 deletions trunk/include/linux/netfilter_ipv4/ip_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ struct ip_conntrack_expect
/* Timer function; deletes the expectation. */
struct timer_list timeout;

/* Usage count. */
atomic_t use;

#ifdef CONFIG_IP_NF_NAT_NEEDED
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
Expand Down
7 changes: 4 additions & 3 deletions trunk/include/linux/netfilter_ipv4/ip_conntrack_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);

/* Allocate space for an expectation: this is mandatory before calling
ip_conntrack_expect_related. */
extern struct ip_conntrack_expect *ip_conntrack_expect_alloc(void);
extern void ip_conntrack_expect_free(struct ip_conntrack_expect *exp);
ip_conntrack_expect_related. You will have to call put afterwards. */
extern struct ip_conntrack_expect *
ip_conntrack_expect_alloc(struct ip_conntrack *master);
extern void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);

/* Add an expected connection: can have more than one per connection */
extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp);
Expand Down
8 changes: 3 additions & 5 deletions trunk/net/ipv4/netfilter/ip_conntrack_amanda.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,13 @@ static int help(struct sk_buff **pskb,
if (port == 0 || len > 5)
break;

exp = ip_conntrack_expect_alloc();
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}

exp->expectfn = NULL;
exp->master = ct;

exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
exp->tuple.src.u.tcp.port = 0;
Expand All @@ -126,10 +125,9 @@ static int help(struct sk_buff **pskb,
ret = ip_nat_amanda_hook(pskb, ctinfo,
tmp - amanda_buffer,
len, exp);
else if (ip_conntrack_expect_related(exp) != 0) {
ip_conntrack_expect_free(exp);
else if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
}
ip_conntrack_expect_put(exp);
}

out:
Expand Down
40 changes: 18 additions & 22 deletions trunk/net/ipv4/netfilter/ip_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,12 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,


/* ip_conntrack_expect helper functions */
static void destroy_expect(struct ip_conntrack_expect *exp)
{
ip_conntrack_put(exp->master);
IP_NF_ASSERT(!timer_pending(&exp->timeout));
kmem_cache_free(ip_conntrack_expect_cachep, exp);
CONNTRACK_STAT_INC(expect_delete);
}

static void unlink_expect(struct ip_conntrack_expect *exp)
{
ASSERT_WRITE_LOCK(&ip_conntrack_lock);
IP_NF_ASSERT(!timer_pending(&exp->timeout));
list_del(&exp->list);
/* Logically in destroy_expect, but we hold the lock here. */
CONNTRACK_STAT_INC(expect_delete);
exp->master->expecting--;
}

Expand All @@ -160,7 +153,7 @@ static void expectation_timed_out(unsigned long ul_expect)
write_lock_bh(&ip_conntrack_lock);
unlink_expect(exp);
write_unlock_bh(&ip_conntrack_lock);
destroy_expect(exp);
ip_conntrack_expect_put(exp);
}

/* If an expectation for this connection is found, it gets delete from
Expand Down Expand Up @@ -198,7 +191,7 @@ static void remove_expectations(struct ip_conntrack *ct)
list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) {
if (i->master == ct && del_timer(&i->timeout)) {
unlink_expect(i);
destroy_expect(i);
ip_conntrack_expect_put(i);
}
}
}
Expand Down Expand Up @@ -537,7 +530,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
if (exp) {
if (exp->expectfn)
exp->expectfn(conntrack, exp);
destroy_expect(exp);
ip_conntrack_expect_put(exp);
}

return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
Expand Down Expand Up @@ -729,14 +722,14 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
if (expect_matches(i, exp) && del_timer(&i->timeout)) {
unlink_expect(i);
write_unlock_bh(&ip_conntrack_lock);
destroy_expect(i);
ip_conntrack_expect_put(i);
return;
}
}
write_unlock_bh(&ip_conntrack_lock);
}

struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
{
struct ip_conntrack_expect *new;

Expand All @@ -745,18 +738,23 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
DEBUGP("expect_related: OOM allocating expect\n");
return NULL;
}
new->master = NULL;
new->master = me;
atomic_inc(&new->master->ct_general.use);
atomic_set(&new->use, 1);
return new;
}

void ip_conntrack_expect_free(struct ip_conntrack_expect *expect)
void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
{
kmem_cache_free(ip_conntrack_expect_cachep, expect);
if (atomic_dec_and_test(&exp->use)) {
ip_conntrack_put(exp->master);
kmem_cache_free(ip_conntrack_expect_cachep, exp);
}
}

static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
{
atomic_inc(&exp->master->ct_general.use);
atomic_inc(&exp->use);
exp->master->expecting++;
list_add(&exp->list, &ip_conntrack_expect_list);

Expand All @@ -778,7 +776,7 @@ static void evict_oldest_expect(struct ip_conntrack *master)
if (i->master == master) {
if (del_timer(&i->timeout)) {
unlink_expect(i);
destroy_expect(i);
ip_conntrack_expect_put(i);
}
break;
}
Expand Down Expand Up @@ -810,8 +808,6 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
/* Refresh timer: if it's dying, ignore.. */
if (refresh_timer(i)) {
ret = 0;
/* We don't need the one they've given us. */
ip_conntrack_expect_free(expect);
goto out;
}
} else if (expect_clash(i, expect)) {
Expand Down Expand Up @@ -881,7 +877,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) {
if (exp->master->helper == me && del_timer(&exp->timeout)) {
unlink_expect(exp);
destroy_expect(exp);
ip_conntrack_expect_put(exp);
}
}
/* Get rid of expecteds, set helpers to NULL. */
Expand Down
14 changes: 7 additions & 7 deletions trunk/net/ipv4/netfilter/ip_conntrack_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ static int help(struct sk_buff **pskb,
fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff);

/* Allocate expectation which will be inserted */
exp = ip_conntrack_expect_alloc();
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
Expand All @@ -403,8 +403,7 @@ static int help(struct sk_buff **pskb,
networks, or the packet filter itself). */
if (!loose) {
ret = NF_ACCEPT;
ip_conntrack_expect_free(exp);
goto out_update_nl;
goto out_put_expect;
}
exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16)
| (array[2] << 8) | array[3]);
Expand All @@ -419,7 +418,6 @@ static int help(struct sk_buff **pskb,
{ 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});

exp->expectfn = NULL;
exp->master = ct;

/* Now, NAT might want to mangle the packet, and register the
* (possibly changed) expectation itself. */
Expand All @@ -428,13 +426,15 @@ static int help(struct sk_buff **pskb,
matchoff, matchlen, exp, &seq);
else {
/* Can't expect this? Best to drop packet now. */
if (ip_conntrack_expect_related(exp) != 0) {
ip_conntrack_expect_free(exp);
if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
} else
else
ret = NF_ACCEPT;
}

out_put_expect:
ip_conntrack_expect_put(exp);

out_update_nl:
/* Now if this ends in \n, update ftp info. Seq may have been
* adjusted by NAT code. */
Expand Down
8 changes: 3 additions & 5 deletions trunk/net/ipv4/netfilter/ip_conntrack_irc.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ static int help(struct sk_buff **pskb,
continue;
}

exp = ip_conntrack_expect_alloc();
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
Expand All @@ -221,16 +221,14 @@ static int help(struct sk_buff **pskb,
{ { 0, { 0 } },
{ 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
exp->expectfn = NULL;
exp->master = ct;
if (ip_nat_irc_hook)
ret = ip_nat_irc_hook(pskb, ctinfo,
addr_beg_p - ib_ptr,
addr_end_p - addr_beg_p,
exp);
else if (ip_conntrack_expect_related(exp) != 0) {
ip_conntrack_expect_free(exp);
else if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
}
ip_conntrack_expect_put(exp);
goto out;
} /* for .. NUM_DCCPROTO */
} /* while data < ... */
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/netfilter/ip_conntrack_standalone.c
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,7 @@ EXPORT_SYMBOL(ip_ct_refresh_acct);
EXPORT_SYMBOL(ip_ct_protos);
EXPORT_SYMBOL(ip_ct_find_proto);
EXPORT_SYMBOL(ip_conntrack_expect_alloc);
EXPORT_SYMBOL(ip_conntrack_expect_free);
EXPORT_SYMBOL(ip_conntrack_expect_put);
EXPORT_SYMBOL(ip_conntrack_expect_related);
EXPORT_SYMBOL(ip_conntrack_unexpect_related);
EXPORT_SYMBOL(ip_conntrack_tuple_taken);
Expand Down
8 changes: 3 additions & 5 deletions trunk/net/ipv4/netfilter/ip_conntrack_tftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static int tftp_help(struct sk_buff **pskb,
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);

exp = ip_conntrack_expect_alloc();
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL)
return NF_DROP;

Expand All @@ -75,17 +75,15 @@ static int tftp_help(struct sk_buff **pskb,
exp->mask.dst.u.udp.port = 0xffff;
exp->mask.dst.protonum = 0xff;
exp->expectfn = NULL;
exp->master = ct;

DEBUGP("expect: ");
DUMP_TUPLE(&exp->tuple);
DUMP_TUPLE(&exp->mask);
if (ip_nat_tftp_hook)
ret = ip_nat_tftp_hook(pskb, ctinfo, exp);
else if (ip_conntrack_expect_related(exp) != 0) {
ip_conntrack_expect_free(exp);
else if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
}
ip_conntrack_expect_put(exp);
break;
case TFTP_OPCODE_DATA:
case TFTP_OPCODE_ACK:
Expand Down
4 changes: 1 addition & 3 deletions trunk/net/ipv4/netfilter/ip_nat_amanda.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ static unsigned int help(struct sk_buff **pskb,
break;
}

if (port == 0) {
ip_conntrack_expect_free(exp);
if (port == 0)
return NF_DROP;
}

sprintf(buffer, "%u", port);
ret = ip_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
Expand Down
4 changes: 1 addition & 3 deletions trunk/net/ipv4/netfilter/ip_nat_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,8 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb,
break;
}

if (port == 0) {
ip_conntrack_expect_free(exp);
if (port == 0)
return NF_DROP;
}

if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
seq)) {
Expand Down
4 changes: 1 addition & 3 deletions trunk/net/ipv4/netfilter/ip_nat_irc.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,8 @@ static unsigned int help(struct sk_buff **pskb,
break;
}

if (port == 0) {
ip_conntrack_expect_free(exp);
if (port == 0)
return NF_DROP;
}

/* strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27
* strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28
Expand Down
4 changes: 1 addition & 3 deletions trunk/net/ipv4/netfilter/ip_nat_tftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ static unsigned int help(struct sk_buff **pskb,
exp->saved_proto.udp.port = exp->tuple.dst.u.tcp.port;
exp->dir = IP_CT_DIR_REPLY;
exp->expectfn = ip_nat_follow_master;
if (ip_conntrack_expect_related(exp) != 0) {
ip_conntrack_expect_free(exp);
if (ip_conntrack_expect_related(exp) != 0)
return NF_DROP;
}
return NF_ACCEPT;
}

Expand Down

0 comments on commit fd3591e

Please sign in to comment.