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 }

 

posted @ 2020-11-14 18:56  Action_er  阅读(339)  评论(0)    收藏  举报