我是靠谱客的博主 漂亮万宝路,最近开发中收集的这篇文章主要介绍连接跟踪子系统之初始化1. 初始化入口:nf_conntrack_standalone_init()2. 核心初始化:nf_conntrack_init()3. 内核变量(未完待补充),觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
这篇笔记记录了连接跟踪子系统的初始化过程,从初始化过程中可以了解到连接跟踪子系统由哪些子模块组成。初始化涉及的核心代码文件有:
代码路径 | 说明 |
---|---|
net/netfilter/nf_conntrack_standalone.c | 连接跟踪子系统的初始化入口 |
net/netfilter/nf_conntrack_core.c | 连接跟踪子系统框架的核心部分 |
1. 初始化入口:nf_conntrack_standalone_init()
static int __init nf_conntrack_standalone_init(void)
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
int ret = 0;
//连接跟踪子系统的核心初始化过程
ret = nf_conntrack_init();
if (ret < 0)
return ret;
#ifdef CONFIG_PROC_FS
//创建/proc/net/nf_conntrack文件,该文件只读,
//读取该文件可以获取当前内核中跟踪的所有连接的信息
proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops);
if (!proc)
goto cleanup_init;
//创建/proc/net/stat/nf_conntrack文件,获取连接跟踪子系统的统计信息
if (!proc_create("nf_conntrack", S_IRUGO, init_net.proc_net_stat, &ct_cpu_seq_fops))
goto cleanup_proc;
#endif
#ifdef CONFIG_SYSCTL
//在/proc/sys/net/netfilter子目录,暴露一部分内核变量给用户态
nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table);
if (nf_ct_sysctl_header == NULL) {
printk("nf_conntrack: can't register to sysctl.n");
ret = -ENOMEM;
goto cleanup_proc_stat;
}
#endif
return ret;
...
}
可以看出,nf_conntrack_standalone_init()除了在/proc文件系统下面创建一些节点外,核心的初始化过程都是调用nf_conntrack_init()完成的。
2. 核心初始化:nf_conntrack_init()
int __init nf_conntrack_init(void)
{
int max_factor = 8;
int ret;
//根据系统内存大小确定连接跟踪哈希桶的大小
if (!nf_conntrack_htable_size) {
nf_conntrack_htable_size = (((num_physpages << PAGE_SHIFT) / 16384)
/ sizeof(struct hlist_head));
if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
nf_conntrack_htable_size = 16384;
if (nf_conntrack_htable_size < 32)
nf_conntrack_htable_size = 32;
/* Use a max. factor of four by default to get the same max as
* with the old struct list_heads. When a table size is given
* we use the old value of 8 to avoid reducing the max.
* entries. */
max_factor = 4;
}
//为nf_conntrack_hash分配空间,桶的个数就是nf_conntrack_htable_size
nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
&nf_conntrack_vmalloc);
if (!nf_conntrack_hash)
goto err_out;
//最大能够跟踪的连接数是哈希桶的整数倍(8倍或4倍),这种限制是为了
//防止冲突过多影响了数据包的处理效率
nf_conntrack_max = max_factor * nf_conntrack_htable_size;
//为连接跟踪信息块struct nf_conn创建高速缓存
nf_conntrack_cachep =
kmem_cache_create("nf_conntrack", sizeof(struct nf_conn), 0, 0, NULL);
if (!nf_conntrack_cachep)
goto err_free_hash;
//初始化协议管理子模块
ret = nf_conntrack_proto_init();
if (ret < 0)
goto err_free_conntrack_slab;
//初始化期望连接子模块
ret = nf_conntrack_expect_init();
if (ret < 0)
goto out_fini_proto;
//初始化helper子模块
ret = nf_conntrack_helper_init();
if (ret < 0)
goto out_fini_expect;
/* For use by REJECT target */
rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
//destroy_conntrack()函数将会在连接跟踪信息块被销毁时调用
rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
//构造一个假的连接,该假连接不会出现在全局的哈希表中
atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
return ret;
...
}
2.1 协议管理子模块初始化:nf_conntrack_proto_init()
协议管理子模块的分析见笔记连接跟踪子系统之L3L4协议管理。
2.2 期望连接子模块初始化:nf_conntrack_expect_init()
helper子模块的分析见笔记连接跟踪子系统之期望连接。
2.3 helper子模块初始化:nf_conntrack_helper_init()
helper子模块的分析见笔记连接跟踪子系统之helper。
3. 内核变量(未完待补充)
通过/proc/sys/net/netfilter目录,用户态可以操作一部分内核变量,进而改变内核的配置,在一定程度上提供了配置的灵活性。在连接跟踪子系统初始化过程中,涉及如下内核变量:
- nf_conntrack_max:路径为/proc/sys/net/netfilter/nf_conntrack_max。表示内核同时能够跟踪的最大连接个数;
- nf_conntrack_count:路径为/proc/sys/net/netfilter/nf_conntrack_count。表示内核中当前跟踪了多少条连接;
- nf_conntrack_buckets:路径为/proc/sys/net/netfilter/nf_conntrack_buckets。
- nf_conntrack_checksum
- nf_conntrack_log_invalid
- nf_conntrack_expect_max
最后
以上就是漂亮万宝路为你收集整理的连接跟踪子系统之初始化1. 初始化入口:nf_conntrack_standalone_init()2. 核心初始化:nf_conntrack_init()3. 内核变量(未完待补充)的全部内容,希望文章能够帮你解决连接跟踪子系统之初始化1. 初始化入口:nf_conntrack_standalone_init()2. 核心初始化:nf_conntrack_init()3. 内核变量(未完待补充)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复