Linux体系NAT实现机制的进级改造
cleanup_rule_init: ... } static void __exit nf_nat_standalone_fini(void) { ////////////////////////// #ifdef CONFIG_SYSCTL unregister_sysctl_table(nat_sysctl_header); nat_sysctl_header = NULL; #endif ////////////////////////// ... } 说明:为NAT的Netflter的HOOK函数添加何时执行NAT的判断逻辑。 net/ipv4/netfilter/nf_nat_rule.c int nf_nat_rule_find(struct sk_buff *skb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, struct nf_conn *ct) { struct net *net = nf_ct_net(ct); int ret; ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table); if (ret == NF_ACCEPT) { /////////////######## if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)) || test_bit(NF_FORCE_NAT_BIT, &ct->status)) { /////////////######## ////////////////////////// //如果在ipt_do_table中没有匹配到NAT规则,并且此时允许重新NAT,则说明要把反向五元组还原成原始的反向五元组 //本来想在这里做一个优化的,即如果还原了之后,在新的NAT配置上来之前,不再执行还原操作,然而这样会有问题, //注意本文第一节,由于不能保证其它的数据流是否做了NAT从而占据了不该占据的五元组,为了保证唯一性,这里的 //alloc_null_binding必须持续调用,唯一可以优化的地方在于可以不用每次都调用nf_ct_invert_tuplepr以及 //nf_conntrack_alter_reply,而这只需要一个flag位即可。 /* NUL mapping */ if (nf_ct_is_confirmed(ct)) { struct nf_conntrack_tuple reply; nf_ct_invert_tuplepr(&reply, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); nf_conntrack_alter_reply(ct, &reply); } ////////////////////////// ret = alloc_null_binding(ct, hooknum); } } return ret; } 说明:nf_nat_rule_find中如果没有找到规则,则判断是否是将已有规则删除了,进而恢复原始状态。 net/ipv4/netfilter/nf_nat_core.c unsigned int nf_nat_setup_info(struct nf_conn *ct, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype) { ... /////////////######## 查看本栏目更多精彩内容:http://www.bianceng.cn/OS/Linux/ //bug仅仅on BUG_ON(!test_bit(NF_FORCE_NAT_BIT, &ct->status) && nf_nat_initialized(ct, maniptype)); /////////////######## ... nf_ct_invert_tuplepr(&reply, &new_tuple); ////////////////////////// if (nf_ct_is_confirmed(ct)) { spin_lock_bh(&nf_conntrack_lock); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode); } ////////////////////////// nf_conntrack_alter_reply(ct, &reply); ////////////////////////// if (nf_ct_is_confirmed(ct)) { nf_conntrack_hash_insert(ct); spin_unlock_bh(&nf_conntrack_lock); } ////////////////////////// ... ////////////////////////// clear_bit(NF_FORCE_NAT_BIT, &ct->status); ////////////////////////// (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |