这篇文章主要分析inet_init()函数的实现过程:
1796 static int __init inet_init(void) 1797 { 1798 struct inet_protosw *q; 1799 struct list_head *r; 1800 int rc = -EINVAL; 1801 1802 sock_skb_cb_check_size(sizeof(struct inet_skb_parm)); 1803 1804 rc = proto_register(&tcp_prot, 1); 1805 if (rc) 1806 goto out; 1807 1808 rc = proto_register(&udp_prot, 1); 1809 if (rc) 1810 goto out_unregister_tcp_proto; 1811 1812 rc = proto_register(&raw_prot, 1); 1813 if (rc) 1814 goto out_unregister_udp_proto; 1815 1816 rc = proto_register(&ping_prot, 1); 1817 if (rc) 1818 goto out_unregister_raw_proto; 1820 /* 1821 * Tell SOCKET that we are alive... 1822 */ 1823 1824 (void)sock_register(&inet_family_ops); 1825 1826 #ifdef CONFIG_SYSCTL 1827 ip_static_sysctl_init(); 1828 #endif 1829 1830 /* 1831 * Add all the base protocols. 1832 */ 1833 1834 if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0) 1835 pr_crit("%s: Cannot add ICMP protocol\n", __func__); 1836 if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0) 1837 pr_crit("%s: Cannot add UDP protocol\n", __func__); 1838 if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0) 1839 pr_crit("%s: Cannot add TCP protocol\n", __func__); 1840 #ifdef CONFIG_IP_MULTICAST 1841 if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0) 1842 pr_crit("%s: Cannot add IGMP protocol\n", __func__); 1843 #endif 1844 1845 /* Register the socket-side information for inet_create. */ 1846 for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r) 1847 INIT_LIST_HEAD(r); 1848 1849 for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q) 1850 inet_register_protosw(q); 1852 /* 1853 * Set the ARP module up 1854 */ 1855 1856 arp_init(); 1857 1858 /* 1859 * Set the IP module up 1860 */ 1861 1862 ip_init(); 1863 1864 /* Setup TCP slab cache for open requests. */ 1865 tcp_init(); 1866 1867 /* Setup UDP memory threshold */ 1868 udp_init(); 1869 1870 /* Add UDP-Lite (RFC 3828) */ 1871 udplite4_register(); 1872 1873 ping_init(); 1874 1875 /* 1876 * Set the ICMP layer up 1877 */ 1878 1879 if (icmp_init() < 0) 1880 panic("Failed to create the ICMP control socket.\n"); 1881 1882 /* 1883 * Initialise the multicast router 1884 */ 1885 #if defined(CONFIG_IP_MROUTE) 1886 if (ip_mr_init()) 1887 pr_crit("%s: Cannot init ipv4 mroute\n", __func__); 1888 #endif 1889 1890 if (init_inet_pernet_ops()) 1891 pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__); 1892 /* 1893 * Initialise per-cpu ipv4 mibs 1894 */ 1895 1896 if (init_ipv4_mibs()) 1897 pr_crit("%s: Cannot init ipv4 mibs\n", __func__); 1898 1899 ipv4_proc_init(); 1900 1901 ipfrag_init(); 1902 1903 dev_add_pack(&ip_packet_type); 1904 1905 ip_tunnel_core_init(); 1906 1907 rc = 0; 1908 out: 1909 return rc; 1910 out_unregister_raw_proto: 1911 proto_unregister(&raw_prot); 1912 out_unregister_udp_proto: 1913 proto_unregister(&udp_prot); 1914 out_unregister_tcp_proto: 1915 proto_unregister(&tcp_prot); 1916 goto out; 1917 } 1918 1919 fs_initcall(inet_init);其他函数在前面的都介绍过了,这篇文章我们主要介绍下面几个函数:
1856 arp_init(); 1857 1858 /* 1859 * Set the IP module up 1860 */ 1861 1862 ip_init(); 1863 1864 /* Setup TCP slab cache for open requests. */ 1865 tcp_init(); 1866 1867 /* Setup UDP memory threshold */ 1868 udp_init(); 1869 1870 /* Add UDP-Lite (RFC 3828) */ 1871 udplite4_register(); 1872 1873 ping_init(); 1874 1875 /* 1876 * Set the ICMP layer up 1877 */ 1878 1879 if (icmp_init() < 0) 1880 panic("Failed to create the ICMP control socket.\n"); 1881 1882 /* 1883 * Initialise the multicast router 1884 */ 1885 #if defined(CONFIG_IP_MROUTE) 1886 if (ip_mr_init()) 1887 pr_crit("%s: Cannot init ipv4 mroute\n", __func__); 1888 #endif 1889 1890 if (init_inet_pernet_ops()) 1891 pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__); 1892 /* 1893 * Initialise per-cpu ipv4 mibs 1894 */ 1895 1896 if (init_ipv4_mibs()) 1897 pr_crit("%s: Cannot init ipv4 mibs\n", __func__); 1898 1899 ipv4_proc_init(); 1900 1901 ipfrag_init(); 1902 1903 dev_add_pack(&ip_packet_type); 1904 1905 ip_tunnel_core_init();同时也完成/proc/net/arp文件的初始化。
tcp的初始化内容比较多,后面单独讲
它最后调用inet_init_net(struct net *net)完成以下网路命名空间的初始化,每一个网络设备都会有一个网络命名空间,比如eth1, ath0等,可以查看这里了解。
前面说了,每一个网络接口都对应着一个网络命名空间,这些网路空间串联在一个由”struct net”对象组成的结构体中,该函数完成这些空间数据统计的一些信息初始化。
static __net_init int ipv4_mib_init_net(struct net *net) { int i; net->mib.tcp_statistics = alloc_percpu(struct tcp_mib); if (!net->mib.tcp_statistics) goto err_tcp_mib; net->mib.ip_statistics = alloc_percpu(struct ipstats_mib); if (!net->mib.ip_statistics) goto err_ip_mib; for_each_possible_cpu(i) { struct ipstats_mib *af_inet_stats; af_inet_stats = per_cpu_ptr(net->mib.ip_statistics, i); u64_stats_init(&af_inet_stats->syncp); } net->mib.net_statistics = alloc_percpu(struct linux_mib); if (!net->mib.net_statistics) goto err_net_mib; net->mib.udp_statistics = alloc_percpu(struct udp_mib); if (!net->mib.udp_statistics) goto err_udp_mib; net->mib.udplite_statistics = alloc_percpu(struct udp_mib); if (!net->mib.udplite_statistics) goto err_udplite_mib; net->mib.icmp_statistics = alloc_percpu(struct icmp_mib); if (!net->mib.icmp_statistics) goto err_icmp_mib; net->mib.icmpmsg_statistics = kzalloc(sizeof(struct icmpmsg_mib), GFP_KERNEL); if (!net->mib.icmpmsg_statistics) goto err_icmpmsg_mib; tcp_mib_init(net);IP分片的初始化,其中指定了对应动作所调用的函数
void __init ipfrag_init(void) { ip4_frags_ctl_register(); register_pernet_subsys(&ip4_frags_ops); ip4_frags.hashfn = ip4_hashfn; ip4_frags.constructor = ip4_frag_init; ip4_frags.destructor = ip4_frag_free; ip4_frags.qsize = sizeof(struct ipq); ip4_frags.match = ip4_frag_match; ip4_frags.frag_expire = ip_expire; ip4_frags.frags_cache_name = ip_frag_cache_name; if (inet_frags_init(&ip4_frags)) panic("IP: failed to allocate ip4_frags cache\n"); }在proc的ipv4目录下,会根据不同的协议创建不同的文件
static int __init ipv4_proc_init(void) { int rc = 0; if (raw_proc_init()) goto out_raw; if (tcp4_proc_init()) goto out_tcp; if (udp4_proc_init()) goto out_udp; if (ping_proc_init()) goto out_ping; if (ip_misc_proc_init()) goto out_misc;root:/proc/213/net# cat tcp sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 0: 00000000:8240 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 18057 1 d9aa0000 100 0 0 10 0 1: FA01A8C0:C000 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 10027 1 d9828000 100 0 0 10 0 2: 00000000:4E25 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 18624 1 d86b8000 100 0 0 10 0 3: 00000000:0D05 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 3566 1 de690500 100 0 0 10 0 4: 0100007F:1E6B 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 16883 1 d9828500 100 0 0 10 0 5: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 3548 1 de690000 100 0 0 10 0 6: 00000000:15B3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 10551287 1 d86bc600 100 0 0 10 0 7: 00000000:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 18632 1 d86b8500 100 0 0 10 0 8: 0100007F:DAEA 0100007F:0050 06 00000000:00000000 03:00000640 00000000 0 0 0 3 d86c7d80 9: FA01A8C0:A668 0A01A8C0:0B35 06 00000000:00000000 03:000011B2 00000000 0 0 0 3 de52c000 10: FA01A8C0:A664 0A01A8C0:0B35 06 00000000:00000000 03:0000107F 00000000 0 0 0 3 de52ca80 11: FA01A8C0:A669 0A01A8C0:0B35 06 00000000:00000000 03:000011B1 00000000 0 0 0 3 de52c180 12: FA01A8C0:A66A 0A01A8C0:0B35 06 00000000:00000000 03:000011B1 00000000 0 0 0 3 de52c480 13: FA01A8C0:A670 0A01A8C0:0B35 06 00000000:00000000 03:000014B9 00000000 0 0 0 3 d9fb3cc0 14: FA01A8C0:A64B 0A01A8C0:0B35 06 00000000:00000000 03:00000216 00000000 0 0 0 3 d9fb3e40
也许你会问路径里面的213是什么,应该是不同的name space 吧