--- zzzz-none-000/linux-2.4.17/net/ipv4/netfilter/ip_nat_standalone.c 2001-09-30 19:26:08.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/net/ipv4/netfilter/ip_nat_standalone.c 2004-11-24 13:22:08.000000000 +0000 @@ -5,7 +5,12 @@ */ /* (c) 1999 Paul `Rusty' Russell. Licenced under the GNU General - Public Licence. */ + * Public Licence. + * + * 23 Apr 2001: Harald Welte + * - new API and handling of conntrack/nat helpers + * - now capable of multiple expectations for one master + * */ #include #include @@ -41,7 +46,17 @@ #define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \ : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \ : ((hooknum) == NF_IP_LOCAL_OUT ? "LOCAL_OUT" \ - : "*ERROR*"))) + : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \ + : "*ERROR*"))) + +static inline int call_expect(struct ip_conntrack *master, + struct sk_buff **pskb, + unsigned int hooknum, + struct ip_conntrack *ct, + struct ip_nat_info *info) +{ + return master->nat.info.helper->expect(pskb, hooknum, ct, info); +} static unsigned int ip_nat_fn(unsigned int hooknum, @@ -94,6 +109,12 @@ } /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */ case IP_CT_NEW: +#ifdef CONFIG_IP_NF_NAT_LOCAL + /* LOCAL_IN hook doesn't have a chain and thus doesn't care + * about new packets -HW */ + if (hooknum == NF_IP_LOCAL_IN) + return NF_ACCEPT; +#endif info = &ct->nat.info; WRITE_LOCK(&ip_nat_lock); @@ -103,8 +124,16 @@ int in_hashes = info->initialized; unsigned int ret; - ret = ip_nat_rule_find(pskb, hooknum, in, out, - ct, info); + if (ct->master + && master_ct(ct)->nat.info.helper + && master_ct(ct)->nat.info.helper->expect) { + ret = call_expect(master_ct(ct), pskb, + hooknum, ct, info); + } else { + ret = ip_nat_rule_find(pskb, hooknum, in, out, + ct, info); + } + if (ret != NF_ACCEPT) { WRITE_UNLOCK(&ip_nat_lock); return ret; @@ -232,6 +261,11 @@ static struct nf_hook_ops ip_nat_local_out_ops = { { NULL, NULL }, ip_nat_local_fn, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_NAT_DST }; +#ifdef CONFIG_IP_NF_NAT_LOCAL +static struct nf_hook_ops ip_nat_local_in_ops += { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_NAT_SRC }; +#endif + /* Protocol registration. */ int ip_nat_protocol_register(struct ip_nat_protocol *proto) { @@ -300,6 +334,13 @@ printk("ip_nat_init: can't register local out hook.\n"); goto cleanup_outops; } +#ifdef CONFIG_IP_NF_NAT_LOCAL + ret = nf_register_hook(&ip_nat_local_in_ops); + if (ret < 0) { + printk("ip_nat_init: can't register local in hook.\n"); + goto cleanup_localoutops; + } +#endif if (ip_conntrack_module) __MOD_INC_USE_COUNT(ip_conntrack_module); return ret; @@ -307,6 +348,10 @@ cleanup: if (ip_conntrack_module) __MOD_DEC_USE_COUNT(ip_conntrack_module); +#ifdef CONFIG_IP_NF_NAT_LOCAL + nf_unregister_hook(&ip_nat_local_in_ops); + cleanup_localoutops: +#endif nf_unregister_hook(&ip_nat_local_out_ops); cleanup_outops: nf_unregister_hook(&ip_nat_out_ops); @@ -335,12 +380,11 @@ module_exit(fini); EXPORT_SYMBOL(ip_nat_setup_info); +EXPORT_SYMBOL(ip_nat_protocol_register); +EXPORT_SYMBOL(ip_nat_protocol_unregister); EXPORT_SYMBOL(ip_nat_helper_register); EXPORT_SYMBOL(ip_nat_helper_unregister); -EXPORT_SYMBOL(ip_nat_expect_register); -EXPORT_SYMBOL(ip_nat_expect_unregister); EXPORT_SYMBOL(ip_nat_cheat_check); EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); -EXPORT_SYMBOL(ip_nat_seq_adjust); -EXPORT_SYMBOL(ip_nat_delete_sack); +EXPORT_SYMBOL(ip_nat_used_tuple); MODULE_LICENSE("GPL");