连接跟踪子系统之初始化

这篇笔记记录了连接跟踪子系统的初始化过程,从初始化过程中可以了解到连接跟踪子系统由哪些子模块组成。初始化涉及的核心代码文件有:

代码路径说明
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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值