最详细的Linux TCP/IP 协议栈源码分析( 三 )
void __init sock_init(void) { int i;printk(KERN_INFO "Linux NET4.0 for Linux 2.4/n"); printk(KERN_INFO "Based upon Swansea University Computer Society NET3.039/n");/** Initialize all address (protocol) families. 每一项表示的是针对一个地址族的操作集合 , 例如对于ipv4来说 , 在net/ipv4/af_inet.c文件中的函数inet_proto_init()就调用sock_register()函数将inet_families_ops初始化到属于IPV4的net_families数组中的一项 。*/ for (i = 0; i < NPROTO; i++)net_families[i] = NULL; /** Initialize sock SLAB cache.初始化对于sock结构预留的内存的slab缓存 。*/ sk_init();#ifdef SLAB_SKB /** Initialize skbuff SLAB cache 初始化对于skbuff结构的slab缓存 。 以后对于skbuff的申请可以通过函数kmem_cache_alloc()在这个缓存中申请空间 。*/ skb_init(); #endif/** Wan router layer.*/#ifdef CONFIG_WAN_ROUTERwanrouter_init(); #endif/** Initialize the protocols module. 向系统登记sock文件系统 , 并且将其安装到系统上来 。*/register_filesystem( sock_mnt = kern_mount( /* The real protocol initialization is performed when*do_initcalls is run.*//** The netlink device handler may be needed early.*/#ifdef CONFIG_NET rtnetlink_init(); #endif #ifdef CONFIG_NETLINK_DEV init_netlink(); #endif #ifdef CONFIG_NETFILTER netfilter_init(); #endif#ifdef CONFIG_BLUEZ bluez_init(); #endif/*yfhuang ipsec*/ #ifdef CONFIG_IPSECpfkey_init(); #endif /*yfhuang ipsec*/ }
2.2 do_initcalls() 中做了其它的初始化 , 其中包括
协议初始化 , 路由初始化 , 网络接口设备初始化
(例如inet_init函数以_init开头表示是系统初始化时做 , 函数结束后跟module_init(inet_init),这是一个宏 , 在include/linux/init.c中定义 , 展开为_initcall(inet_init),表示这个函数在do_initcalls被调用了)
2.3 协议初始化
此处主要列举inet协议的初始化过程 。
static int __init inet_init(void) { struct sk_buff *dummy_skb; struct inet_protocol *p; struct inet_protosw *q; struct list_head *r;printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0/n");if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) {printk(KERN_CRIT "inet_proto_init: panic/n");return -EINVAL; }/** Tell SOCKET that we are alive... 注册socket , 告诉socket inet类型的地址族已经准备好了*/(void) sock_register(/** Add all the protocols. 包括arp,ip、ICMP、UPD、tcp_v4、tcp、igmp的初始化 , 主要初始化各种协议对应的inode和socket变量 。 其中arp_init完成系统中路由部分neighbour表的初始化ip_init完成ip协议的初始化 。 在这两个函数中 , 都通过定义一个packet_type结构的变量将这种数据包对应的协议发送数据、允许发送设备都做初始化 。*/printk(KERN_INFO "IP Protocols: "); for (p = inet_protocol_base; p != NULL;) {struct inet_protocol *tmp = (struct inet_protocol *) p->next;inet_add_protocol(p);printk("%s%s",p->name,tmp?", ":"/n");p = tmp; }/* Register the socket-side information for inet_create. */ for(r =r <++r)INIT_LIST_HEAD(r);for(q = inetsw_array; q <++q)inet_register_protosw(q);/** Set the ARP module up*/arp_init();/** Set the IP module up*/ip_init();tcp_v4_init(/* Setup TCP slab cache for open requests. */ tcp_init();/** Set the ICMP layer up*/icmp_init(/* I wish inet_add_protocol had no constructor hook...I had to move IPIP from net/ipv4/protocol.c :-( --ANK*/ #ifdef CONFIG_NET_IPIP ipip_init(); #endif #ifdef CONFIG_NET_IPGRE ipgre_init(); #endif/** Initialise the multicast router*/ #if defined(CONFIG_IP_MROUTE) ip_mr_init(); #endif/** Create all the /proc entries.*/ #ifdef CONFIG_PROC_FS proc_net_create ("raw", 0, raw_get_info); proc_net_create ("netstat", 0, netstat_get_info); proc_net_create ("snmp", 0, snmp_get_info); proc_net_create ("sockstat", 0, afinet_get_info); proc_net_create ("tcp", 0, tcp_get_info); proc_net_create ("udp", 0, udp_get_info); #endif/* CONFIG_PROC_FS */ipfrag_init();return 0; }module_init(inet_init);
- Linux Kernel 5.10.5发布:禁用FBCON加速滚动特性
- Linux 5.11开始围绕PCI Express 6.0进行早期准备
- Fedora正在寻求协助 希望加快Linux 5.10 LTS内核测试进度
- Linux Mint 20.1 Ulyssa稳定版已确定延期至2021年初发布
- 英特尔Xe GPU在Linux 5.11上的性能表现不错
- MIPS架构厂商日渐式微 Linux报告其漏洞遭遇困难
- Linux Kernel 5.11首个候选版本更新发布
- Linux 5.12内核将支持Radeon RX 6000系列显卡超频
- 开源开发者尝试为任天堂N64主机带来了新的Linux内核移植
- Linux 5.11窗口合并期今天结束 引入大量新特性和改进