基于2.6.20版本的《Linux内核源码剖析--TCP/IP实现》

2020-05-22 00:00:00 接口 选项 结构 报文 组播

经过两年半深入的研究,已完成《Linux内核源码剖析--TCP/IP实现》一书,此书的框架参照了大师级作品《TCP/IP详解-卷2》

内容提要
本书完整而详细的论述了Linux内核2.6.20版本中TCP/IP协议是如何实现的。书中给出了大量的源代码,通过对源代码的详细的论述,帮助你掌握TCP/IP的实现。本书根据协议栈层次,从驱动层逐步论述到传输层,包括驱动的实现、接口层的输入输出、IP层的输入输出以及IP选项的处理、邻居子系统、路由、套接口及传输层等内容,全书基本涵盖了网络体系架构全部的知识点。特别是TCP,包括TCP连接的建立和终止、输入与输出、以及拥塞控制的实现。
本书的适用于那些熟悉Linux的基本使用方法,对Linux内核工作原理以及网络知识有一定的了解,而又极想更深入地理解各个机制在Linux中是怎样来实现的人们,包括应用程序员和嵌入式程序员等。也适合那些做相关研究和开发的科研人员在通篇阅读本书之外,当工作中遇到问题时查阅本书来帮助理解相关内核部分是怎样实现的。此外对于计算机相关专业的本科高年级学生和研究生,在学习相关课程(如操作系统、计算机网络等)时,作为辅助教程,与理论相结合以便于更好得理解相应的知识点。对于初学者,可能会在阅读中遇到诸多的障碍,本书中会尽量对一些基本知识点加以简单的描述,但限于篇幅,不可能在这上面作过多的逗留,读者可以查阅相关的资料。


前言
有人宣称Linux人才是未来20年IT职场中的,无论这种说法有多夸张,但有一个事实是不可否认的,那就是,近年来Linux的市场份额不断增长,Linux正在受到越来越多人的关注乃至推崇。由于Linux可广泛地应用到各种系统,包括很多嵌入式系统上,以及其自身其它的诸多优点,如开放性、高效性、丰富的网络功能等,这种趋势在可预计的未来还将持续。
目前,国内对Linux各方面的研究工作相对没有国外那样广泛和深入,相关的出版物水准参差不齐。别是在网络的实现方面,有些著作针对性不强,有些则缺少了重要的传输层协议实现的论述,还有一些虽然有比较全面的介绍,然后欠缺在深入程度不够,选用的Linux版本比较旧。
针对以上情况,选择了较新的2.6.20版本内核来作详细的论述,在重要的细节处甚至逐行分析,并在此基础上,对于代码背后的机制和原理作了深入的阐述,将各关键点连成一个整体,帮助读者理清整个Linux网络部分的脉络。作者本着严谨的态度,在写作过程中参阅了大量的中英文资料以及相关的文档。本书与上述书籍还有一个显著优点,没有翻译折损,行文更符合中文的习惯,便于读者理解。相信本书将可以成为那些想要深入了解Linux的TCP/IP协议栈、网络部分实现的人们一个有用的工具。
本书是通过自底向上的方法来论述TCP/IP的实现,从数据链路层开始,然后是网络层(IP、ICMP、IGMP、路由以及邻居子系统和IP组播),接下来是套接口,后是传输层(TCP和UDP)。当然在学习的时候也可以自顶向下的方法(从传输层开始向下),或者结合以上两种的方法。要理解一个系统的运行机制,对于一个专业人员来说,代码是为直接也为可靠的资源。Linux普及面不断扩展,越来越多的人会想通过研读内核代码来了解Linux系统,一来是更好地解决具体工作中的相关问题,二来从Linux这个质量的操作系统中学习到更多的编程、架构等技术。本书的读点如下:
1.选择的内核版本新,这就保证了不会在短期内出现内容过时的可能。
2.对代码作了详细的论述,在此基础上进一步分析了代码背后的机制和原理,为读者理清了整个框架的脉络,避免了读者“不识芦山真面目,只缘身在此山中”迷失在细节中。
3.写作过程中参阅大量资料中英文资料和相关的文档,对内核代码更是作了长时间深入细致的研究和分析,在细节处反复推敲,以确保本书有一个较高的质量。
4.书中有大量的图表,用来帮助读者直观地理解各个数据结构之间的联系,各个函数的调用关系等。
Linux内核中的网络模块虽然是一个比较独立的模块,但仍运行内核中一些常用的技术和算法,因此希望读者在阅读本书之前需要掌握一些基础知识。包括对TCP/IP协议有一定的了解,了解Linux内核的运行,包括进程管理、内存管理、文件系统、系统调用、netlink、内核中多种锁(自旋锁、读写锁、RCU)等。当然在学习过程中,免不了要做些实验,因此也需要熟悉Linux提供的多种工具,包括ip、ifconfig等命令。
本书针对的Linux内核版本为2.6.20,也许读者想知道为什么选择这个版本,实际上开始分析TCP/IP代码时,选择是新版本。正是因为Linux内核快速的更新,只是经过二年多的分析后,新版本已经是2.6.3x了,即便如此,如果读者能领悟了2.6.20版本的代码,则再读新版本的代码时,应该不会有多少难度。由于内容繁多,不足和漏洞之处可能还会存在,请读者谅解并提出修改建议,建议和意见留言到作者的博客:http://blog.chinaunix.net/u3/112243/。
在此,还要特别感谢网友衫秋南,对本书提出宝贵的意见和建议。

目录第1章 预备知识 1
1.1 应用层配置诊断工具 1
1.1.1 iputils 2
1.1.2 net-tools 2
1.1.3 IPROUTE2 2
1.2 内核空间与用户空间的接口 2
1.2.1 procfs 2
1.2.2 sysctl(/proc/sys目录) 3
1.2.3 sysfs(/sys文件系统) 5
1.2.4 ioctl系统调用 6
1.2.5 netlink套接口 6
1.3 网络I/O加速 6
1.3.1 TSO/GSO 7
1.3.2 I/O AT 8
1.4 其他 8
1.4.1 slab分配器 9
1.4.2 RCU 9
第2章 网络体系结构概述 10
2.1 引言 10
2.2 协议简介 10
2.3 网络架构 11
2.4 系统调用接口 11
2.5 协议无关接口 12
2.6 传输层协议 12
2.7 套接口缓存 13
2.8 设备无关接口 14
2.9 设备驱动程序 15
2.10 网络模块源代码组织 15
第3章 套接口缓存 16
3.1 引言 16
3.2 sk_buff结构 16
3.2.1 网络参数和内核数据结构 17
3.2.2 SKB组织相关的变量 20
3.2.3 数据存储相关的变量 21
3.2.4 通用的成员变量 22
3.2.5 标志性变量 25
3.2.6 特性相关的成员变量 26
3.3 skb_shared_info结构 26
3.3.1 “零拷贝”技术 27
3.3.2 对聚合分散I/O数据的支持 28
3.3.3 对GSO的支持 31
3.3.4 访问skb_shared_info结构 32
3.4 管理函数 32
3.4.1 SKB的缓存池 33
3.4.2 分配SKB 33
3.4.3 释放SKB 36
3.4.4 数据预留和对齐 38
3.4.5 克隆和复制SKB 40
3.4.6 链表管理函数 45
3.4.7 添加或删除尾部数据 45
3.4.8 拆分数据:skb_split() 47
3.4.9 重新分配SKB的线性数据区:pskb_expand_head() 49
3.4.10 其他函数 49
第4章 网络模块初始化 51
4.1 引言 51
4.2 网络模块初始化顺序 51
4.3 优化基于宏的标记 52
4.4 网络设备处理层初始化 55
第5章 网络设备 58
5.1 PCI设备 58
5.1.1 PCI驱动程序相关结构 58
5.1.2 注册PCI驱动程序 60
5.2 网络设备有关的数据结构 62
5.2.1 net_device结构 62
5.2.2 网络设备有关结构的组织 74
5.2.3 相关函数 76
5.3 网络设备的注册 76
5.3.1 设备注册的时机 76
5.3.2 分配net_device结构空间 76
5.3.3 网络设备注册过程 78
5.3.4 注册设备的状态迁移 82
5.3.5 设备注册状态通知 83
5.3.6 引用计数 84
5.4 网络设备的注销 84
5.4.1 设备注销的时机 84
5.4.2 网络设备注销过程 85
5.5 网络设备的启用 91
5.6 网络设备的禁用 92
5.7 与电源管理交互 94
5.7.1 挂起设备 94
5.7.2 唤醒设备 95
5.8 侦测连接状态改变 96
5.8.1 调度处理连接状态改变事件 96
5.8.2 linkwatch标志 100
5.9 从用户空间配置设备相关信息 100
5.9.1 ethtool 100
5.9.2 媒体独立接口 102
5.10 虚拟网络设备 102
第6章 IP编址 105
6.1 接口和IP地址 105
6.1.1 主IP地址、从属IP地址和IP别名 105
6.1.2 IP地址的组织 105
6.1.3 in_device结构 106
6.1.4 in_ifaddr结构 107
6.2 函数 109
6.2.1 inetdev_init() 109
6.2.2 inetdev_destroy() 110
6.2.3 inet_select_addr() 111
6.2.4 inet_confirm_addr() 112
6.2.5 inet_addr_onlink() 113
6.2.6 inetdev_by_index() 114
6.2.7 inet_ifa_byprefix() 114
6.2.8 inet_abc_len() 114
6.3 IP地址的设置 115
6.3.1 netlink接口 115
6.3.2 inet_insert_ifa() 118
6.3.3 inet_del_ifa() 119
6.4 IOCTL 122
6.5 inetaddr_chain通知链 128
第7章 接口层的输入 129
7.1 系统参数 129
7.2 接口层的IOCTL 130
7.2.1 SIOCxIFxxx类命令 130
7.2.2 SIOCETHTOOL 134
7.2.3 私有命令 135
7.3 初始化 135
7.4 softnet_data结构 136
7.5 NAPI方式 138
7.5.1 网络设备中断例程 139
7.5.2 网络输入软中断 139
7.5.3 轮询处理 141
7.6 非NAPI方式 142
7.7 接口层输入报文的处理 145
7.7.1 报文接收例程 145
7.7.2 netif_receive_skb() 146
7.7.3 dev_queue_xmit_nit() 148
7.8 响应CPU状态的变化 150
7.9 netpoll 151
7.9.1 netpoll相关结构 151
7.9.2 注册netpoll实例 153
7.9.3 netpoll的输入 156
7.9.4 netpoll的输出 165
7.9.5 tx_work工作队列 167
7.9.6 netpoll实例:netconsole 168
第8章 接口层的输出 172
8.1 输出接口 172
8.1.1 dev_queue_xmit() 172
8.1.2 dev_hard_start_xmit() 176
8.1.3 e100的输出接口:e100_xmit_frame() 177
8.2 网络输出软中断 177
8.2.1 netif_schedule() 177
8.2.2 net_tx_action() 178
8.3 网络设备不支持GSO的处理 179
8.3.1 dev_gso_cb私有控制块 180
8.3.2 dev_gso_segment() 181
8.3.3 skb_gso_segment() 181
第9章 流量控制 183
9.1 通过流量控制后输出 183
9.1.1 dev_queue_xmit() 184
9.1.2 qdisc_restart() 185
9.2 构成流量控制的三种元素 187
9.2.1 排队规则 189
9.2.2 类 196
9.2.3 过滤器 200
9.3 缺省的FIFO排队规则 203
9.3.1 pfifo_fast_init() 205
9.3.2 pfifo_fast_reset() 206
9.3.3 pfifo_fast_enqueue() 206
9.3.4 pfifo_fast_dequeue() 207
9.3.5 pfifo_fast_requeue() 208
9.4 netlink的tc接口 208
9.5 排队规则的创建接口 210
9.5.1 类的创建接口 214
9.5.2 过滤器的创建接口 217
第10章 Internet协议族 222
10.1 net_proto_family结构 222
10.2 inet_protosw结构 223
10.3 net_protocol结构 225
10.4 Internet协议族的初始化 227
第11章 IP:网际协议 231
11.1 引言 231
11.1.1 IP首部 232
11.1.2 IP数据报的输入与输出 233
11.2 IP的私有信息控制块 234
11.3 系统参数 235
11.4 初始化 238
11.5 IP层套接口选项 238
11.6 ipv4_devconf结构 242
11.7 套接口的错误队列 244
11.7.1 添加ICMP差错信息 246
11.7.2 添加由本地产生的差错信息 247
11.7.3 读取错误信息 248
11.8 报文控制信息 250
11.8.1 IP控制信息块 250
11.8.2 报文控制信息的输出 251
11.8.3 报文控制信息的输入 252
11.9 对端信息块 253
11.9.1 系统参数 254
11.9.2 对端信息块的创建和查找 255
11.9.3 对端信息块的删除 257
11.9.4 垃圾回收 257
11.10 IP数据报的输入处理 260
11.10.1 IP数据报输入到本地 263
11.10.2 IP数据报的转发 265
11.11 IP数据报的输出处理 269
11.11.1 IP数据报输出到设备 269
11.11.2 TCP输出的接口 271
11.11.3 UDP输出的接口 277
11.12 IP层对GSO的支持 292
11.12.1 inet_gso_segment() 292
11.12.2 inet_gso_send_check() 294
第12章 IP选项处理 295
12.1 IP选项 295
12.1.1 选项列表的结束符 296
12.1.2 空操作 296
12.1.3 安全选项 296
12.1.4 严格源路由选项 297
12.1.5 宽松源路由选项 299
12.1.6 记录路由选项 299
12.1.7 流标识选项 300
12.1.8 时间戳选项 300
12.1.9 路由器警告选项 301
12.2 ip_options结构 301
12.3 在IP数据报中构建IP选项 303
12.4 复制IP数据报中选项到指定的ip_options结构 304
12.5 处理待发送IP分片中的选项 307
12.6 解析IP选项 308
12.7 还原在校验IP选项时修改的IP选项 314
12.8 处理转发IP数据报中的IP选项 315
12.9 处理IP数据报的源路由选项 316
12.10 解析并处理IP首部中的IP选项 318
12.11 路由警告选项的处理 319
12.12 由控制信息生成IP选项信息块 319
第13章 IP的分片与组装 321
13.1 系统参数 321
13.2 分片 321
13.2.1 快速分片 324
13.2.2 慢速分片 327
13.3 组装 330
13.3.1 ipq结构 330
13.3.2 ipq散列表和链表的维护 333
13.3.3 ipq散列表的重组 334
13.3.4 超时IP分片的清除 335
13.3.5 垃圾收集 337
13.3.6 相关分片组装函数 338
13.3.7 分片组装 346
第14章 ICMP:Internet控制报文协议 349
14.1 ICMP报文结构 349
14.2 注册ICMP报文类型 349
14.3 系统参数 349
14.4 ICMP的初始化 351
14.5 输入处理 352
14.5.1 差错处理 356
14.5.2 重定向处理 361
14.5.3 请求回显 362
14.5.4 时间戳请求 363
14.5.5 地址掩码请求和应答 365
14.6 输出处理 365
14.6.1 发送ICMP报文 365
14.6.2 发送回显应答和时间戳应答报文 369
第15章 IP组播 372
15.1 初始化 372
15.2 虚拟接口 373
15.2.1 虚拟接口的添加 374
15.2.2 虚拟接口的删除:vif_delete() 376
15.2.3 查找虚拟接口:ipmr_find_vif() 377
15.3 组播转发缓存 377
15.3.1 组播转发缓存的创建 380
15.3.2 组播转发缓存的删除 380
15.3.3 组播转发缓存的查找 380
15.3.4 向组播路由守护进程发送报告 380
15.4 临时组播转发缓存 383
15.4.1 临时组播转发缓存队列 384
15.4.2 创建临时组播转发缓存 384
15.4.3 用于超时而删除临时组播转发缓存的定时器 386
15.4.4 释放临时组播缓存项中保存的临时组播报文 387
15.5 外部事件 388
15.6 组播套接口选项 388
15.6.1 IP_MULTICAST_TTL 388
15.6.2 IP_MULTICAST_LOOP 389
15.6.3 IP_MULTICAST_IF 389
15.6.4 IP_ADD_MEMBERSHIP 391
15.6.5 IP_DROP_MEMBERSHIP 391
15.6.6 IP_MSFILTER 392
15.6.7 IP_BLOCK_SOURCE和IP_UNBLOCK_SOURCE 393
15.6.8 IP_ADD_SOURCE_MEMBERSHIP和IP_DROP_SOURCE_MEMBERSHIP 394
15.6.9 MCAST_JOIN_GROUP 395
15.6.10 MCAST_LEAVE_GROUP 395
15.6.11 MCAST_BLOCK_SOURCE和MCAST_UNBLOCK_SOURCE 396
15.6.12 MCAST_JOIN_SOURCE_GROUP和MCAST_LEAVE_SOURCE_GROUP 396
15.6.13 MCAST_MSFILTER 397
15.7 组播选路套接口选项 397
15.7.1 MRT_INIT 397
15.7.2 MRT_DONE 398
15.7.3 MRT_ADD_VIF和MRT_DEL_VIF 398
15.7.4 MRT_ADD_MFC和MRT_DEL_MFC 399
15.7.5 MRT_ASSERT 399
15.8 组播的IOCTLS 399
15.8.1 SIOCGETVIFCNT 399
15.8.2 SIOCGETSGCNT 399
15.9 组播报文的输入 400
15.10 组播报文的转发 402
15.10.1 ip_mr_forward() 402
15.10.2 ipmr_queue_xmit() 404
15.11 组播报文的输出 407
第16章 IGMP:Internet组管理协议 409
16.1 in_device结构中的组播参数 409
16.2 ip_mc_list结构 410
16.3 系统参数 412
16.4 IGMP的版本与协议结构 412
16.4.1 IGMP的版本 412
16.4.2 版和第二版的IGMP报文结构 413
16.4.3 第三版的IGMP查询报文结构 414
16.4.4 第三版的IGMP报告结构 415
16.5 IGMP报文的输入 417
16.6 函数 419
16.6.1 ip_mc_find_dev() 419
16.6.2 ip_check_mc() 419
16.7 成员关系查询 419
16.8 成员关系报告 423
16.8.1 近离开组播组列表的维护 423
16.8.2 is_in() 423
16.8.3 add_grec() 425
16.8.4 普通查询的报告 428
16.8.5 V1和V2的报告以及V3的当前状态记录报告 430
16.8.6 主动发送组关系报告 433
16.9 维护套接口组播状态 436
16.9.1 套接口加入组播组 437
16.9.2 套接口离开组播组 439
16.10 维护网络设备组播状态 439
16.10.1 被阻止的组播源列表的维护 441
16.10.2 网络设备加入组播组 441
16.10.3 网络设备离开组播组 446
16.11 ip_mc_source() 451
16.12 ip_mc_msfilter() 455
16.13 网络设备组播硬件地址的管理 457
第17章 邻居子系统 459
17.1 邻居子系统概念 459
17.2 系统参数 459
17.3 邻居子系统的结构 460
17.3.1 neigh_table结构 461
17.3.2 neighbour结构 464
17.3.3 neigh_ops结构 466
17.3.4 neigh_parms结构 467
17.3.5 pneigh_entry结构 469
17.3.6 neigh_statistics结构 469
17.3.7 hh_cache结构 470
17.4 邻居表的初始化 471
17.5 邻居项的状态机 472
17.6 邻居项的添加与删除 474
17.6.1 netlink接口 474
17.6.2 ioctl 478
17.6.3 路由表项与邻居项的绑定 478
17.6.4 接收到的并非请求的应答 478
17.7 邻居项的创建与初始化 478
17.7.1 neigh_alloc() 478
17.7.2 neigh_create() 479
17.8 邻居项散列表的扩容 481
17.9 邻居项的查找 482
17.9.1 neigh_lookup() 482
17.9.2 neigh_lookup_nodev() 483
17.9.3 __neigh_looku()和neigh_lookup_errno() 483
17.10 邻居项的更新 483
17.11 垃圾回收 488
17.11.1 同步回收 488
17.11.2 异步回收 489
17.12 外部事件 491
17.13 邻居项状态处理定时器 491
17.14 代理项 494
17.14.1 代理项的查找、添加和删除 494
17.14.2 延时处理代理的请求报文 494
17.15 输出函数 496
17.15.1 丢弃 496
17.15.2 慢速发送 497
17.15.3 快速发送 500
第18章 ARP-地址解析协议 502
18.1 ARP报文格式 502
18.2 系统参数 503
18.3 注册ARP报文类型 505
18.4 ARP初始化 505
18.5 ARP的邻居项函数指针表 505
18.6 ARP表 506
18.7 函数 507
18.7.1 arp_error_report() 507
18.7.2 arp_solicit() 507
18.7.3 arp_ignore() 509
18.7.4 arp_filter() 510
18.8 IPv4中邻居项的初始化 510
18.9 ARP报文的创建 512
18.10 ARP的输出 513
18.11 ARP的输入 514
18.11.1 arp_rcv() 514
18.11.2 arp_process() 515
18.12 ARP代理 521
18.12.1 arp_process() 521
18.12.2 arp_fwd_proxy() 522
18.12.3 parp_redo() 523
18.13 ARP的IOCTLS 523
18.14 外部事件 524
18.15 路由表项与邻居项的绑定 525


文章来源CU社区:基于2.6.20版本的《Linux内核源码剖析--TCP/IP实现》【465楼为勘误列表】

相关文章