diff -pruN a/net/netfilter/Kconfig b/net/netfilter/Kconfig --- a/net/netfilter/Kconfig 2007-10-09 23:31:38.000000000 +0300 +++ b/net/netfilter/Kconfig 2008-02-02 12:13:01.000000000 +0200 @@ -353,6 +353,12 @@ config NETFILTER_XT_TARGET_NOTRACK If you want to compile it as a module, say M here and read . If unsure, say `N'. +config NETFILTER_XT_TARGET_NOTRACK_NEW + bool "NOTRACK safe (only new)" + depends on NETFILTER_XT_TARGET_NOTRACK + help + Slow but safe way to NOTRACK only new/untracked connections. + config NETFILTER_XT_TARGET_TRACE tristate '"TRACE" target support' depends on NETFILTER_XTABLES diff -pruN a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c --- a/net/netfilter/nf_conntrack_core.c 2007-10-09 23:31:38.000000000 +0300 +++ b/net/netfilter/nf_conntrack_core.c 2008-02-02 12:14:51.000000000 +0200 @@ -589,20 +589,38 @@ resolve_normal_ct(struct sk_buff *skb, struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; +#ifdef CONFIG_NETFILTER_XT_TARGET_NOTRACK_NEW + struct nf_conntrack_expect *exp; +#endif if (!nf_ct_get_tuple(skb, skb_network_offset(skb), dataoff, l3num, protonum, &tuple, l3proto, l4proto)) { pr_debug("resolve_normal_ct: Can't get tuple\n"); + NF_CT_STAT_INC_ATOMIC(invalid); return NULL; } /* look for tuple match */ h = nf_conntrack_find_get(&tuple); if (!h) { +#ifdef CONFIG_NETFILTER_XT_TARGET_NOTRACK_NEW + if(skb->nfctinfo == IP_CT_NEW) { + exp = nf_ct_expect_find_get(&tuple); + if(!exp){ + skb->nfct = &nf_conntrack_untracked.ct_general; + nf_conntrack_get(skb->nfct); + NF_CT_STAT_INC_ATOMIC(ignore); + return NULL; + } + nf_ct_expect_put(exp); + } +#endif h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff); - if (!h) + if (!h) { + NF_CT_STAT_INC_ATOMIC(invalid); return NULL; + } if (IS_ERR(h)) return (void *)h; } @@ -678,7 +696,6 @@ nf_conntrack_in(int pf, unsigned int hoo &set_reply, &ctinfo); if (!ct) { /* Not valid part of a connection */ - NF_CT_STAT_INC_ATOMIC(invalid); return NF_ACCEPT; } diff -pruN a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c --- a/net/netfilter/xt_NOTRACK.c 2007-10-09 23:31:38.000000000 +0300 +++ b/net/netfilter/xt_NOTRACK.c 2008-02-02 12:13:01.000000000 +0200 @@ -22,6 +22,9 @@ target(struct sk_buff **pskb, if ((*pskb)->nfct != NULL) return XT_CONTINUE; +#ifdef CONFIG_NETFILTER_XT_TARGET_NOTRACK_NEW + (*pskb)->nfctinfo = IP_CT_NEW; +#else /* Attach fake conntrack entry. If there is a real ct entry correspondig to this packet, it'll hang aroun till timing out. We don't deal with it @@ -29,6 +32,7 @@ target(struct sk_buff **pskb, (*pskb)->nfct = &nf_conntrack_untracked.ct_general; (*pskb)->nfctinfo = IP_CT_NEW; nf_conntrack_get((*pskb)->nfct); +#endif return XT_CONTINUE; }