summaryrefslogtreecommitdiff
path: root/release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c')
-rw-r--r--release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c185
1 files changed, 80 insertions, 105 deletions
diff --git a/release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c b/release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c
index 9c6f040f..324951ee 100644
--- a/release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/release/src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c
@@ -34,7 +34,12 @@
/* For ERR_PTR(). Yeah, I know... --RR */
#include <linux/fs.h>
-#include <linux/netdevice.h>
+#define TEST_JHASH // test jhash from 2.4.33 -- zzz
+
+#ifdef TEST_JHASH
+#include <linux/jhash.h>
+#include <linux/random.h>
+#endif
/* This rwlock protects the main hash table, protocol/helper/expected
registrations, conntrack timers*/
@@ -71,7 +76,7 @@ static kmem_cache_t *ip_conntrack_cachep;
int sysctl_ip_conntrack_tcp_timeouts[10] = {
30 MINS, /* TCP_CONNTRACK_NONE, */
- 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */
+ 4 HOURS, /* TCP_CONNTRACK_ESTABLISHED, */ // was 5 days zzz
2 MINS, /* TCP_CONNTRACK_SYN_SENT, */
60 SECS, /* TCP_CONNTRACK_SYN_RECV, */
2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */
@@ -128,9 +133,20 @@ ip_conntrack_put(struct ip_conntrack *ct)
nf_conntrack_put(&ct->infos[0]);
}
+#ifdef TEST_JHASH
+static int ip_conntrack_hash_rnd_initted;
+static unsigned int ip_conntrack_hash_rnd;
+#endif
+
static inline u_int32_t
hash_conntrack(const struct ip_conntrack_tuple *tuple)
{
+#ifdef TEST_JHASH
+ return (jhash_3words(tuple->src.ip,
+ (tuple->dst.ip ^ tuple->dst.protonum),
+ (tuple->src.u.all | (tuple->dst.u.all << 16)),
+ ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
+#else
/* ntohl because more differences in low bits. */
/* To ensure that halves of the same connection don't hash
clash, we add the source per-proto again. */
@@ -139,6 +155,7 @@ hash_conntrack(const struct ip_conntrack_tuple *tuple)
+ tuple->dst.protonum)
+ ntohs(tuple->src.u.all))
% ip_conntrack_htable_size;
+#endif
}
inline int
@@ -314,9 +331,6 @@ clean_from_lists(struct ip_conntrack *ct)
{
DEBUGP("clean_from_lists(%p)\n", ct);
MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
- /* Remove from both hash lists: must not NULL out next ptrs,
- otherwise we'll look unconfirmed. Fortunately, LIST_DELETE
- doesn't do this. --RR */
LIST_DELETE(&ip_conntrack_hash
[hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)],
&ct->tuplehash[IP_CT_DIR_ORIGINAL]);
@@ -359,6 +373,14 @@ destroy_conntrack(struct nf_conntrack *nfct)
list_del(&ct->master->expected_list);
kfree(ct->master);
}
+
+ #if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE)
+ if(ct->layer7.app_proto)
+ kfree(ct->layer7.app_proto);
+ if(ct->layer7.app_data)
+ kfree(ct->layer7.app_data);
+ #endif
+
WRITE_UNLOCK(&ip_conntrack_lock);
DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
@@ -489,6 +511,7 @@ __ip_conntrack_confirm(struct nf_ct_info *nfct)
ct->timeout.expires += jiffies;
add_timer(&ct->timeout);
atomic_inc(&ct->ct_general.use);
+ set_bit(IPS_CONFIRMED_BIT, &ct->status);
WRITE_UNLOCK(&ip_conntrack_lock);
return NF_ACCEPT;
}
@@ -606,7 +629,7 @@ icmp_error_track(struct sk_buff *skb,
connection. Too bad: we're in trouble anyway. */
static inline int unreplied(const struct ip_conntrack_tuple_hash *i)
{
- return !(i->ctrack->status & IPS_ASSURED);
+ return !(test_bit(IPS_ASSURED_BIT, &i->ctrack->status));
}
static int early_drop(struct list_head *chain)
@@ -632,31 +655,6 @@ static int early_drop(struct list_head *chain)
return dropped;
}
-/******************lzh add ***************************************
-* DESCRIPTION:delete seleted ip conntrack from conntrack_hash list
-* INPUT : ip_conntrack_tuple_hash h
-* OUTPUT: NULL
-* AUTHOR: linzhihong
-* DATE : 2006.7.20
-*****************************************************************/
-void del_selected_conntrack(struct ip_conntrack_tuple_hash *h)
-{
- DEBUGP("hahaha enter %s\n", __FUNCTION__);
- if(h)
- {
- #if 1
- ip_ct_refresh(h->ctrack, 1*HZ);
- #else
- if(del_timer(&h->ctrack->timeout))
- {
- death_by_timeout((unsigned long)h->ctrack);
- }
- //ip_conntrack_put(h->ctrack);
- #endif
- }
-}
-/**************************** lzh end ******************************/
-
static inline int helper_cmp(const struct ip_conntrack_helper *i,
const struct ip_conntrack_tuple *rtuple)
{
@@ -670,41 +668,6 @@ struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *t
tuple);
}
-#define RESERVE_CONNTRACK_FOR_ROUTER
-#ifdef RESERVE_CONNTRACK_FOR_ROUTER
-#define RESERVE_CONNTRACK_NUM 20
-/*
- Check if the packet is for Router AP(LAN side only), or generate from
- Router itself(Both sides).
- */
-static int cmp_local_ip(u_int32_t dst, u_int32_t src)
-{
-#define IF_LAN_NAME "br0"
-
- int ret = -1;
- struct in_device *in_dev;
- struct net_device *dev;
- struct in_ifaddr **ifap = NULL;
- struct in_ifaddr *ifa = NULL;
-
- for(dev = dev_base; dev != NULL; dev = dev->next){
- if((in_dev=__in_dev_get(dev)) != NULL){
- for(ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next){
- if((ifa->ifa_address == dst && !strcmp(IF_LAN_NAME, ifa->ifa_label)) || ifa->ifa_address == src){
- /*match*/
- ret = 0;
- break;
- }
- }
- }
- }
-
- return ret;
-
-#undef IF_LAN_NAME
-}
-#endif
-
/* Allocate a new conntrack: we return -ENOMEM if classification
failed due to stress. Otherwise it really is unclassifiable. */
static struct ip_conntrack_tuple_hash *
@@ -719,9 +682,15 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
int i;
static unsigned int drop_next = 0;
+#ifdef TEST_JHASH
+ if (!ip_conntrack_hash_rnd_initted) {
+ get_random_bytes(&ip_conntrack_hash_rnd, 4);
+ ip_conntrack_hash_rnd_initted = 1;
+ }
+#endif
+
hash = hash_conntrack(tuple);
- #ifndef RESERVE_CONNTRACK_FOR_ROUTER
if (ip_conntrack_max &&
atomic_read(&ip_conntrack_count) >= ip_conntrack_max) {
/* Try dropping from random chain, or else from the
@@ -738,32 +707,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
return ERR_PTR(-ENOMEM);
}
}
- #else
-#define IPV4_BROADCAST_ADDR 0x000000FF
-#define IPV4_MULTICAST_ADDR 0xE0000000
- if (ip_conntrack_max &&
- (ip_conntrack_max - atomic_read(&ip_conntrack_count)) <= RESERVE_CONNTRACK_NUM){
- if((atomic_read(&ip_conntrack_count) < ip_conntrack_max) &&
- (((tuple->dst).ip & IPV4_BROADCAST_ADDR == IPV4_BROADCAST_ADDR) || ((tuple->dst).ip & IPV4_BROADCAST_ADDR == IPV4_MULTICAST_ADDR) || !cmp_local_ip((tuple->dst).ip, (tuple->src).ip))){
- //packet for router(LAN side only) or packet from router, let it go thru
- }
- else{
- /* Try dropping from random chain, or else from the
- chain about to put into (in case they're trying to
- bomb one hash chain). */
- unsigned int next = (drop_next++)%ip_conntrack_htable_size;
-
- if (!early_drop(&ip_conntrack_hash[next])
- && !early_drop(&ip_conntrack_hash[hash])) {
- if (net_ratelimit())
- printk(KERN_WARNING
- "ip_conntrack: table full, dropping"
- " packet.\n");
- return ERR_PTR(-ENOMEM);
- }
- }
- }
- #endif
if (!invert_tuple(&repl_tuple, tuple, protocol)) {
DEBUGP("Can't invert tuple.\n");
@@ -829,9 +772,12 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
conntrack, expected);
/* Welcome, Mr. Bond. We've been expecting you... */
IP_NF_ASSERT(master_ct(conntrack));
- conntrack->status = IPS_EXPECTED;
+ __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected;
expected->sibling = conntrack;
+#if CONFIG_IP_NF_CONNTRACK_MARK
+ conntrack->mark = expected->expectant->mark;
+#endif
LIST_DELETE(&ip_conntrack_expect_list, expected);
INIT_LIST_HEAD(&expected->list);
expected->expectant->expecting--;
@@ -878,11 +824,11 @@ resolve_normal_ct(struct sk_buff *skb,
*set_reply = 1;
} else {
/* Once we've had two way comms, always ESTABLISHED. */
- if (h->ctrack->status & IPS_SEEN_REPLY) {
+ if (test_bit(IPS_SEEN_REPLY_BIT, &h->ctrack->status)) {
DEBUGP("ip_conntrack_in: normal packet for %p\n",
h->ctrack);
*ctinfo = IP_CT_ESTABLISHED;
- } else if (h->ctrack->status & IPS_EXPECTED) {
+ } else if (test_bit(IPS_EXPECTED_BIT, &h->ctrack->status)) {
DEBUGP("ip_conntrack_in: related packet for %p\n",
h->ctrack);
*ctinfo = IP_CT_RELATED;
@@ -1056,16 +1002,15 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
}
if (old) {
- /************************* lzh add ******************************************
- * fix sip alg CDROUTE test fail
- * 2007/3/16
- ***************************************************************************/
- if (old->help.exp_sip_info.nated && (old->help.exp_sip_info.type == CONN_RTP))
- {
- DEBUGP("%s: found old exp and nated, rtp port=%d\n", __FUNCTION__,ntohs(old->tuple.dst.u.udp.port));
- related_to->help.ct_sip_info.rtpport = ntohs(old->tuple.dst.u.udp.port);
+#if 0 // removed 1.11 forward bug test
+ if (1) { // 43011 (09?): checkme
+ // lzh add, fix sip alg CDROUTE test fail, 2007/3/16
+ if (old->help.exp_sip_info.nated && (old->help.exp_sip_info.type == CONN_RTP)) {
+ DEBUGP("%s: found old exp and nated, rtp port=%d\n", __FUNCTION__,ntohs(old->tuple.dst.u.udp.port));
+ related_to->help.ct_sip_info.rtpport = ntohs(old->tuple.dst.u.udp.port);
+ }
}
- /************************ lzh end ******************************************/
+#endif
WRITE_UNLOCK(&ip_conntrack_lock);
return -EEXIST;
}
@@ -1530,6 +1475,7 @@ int __init ip_conntrack_init(void)
unsigned int i;
int ret;
+#if 0
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
* machine has 256 buckets. >= 1GB machines have 8192 buckets. */
if (hashsize) {
@@ -1544,6 +1490,33 @@ int __init ip_conntrack_init(void)
ip_conntrack_htable_size = 16;
}
ip_conntrack_max = 8 * ip_conntrack_htable_size;
+#else
+/*
+
+ sizeof(list_head) = 8
+ x 4096 = 32K
+
+ sizeof(ip_conntrack) = 368
+ x 2048 = 736K
+
+*/
+
+#ifdef TEST_JHASH
+/*
+ if (hashsize) ip_conntrack_htable_size = hashsize;
+ else ip_conntrack_htable_size = 4096;
+ ip_conntrack_max = 2048;
+*/
+ if (hashsize) ip_conntrack_htable_size = hashsize;
+ else ip_conntrack_htable_size = 8092;
+ ip_conntrack_max = 4096;
+#else
+ if (hashsize) ip_conntrack_htable_size = hashsize;
+ else ip_conntrack_htable_size = 4099;
+ ip_conntrack_max = 2048;
+#endif
+
+#endif
printk("ip_conntrack version %s (%u buckets, %d max)"
" - %d bytes per conntrack\n", IP_CONNTRACK_VERSION,
@@ -1605,3 +1578,5 @@ err_unreg_sockopt:
return -ENOMEM;
}
+
+