linux-network详解2
借这个上一节继续分析函数inet_init函数,定义位于:net/ipv4/af_inet.c
1 static int __init inet_init(void) 2 { 3 struct inet_protosw *q; 4 struct list_head *r; 5 int rc = -EINVAL; 6 7 sock_skb_cb_check_size(sizeof(struct inet_skb_parm)); 8 9 rc = proto_register(&tcp_prot, 1);//注册协议 10 if (rc) 11 goto out; 12 13 rc = proto_register(&udp_prot, 1); 14 if (rc) 15 goto out_unregister_tcp_proto; 16 17 rc = proto_register(&raw_prot, 1); 18 if (rc) 19 goto out_unregister_udp_proto; 20 21 rc = proto_register(&ping_prot, 1); 22 if (rc) 23 goto out_unregister_raw_proto; 24 25 /* 26 * Tell SOCKET that we are alive... 27 */ 28 29 (void)sock_register(&inet_family_ops);//注册sock 30 31 #ifdef CONFIG_SYSCTL 32 ip_static_sysctl_init(); 33 #endif 34 35 /* 36 * Add all the base protocols. 37 */ 38 39 if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)//添加协议 40 pr_crit("%s: Cannot add ICMP protocol\n", __func__); 41 if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0) 42 pr_crit("%s: Cannot add UDP protocol\n", __func__); 43 if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0) 44 pr_crit("%s: Cannot add TCP protocol\n", __func__); 45 #ifdef CONFIG_IP_MULTICAST 46 if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0) 47 pr_crit("%s: Cannot add IGMP protocol\n", __func__); 48 #endif 49 50 /* Register the socket-side information for inet_create. */ 51 for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r) 52 INIT_LIST_HEAD(r); 53 54 for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q) 55 inet_register_protosw(q); 56 57 /* 58 * Set the ARP module up 59 */ 60 61 arp_init(); 62 63 /* 64 * Set the IP module up 65 */ 66 67 ip_init(); 68 69 tcp_v4_init(); 70 71 /* Setup TCP slab cache for open requests. */ 72 tcp_init(); 73 74 /* Setup UDP memory threshold */ 75 udp_init();//udp_table的初始化,创建了两个hash表,用于串联本地套接字对应的端口号 76 77 /* Add UDP-Lite (RFC 3828) */ 78 udplite4_register(); 79 80 ping_init(); 81 82 /* 83 * Set the ICMP layer up 84 */ 85 86 if (icmp_init() < 0)//将一个网络协议模块添加到每一个网络命令空间中,然后再执行其ops->init程序进行初始化,一般其ops->init会在其对应的proc目录下,生成一个网络协议模块对应的proc文件或proc目录,并执行一些协议初始化相关的函数。 87 panic("Failed to create the ICMP control socket.\n"); 88 89 /* 90 * Initialise the multicast router 91 */ 92 #if defined(CONFIG_IP_MROUTE) 93 if (ip_mr_init()) 94 pr_crit("%s: Cannot init ipv4 mroute\n", __func__); 95 #endif 96 97 if (init_inet_pernet_ops()) 98 pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__); 99 /* 100 * Initialise per-cpu ipv4 mibs 101 */ 102 103 if (init_ipv4_mibs())//每一个网络接口都对应着一个网络命名空间,这些网路空间串联在一个由”struct net”对象组成的结构体中,该函数完成这些空间数据统计的一些信息初始化 104 pr_crit("%s: Cannot init ipv4 mibs\n", __func__); 105 106 ipv4_proc_init();//在proc的ipv4目录下,会根据不同的协议创建不同的文件 107 108 ipfrag_init();//IP分片的初始化,其中指定了对应动作所调用的函数 109 110 dev_add_pack(&ip_packet_type); 111 112 ip_tunnel_core_init(); 113 114 rc = 0; 115 out: 116 return rc; 117 out_unregister_raw_proto: 118 proto_unregister(&raw_prot); 119 out_unregister_udp_proto: 120 proto_unregister(&udp_prot); 121 out_unregister_tcp_proto: 122 proto_unregister(&tcp_prot); 123 goto out; 124 }
1.1 函数proto_register
注册协议到全局协议链表中
1 int proto_register(struct proto *prot, int alloc_slab) 2 { 3 if (alloc_slab) { 4 prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,//创对应的缓存 5 SLAB_HWCACHE_ALIGN | prot->slab_flags, 6 NULL); 7 8 if (prot->slab == NULL) { 9 pr_crit("%s: Can't create sock SLAB cache!\n", 10 prot->name); 11 goto out; 12 } 13 14 if (req_prot_init(prot))//初始化prot->rsk_prot元素 15 goto out_free_request_sock_slab; 16 17 if (prot->twsk_prot != NULL) { 18 prot->twsk_prot->twsk_slab_name = kasprintf(GFP_KERNEL, "tw_sock_%s", prot->name); 19 20 if (prot->twsk_prot->twsk_slab_name == NULL) 21 goto out_free_request_sock_slab; 22 23 prot->twsk_prot->twsk_slab = 24 kmem_cache_create(prot->twsk_prot->twsk_slab_name, 25 prot->twsk_prot->twsk_obj_size, 26 0, 27 prot->slab_flags, 28 NULL); 29 if (prot->twsk_prot->twsk_slab == NULL) 30 goto out_free_timewait_sock_slab_name; 31 } 32 } 33 34 mutex_lock(&proto_list_mutex); 35 list_add(&prot->node, &proto_list);//加入全局协议链表 36 assign_proto_idx(prot); 37 mutex_unlock(&proto_list_mutex); 38 return 0; 39 40 out_free_timewait_sock_slab_name: 41 kfree(prot->twsk_prot->twsk_slab_name); 42 out_free_request_sock_slab: 43 req_prot_cleanup(prot->rsk_prot); 44 45 kmem_cache_destroy(prot->slab); 46 prot->slab = NULL; 47 out: 48 return -ENOBUFS; 49 }
全局协议链表:
static LIST_HEAD(proto_list);
tcp协议的定义,位于:net\ipv4\tcp_ipv4.c,其他协议类似不再重复。
1 struct proto tcp_prot = { 2 .name = "TCP", 3 .owner = THIS_MODULE, 4 .close = tcp_close, 5 .connect = tcp_v4_connect, 6 .disconnect = tcp_disconnect, 7 .accept = inet_csk_accept, 8 .ioctl = tcp_ioctl, 9 .init = tcp_v4_init_sock, 10 .destroy = tcp_v4_destroy_sock, 11 .shutdown = tcp_shutdown, 12 .setsockopt = tcp_setsockopt, 13 .getsockopt = tcp_getsockopt, 14 .recvmsg = tcp_recvmsg, 15 .sendmsg = tcp_sendmsg, 16 .sendpage = tcp_sendpage, 17 .backlog_rcv = tcp_v4_do_rcv, 18 .release_cb = tcp_release_cb, 19 .hash = inet_hash, 20 .unhash = inet_unhash, 21 .get_port = inet_csk_get_port, 22 .enter_memory_pressure = tcp_enter_memory_pressure, 23 .stream_memory_free = tcp_stream_memory_free, 24 .sockets_allocated = &tcp_sockets_allocated, 25 .orphan_count = &tcp_orphan_count, 26 .memory_allocated = &tcp_memory_allocated, 27 .memory_pressure = &tcp_memory_pressure, 28 .sysctl_mem = sysctl_tcp_mem, 29 .sysctl_wmem = sysctl_tcp_wmem, 30 .sysctl_rmem = sysctl_tcp_rmem, 31 .max_header = MAX_TCP_HEADER, 32 .obj_size = sizeof(struct tcp_sock), 33 .slab_flags = SLAB_DESTROY_BY_RCU, 34 .twsk_prot = &tcp_timewait_sock_ops, 35 .rsk_prot = &tcp_request_sock_ops, 36 .h.hashinfo = &tcp_hashinfo, 37 .no_autobind = true, 38 #ifdef CONFIG_COMPAT 39 .compat_setsockopt = compat_tcp_setsockopt, 40 .compat_getsockopt = compat_tcp_getsockopt, 41 #endif 42 .diag_destroy = tcp_abort, 43 }
1.2 函数arp_init
定义位于:net/ipv4/arp.c
将arp的协议类型添加到ptype_base[]里面,当IP层收到arp包的时候调用arp_rcv()函数进行处理。同时也完成/proc/net/arp文件的初始化。
1 void __init arp_init(void) 2 { 3 neigh_table_init(NEIGH_ARP_TABLE, &arp_tbl); 4 5 dev_add_pack(&arp_packet_type);//将arp的协议类型添加到ptype_base[]里面 6 arp_proc_init(); 7 #ifdef CONFIG_SYSCTL 8 neigh_sysctl_register(NULL, &arp_tbl.parms, NULL); 9 #endif 10 register_netdevice_notifier(&arp_netdev_notifier); 11 }
1.3 函数ip_init
ip子系统的初始化
1 void __init ip_init(void) 2 { 3 ip_rt_init();//路由子系统的初始化 4 inet_initpeers();inet_peer缓存创建 5 6 #if defined(CONFIG_IP_MULTICAST) 7 igmp_mc_init(); 8 #endif 9 }
行胜于言,自强不息。

浙公网安备 33010602011771号