diff -urN linux-2.4.10-wt1-1/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.10-wt1/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.4.10-wt1-1/include/linux/netfilter_ipv4/ip_conntrack.h Sun Oct 7 19:46:08 2001 +++ linux-2.4.10-wt1/include/linux/netfilter_ipv4/ip_conntrack.h Sun Oct 7 19:46:44 2001 @@ -209,5 +209,8 @@ } extern unsigned int ip_conntrack_htable_size; + +/* A fake conntrack which never vanishes. */ +extern struct ip_conntrack untracked_conntrack; #endif /* __KERNEL__ */ #endif /* _IP_CONNTRACK_H */ diff -urN linux-2.4.10-wt1-1/net/ipv4/netfilter/Config.in linux-2.4.10-wt1/net/ipv4/netfilter/Config.in --- linux-2.4.10-wt1-1/net/ipv4/netfilter/Config.in Sun Oct 7 19:46:07 2001 +++ linux-2.4.10-wt1/net/ipv4/netfilter/Config.in Sun Oct 7 19:48:31 2001 @@ -45,6 +45,10 @@ dep_tristate ' Connection state match support' CONFIG_IP_NF_MATCH_STATE $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES dep_tristate ' RPC match support' CONFIG_IP_NF_MATCH_RPC $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES dep_tristate ' Connections/IP limit match support' CONFIG_IP_NF_MATCH_IPLIMIT $CONFIG_IP_NF_IPTABLES + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' notrack table support (EXPERIMENTAL)' CONFIG_IP_NF_NOMATCH $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES + dep_tristate ' NOTRACK target support (EXPERIMENTAL)' CONFIG_IP_NF_TARGET_NOMATCH $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES + fi fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES diff -urN linux-2.4.10-wt1-1/net/ipv4/netfilter/Makefile linux-2.4.10-wt1/net/ipv4/netfilter/Makefile --- linux-2.4.10-wt1-1/net/ipv4/netfilter/Makefile Sun Oct 7 19:45:57 2001 +++ linux-2.4.10-wt1/net/ipv4/netfilter/Makefile Sun Oct 7 19:46:43 2001 @@ -47,10 +47,11 @@ # generic IP tables obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o -# the three instances of ip_tables +# the four instances of ip_tables obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o +obj-$(CONFIG_IP_NF_NOMATCH) += iptable_nomatch.o # matches obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o @@ -103,6 +104,7 @@ obj-$(CONFIG_IP_NF_TARGET_NETLINK) += ipt_NETLINK.o obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o +obj-$(CONFIG_IP_NF_TARGET_NOMATCH) += ipt_NOMATCH.o # backwards compatibility obj-$(CONFIG_IP_NF_COMPAT_IPCHAINS) += ipchains.o diff -urN linux-2.4.10-wt1-1/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.10-wt1/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.10-wt1-1/net/ipv4/netfilter/ip_conntrack_core.c Sun Oct 7 19:46:07 2001 +++ linux-2.4.10-wt1/net/ipv4/netfilter/ip_conntrack_core.c Sun Oct 7 19:46:44 2001 @@ -54,6 +54,7 @@ static atomic_t ip_conntrack_count = ATOMIC_INIT(0); struct list_head *ip_conntrack_hash; static kmem_cache_t *ip_conntrack_cachep; +struct ip_conntrack untracked_conntrack; extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; @@ -1200,5 +1201,9 @@ /* For use by ipt_REJECT */ ip_ct_attach = ip_conntrack_attach; + + /* Set up fake conntrack to never be deleted, not in any hashes */ + untracked_conntrack.ct_general.use = ATOMIC_INIT(1); + return ret; } diff -urN linux-2.4.10-wt1-1/net/ipv4/netfilter/ip_nat_core.c linux-2.4.10-wt1/net/ipv4/netfilter/ip_nat_core.c --- linux-2.4.10-wt1-1/net/ipv4/netfilter/ip_nat_core.c Sun Oct 7 19:45:57 2001 +++ linux-2.4.10-wt1/net/ipv4/netfilter/ip_nat_core.c Sun Oct 7 19:46:44 2001 @@ -889,6 +889,10 @@ if (ip_conntrack_notify_register(&nat_notify) < 0) panic("ip_nat_init: cannot register notifier.\n"); + /* Initialize fake conntrack for "no NAT": other fields are 0, + and that's OK. */ + untracked_conntrack.nat.info.initialized = -1; + return 0; } diff -urN linux-2.4.10-wt1-1/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.4.10-wt1/net/ipv4/netfilter/ipt_NOTRACK.c --- linux-2.4.10-wt1-1/net/ipv4/netfilter/ipt_NOTRACK.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.10-wt1/net/ipv4/netfilter/ipt_NOTRACK.c Sun Oct 7 19:46:44 2001 @@ -0,0 +1,60 @@ +/* This is a module which is used for setting up fake conntracks on + packets so that they are not seen by the tracking code. */ +#include +#include + +static unsigned int +target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + if ((*pskb)->nfct == NULL) { + (*pskb)->nfct = &untracked_conntrack.ct_general; + nf_conntrack_get((*pskb)->nfct); + } + return IPT_ACCEPT; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != 0) { + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", + targinfosize); + return 0; + } + + if (strcmp(tablename, "notrack") != 0) { + printk(KERN_WARNING "NOTRACK: can only be called from" + " \"notrack\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_notrack_reg += { { NULL, NULL }, "NOTRACK", target, checkentry, NULL, THIS_MODULE }; + +static int __init init(void) +{ + if (ipt_register_target(&ipt_notrack_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_notrack_reg); +} + +module_init(init); +module_exit(fini); diff -urN linux-2.4.10-wt1-1/net/ipv4/netfilter/iptable_notrack.c linux-2.4.10-wt1/net/ipv4/netfilter/iptable_notrack.c --- linux-2.4.10-wt1-1/net/ipv4/netfilter/iptable_notrack.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.10-wt1/net/ipv4/netfilter/iptable_notrack.c Sun Oct 7 19:46:44 2001 @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2001 Paul `Rusty' Russell. + * This assigns a fake conntrack to packets, so conntrack code doesn't + * see them. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define NOTRACK_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING)| (1 << NF_IP_LOCAL_OUT)) + +/* Standard entry. */ +struct ipt_standard +{ + struct ipt_entry entry; + struct ipt_standard_target target; +}; + +struct ipt_error_target +{ + struct ipt_entry_target target; + char errorname[IPT_FUNCTION_MAXNAMELEN]; +}; + +struct ipt_error +{ + struct ipt_entry entry; + struct ipt_error_target target; +}; + +static struct +{ + struct ipt_replace repl; + struct ipt_standard entries[2]; + struct ipt_error term; +} initial_table __initdata += { { "notrack", NOTRACK_VALID_HOOKS, 3, + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), + { [NF_IP_PRE_ROUTING] 0, + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, + { [NF_IP_PRE_ROUTING] 0, + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, + 0, NULL, { } }, + { + /* PRE_ROUTING */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_standard), + 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + }, + /* ERROR */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_error), + 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, + { } }, + "ERROR" + } + } +}; + +static struct ipt_table packet_notracker += { { NULL, NULL }, "notrack", &initial_table.repl, + NOTRACK_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL }; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ipt_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ipt_do_table(pskb, hook, in, out, &packet_notrack, NULL); +} + +/* We need to run just before conntrack */ +static struct nf_hook_ops ipt_ops[] += { { { NULL, NULL }, ipt_hook, PF_INET, NF_IP_PRE_ROUTING, + NF_IP_PRI_CONNTRACK-1 }, + { { NULL, NULL }, ipt_local_out_hook, PF_INET, NF_IP_LOCAL_OUT, + NF_IP_PRI_CONNTRACK-1 } +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ipt_register_table(&packet_mangler); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ipt_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ipt_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ipt_ops[0]); + cleanup_table: + ipt_unregister_table(&packet_mangler); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ipt_ops[i]); + + ipt_unregister_table(&packet_mangler); +} + +module_init(init); +module_exit(fini);