--- linux-2.6.3-old/net/ipv4/netfilter/ip_conntrack_core.c 2004-02-22 13:29:30.000000000 +0100 +++ linux-2.6.3/net/ipv4/netfilter/ip_conntrack_core.c 2004-02-25 16:31:09.000000000 +0100 @@ -917,11 +917,53 @@ WRITE_UNLOCK(&ip_conntrack_lock); } +int +ip_conntrack_expect_alloc(struct ip_conntrack_expect **new) +{ + *new = (struct ip_conntrack_expect *) + kmalloc(sizeof(struct ip_conntrack_expect), GFP_ATOMIC); + if (!*new) { + DEBUGP("expect_related: OOM allocating expect\n"); + return -ENOMEM; + } + + /* is this important? */ + memset(*new, 0, sizeof(struct ip_conntrack_expect)); + + return 1; +} + +void +ip_conntrack_expect_insert(struct ip_conntrack_expect *new, + struct ip_conntrack *related_to) +{ + DEBUGP("new expectation %p of conntrack %p\n", new, related_to); + new->expectant = related_to; + new->sibling = NULL; + atomic_set(&new->use, 1); + + /* add to expected list for this connection */ + list_add(&new->expected_list, &related_to->sibling_list); + /* add to global list of expectations */ + + list_prepend(&ip_conntrack_expect_list, &new->list); + /* add and start timer if required */ + if (related_to->helper->timeout) { + init_timer(&new->timeout); + new->timeout.data = (unsigned long)new; + new->timeout.function = expectation_timed_out; + new->timeout.expires = jiffies + + related_to->helper->timeout * HZ; + add_timer(&new->timeout); + } + related_to->expecting++; +} + /* Add a related connection. */ -int ip_conntrack_expect_related(struct ip_conntrack *related_to, - struct ip_conntrack_expect *expect) +int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, + struct ip_conntrack *related_to) { - struct ip_conntrack_expect *old, *new; + struct ip_conntrack_expect *old; int ret = 0; WRITE_LOCK(&ip_conntrack_lock); @@ -953,6 +995,7 @@ if (old) { WRITE_UNLOCK(&ip_conntrack_lock); + kfree(expect); return -EEXIST; } } else if (related_to->helper->max_expected && @@ -971,6 +1014,7 @@ related_to->helper->name, NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); + kfree(expect); return -EPERM; } DEBUGP("ip_conntrack: max number of expected " @@ -1010,37 +1054,12 @@ &expect->mask)) { WRITE_UNLOCK(&ip_conntrack_lock); DEBUGP("expect_related: busy!\n"); + + kfree(expect); return -EBUSY; } - - new = (struct ip_conntrack_expect *) - kmalloc(sizeof(struct ip_conntrack_expect), GFP_ATOMIC); - if (!new) { - WRITE_UNLOCK(&ip_conntrack_lock); - DEBUGP("expect_relaed: OOM allocating expect\n"); - return -ENOMEM; - } - - DEBUGP("new expectation %p of conntrack %p\n", new, related_to); - memcpy(new, expect, sizeof(*expect)); - new->expectant = related_to; - new->sibling = NULL; - atomic_set(&new->use, 1); - - /* add to expected list for this connection */ - list_add(&new->expected_list, &related_to->sibling_list); - /* add to global list of expectations */ - list_prepend(&ip_conntrack_expect_list, &new->list); - /* add and start timer if required */ - if (related_to->helper->timeout) { - init_timer(&new->timeout); - new->timeout.data = (unsigned long)new; - new->timeout.function = expectation_timed_out; - new->timeout.expires = jiffies + - related_to->helper->timeout * HZ; - add_timer(&new->timeout); - } - related_to->expecting++; + + ip_conntrack_expect_insert(expect, related_to); WRITE_UNLOCK(&ip_conntrack_lock); --- linux-2.6.3-old/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-02-18 04:57:46.000000000 +0100 +++ linux-2.6.3/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-02-25 15:16:53.000000000 +0100 @@ -497,6 +497,7 @@ EXPORT_SYMBOL(ip_ct_find_proto); EXPORT_SYMBOL(__ip_ct_find_proto); EXPORT_SYMBOL(ip_ct_find_helper); +EXPORT_SYMBOL(ip_conntrack_expect_alloc); EXPORT_SYMBOL(ip_conntrack_expect_related); EXPORT_SYMBOL(ip_conntrack_change_expect); EXPORT_SYMBOL(ip_conntrack_unexpect_related); --- linux-2.6.3-old/include/linux/netfilter_ipv4/ip_conntrack_helper.h 2004-02-18 04:57:16.000000000 +0100 +++ linux-2.6.3/include/linux/netfilter_ipv4/ip_conntrack_helper.h 2004-02-25 15:38:27.000000000 +0100 @@ -35,9 +35,13 @@ extern struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple); + +/* Allocate space for an expectation: this is mandatory before calling + ip_conntrack_expect_related. */ +extern int ip_conntrack_expect_alloc(struct ip_conntrack_expect **new); /* Add an expected connection: can have more than one per connection */ -extern int ip_conntrack_expect_related(struct ip_conntrack *related_to, - struct ip_conntrack_expect *exp); +extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp, + struct ip_conntrack *related_to); extern int ip_conntrack_change_expect(struct ip_conntrack_expect *expect, struct ip_conntrack_tuple *newtuple); extern void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp);