2008-07-07 22:05
初始化
1,ip_conntrack_standalone_init是contrack模块的初始化函数。它主要完成以下内容:
/*1, 初始化conntrack相关的数据结构,如hash表,ip_conntrack_protocol以及内存管理等*/
ret = ip_conntrack_init();
if (ret < 0)
return ret;
#ifdef CONFIG_PROC_FS
/* 在/proc目录下创建"ip_conntrack","ip_conntrack_expect"记录连接跟踪信息*/
……
#endif
/*2,为conntrack注册hook点*/
ret = nf_register_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops));
if (ret < 0) {
printk("ip_conntrack: can't register hooks./n");
goto cleanup_proc_stat;
}
#ifdef CONFIG_SYSCTL
/*3,注册sysctrl的操作函数集*/
ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
if (ip_ct_sysctl_header == NULL) {
printk("ip_conntrack: can't register to sysctl./n");
ret = -ENOMEM;
goto cleanup_hooks;
}
#endif
2,ip_conntrack_init:
/*1,完成hash的初始化,hash桶的大小为内存大小的1/16384 ,在i386中,若内存小于32M,hash桶为256个,若大于1G,桶为8196个。Hash表的大小为桶个数的8倍,用ip_conntrack_hash 指针表示*/
if (!ip_conntrack_htable_size) {
ip_conntrack_htable_size
= (((num_physpages << PAGE_SHIFT) / 16384)
/ sizeof(struct list_head));
if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
ip_conntrack_htable_size = 8192;
if (ip_conntrack_htable_size < 16)
ip_conntrack_htable_size = 16;
}
ip_conntrack_max = 8 * ip_conntrack_htable_size;
…
ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size, &ip_conntrack_vmalloc);
/*2, conntrack采用catche的内存管理方式*/
ip_conntrack_cachep = kmem_cache_create("ip_conntrack",
sizeof(struct ip_conntrack), 0,
0, NULL, NULL);
…
ip_conntrack_expect_cachep = kmem_cache_create("ip_conntrack_expect",
sizeof(struct ip_conntrack_expect),
0, 0, NULL, NULL);
…
/*3,初始化ip_ct_protos数组。conntrack对每种协议数据的处理,都有不同的地方,例如,tuple
中提取的内容,TCP的与ICMP的肯定不同的,因为ICMP连端口的概念也没有,所以,对于每种协议的一些特殊处理的函数,需要进行封装,struct ip_conntrack_protocol 结构就实现了这一封装。ip_ct_protos数组记录了个协议所需的私有数据,在初始化工作中,ip_ct_protos默认为ip_conntrack_generic_protoco,而对TCP、UDP和ICMP协议,定义了ip_conntrack_protocol_tcp、ip_conntrack_protocol_udp和ip_conntrack_protocol_icmp,封装至ip_ct_protos 数组。这样,在以后的数据包处理后,就可以根据包中的协议值,使用ip_ct_protos[协议值],找到注册的协议节点,调用协议对应的处理函数了*/
for (i = 0; i < MAX_IP_CT_PROTO; i++)
ip_ct_protos[i] = &ip_conntrack_generic_protocol;
/* Sew in builtin protocols. */
ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp;
ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp;
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
…
/*4,??用于ipt_REJECT,似乎和conntrack记录icmp以及TCP rst错误相关,具体需进一步研究*/
ip_ct_attach = ip_conntrack_attach
/*5,??*/
atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
/* - and look it like as a confirmed connection */ set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);