路由2 【转载: 再议路由初始化 】
1 看源代码,发现路由最初初始化的函数在net/ipv4/route.c 2 int __init ip_rt_init(void) 3 { 4 int rc = 0; 5 6 #ifdef CONFIG_NET_CLS_ROUTE 7 ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct)); 8 if (!ip_rt_acct) 9 panic("IP: failed to allocate ip_rt_acct\n"); 10 #endif 11 12 /*既然是全局变量,肯定很重要*/ 13 ipv4_dst_ops.kmem_cachep = 14 kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0, 15 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); 16 17 ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep; 18 19 /*创建struct rt_hash_bucket 类型的哈希表*/ 20 rt_hash_table = (struct rt_hash_bucket *) 21 alloc_large_system_hash("IP route cache", 22 sizeof(struct rt_hash_bucket), 23 rhash_entries, 24 (num_physpages >= 128 * 1024) ? 15 : 17, 25 0, 26 &rt_hash_log, 27 &rt_hash_mask, 28 0); 29 memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket)); 30 rt_hash_lock_init(); 31 32 /*垃圾回收阀值*/ 33 ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1); 34 ip_rt_max_size = (rt_hash_mask + 1) * 16; 35 36 /*主要的初始化函数*/ 37 devinet_init(); 38 ip_fib_init(); 39 40 /* All the timers, started at system startup tend 41 to synchronize. Perturb it a bit. 42 */ 43 schedule_delayed_work(&expires_work, 44 net_random() % ip_rt_gc_interval + ip_rt_gc_interval); 45 46 if (register_pernet_subsys(&rt_secret_timer_ops)) 47 printk(KERN_ERR "Unable to setup rt_secret_timer\n"); 48 49 if (ip_rt_proc_init()) 50 printk(KERN_ERR "Unable to create route proc files\n"); 51 #ifdef CONFIG_XFRM 52 xfrm_init(); 53 xfrm4_init(); 54 #endif 55 /*注册rtnetlink 消息, 这里是获取路由, 在devinet_init()中还有其他三种消息*/ 56 rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL); 57 58 #ifdef CONFIG_SYSCTL 59 register_pernet_subsys(&sysctl_route_ops); 60 #endif 61 return rc; 62 } 63 64 /* 65 * allocate a large system hash table from bootmem 66 * - it is assumed that the hash table must contain an exact power-of-2 67 * quantity of entries(假定哈希表包含2的指数级的表项) 68 * - limit is the number of hash buckets, not the total allocation size 69 * (limit 是哈希桶的数量, 不是所分配的整个空间的大小) 70 */ 71 void *__init alloc_large_system_hash(const char *tablename, 72 unsigned long bucketsize, 73 unsigned long numentries, 74 int scale, 75 int flags, 76 unsigned int *_hash_shift, 77 unsigned int *_hash_mask, 78 unsigned long limit) 79 80 void __init devinet_init(void) 81 { 82 /*还是初始struct net结构中的部分变量*/ 83 register_pernet_subsys(&devinet_ops); 84 85 register_gifconf(PF_INET, inet_gifconf); 86 /*注册一个通知链,主要处理设备的状态改变*/ 87 register_netdevice_notifier(&ip_netdev_notifier); 88 89 /*另外的两个消息*/ 90 rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL); 91 rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL); 92 rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); 93 } 94 95 这是ip_netdev_notifier的初始化值: 96 static struct notifier_block ip_netdev_notifier = { 97 .notifier_call = inetdev_event, 98 }; 99 100 ip_fib_init()在上一篇中已经介绍过!