网络子系统61_路由子系统初始化

//	路由缓存内存量指定办法:
//		1.通过启动参数rhash_entries指定hash表bucket个数
//		2.根据物理内存页数确定使用的内存量

//	根据物理页数分配缓存内存:
//		1.goal目标内存页数=总页数/(2**(26-PAGE_SHIFT))
//		2.最接近goal内存页数的order,用于从伙伴系统中分配
//		3.rt_hash_mask=order页可容纳的bucket数
//		4.对齐rt_hash_mask到2的幂次
//		5.从伙伴系统中分配order页物理内存

//	路由缓存阈值:
//		1.gc_thresh=bucket个数,当路由缓存数超过此阈值时,rt_garbage_collect同步回收内存
//		2.ip_rt_max_size=16*(bucket个数),当路由缓存超过此阈值时,dst_alloc会失败

//	路由子系统初始化
//	调用路径:ip_init->ip_rt_init
//	函数主要任务:
//		1.分配dst缓存的slab缓存
//		2.分配路由缓存表
//		3.向netdev_chain注册监听块
//		4.初始化默认路由表
//		5.初始化路由缓存使用的定时器
//			5.1 垃圾回收定时器
//			5.2 缓存刷新定时器
//			5.3 缓存周期性刷新定时器
//		6.初始化IPSec与路由子系统交互的衔接点
1.1 int __init ip_rt_init(void)
{
	int i, order, goal, rc = 0;
	//
	rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
			     (jiffies ^ (jiffies >> 7)));
	//dst缓存
	ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache",
						     sizeof(struct rtable),
						     0, SLAB_HWCACHE_ALIGN,
						     NULL, NULL);

	//根据物理内存数计算路由缓存使用的内存页数
	goal = num_physpages >> (26 - PAGE_SHIFT);
	if (rhash_entries)//rhash_entries为启动参数,
		goal = (rhash_entries * sizeof(struct rt_hash_bucket)) >> PAGE_SHIFT;
	//计算缓存使用内存页个数以2为底的order
	for (order = 0; (1UL << order) < goal; order++);

	//rt_hash_mask为bucket的个数
	do {
		rt_hash_mask = (1UL << order) * PAGE_SIZE /
			sizeof(struct rt_hash_bucket);
		//使rt_hash_mask 对齐到2的幂次
		while (rt_hash_mask & (rt_hash_mask - 1))
			rt_hash_mask--;

		//分配路由缓存
		rt_hash_table = (struct rt_hash_bucket *)
			__get_free_pages(GFP_ATOMIC, order);
	} while (rt_hash_table == NULL && --order > 0);


	for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++);

	//初始化每个bucket使用的自选锁
	rt_hash_mask--;
	for (i = 0; i <= rt_hash_mask; i++) {
		spin_lock_init(&rt_hash_table[i].lock);
		rt_hash_table[i].chain = NULL;
	}

	//垃圾回收的域值
	ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
	//路由缓存最多保存的缓存个数
	ip_rt_max_size = (rt_hash_mask + 1) * 16;
	//per-cpu统计变量
	rt_cache_stat = alloc_percpu(struct rt_cache_stat);

	//向netdev_chain注册监听块,用netlink为地址和路由命令注册处理函数
	devinet_init();
	//初始化默认路由表
	ip_fib_init();
	//缓存刷新定时器
	init_timer(&rt_flush_timer);
	rt_flush_timer.function = rt_run_flush;
	//垃圾回收定时器
	init_timer(&rt_periodic_timer);
	rt_periodic_timer.function = rt_check_expire;
	//缓存刷新周期定时器
	init_timer(&rt_secret_timer);
	rt_secret_timer.function = rt_secret_rebuild;

	rt_periodic_timer.expires = jiffies + net_random() % ip_rt_gc_interval +
					ip_rt_gc_interval;
	add_timer(&rt_periodic_timer);

	rt_secret_timer.expires = jiffies + net_random() % ip_rt_secret_interval +
		ip_rt_secret_interval;
	add_timer(&rt_secret_timer);

	//处理路由子系统与IPSec的衔接
#ifdef CONFIG_XFRM
	xfrm_init();
	xfrm4_init();
#endif
	return rc;
}
//	监听外部事件
//	调用路径:ip_rt_init->devinet_init
1.2 void __init devinet_init(void)
{
	//netdev_chian监听块
	register_netdevice_notifier(&ip_netdev_notifier);
	//通过netlink为路由命令注册处理程序
	rtnetlink_links[PF_INET] = inet_rtnetlink_table;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值