本文作者:sivenzhang,腾讯 IEG 测试开发工程师
1. 前言
本文主要对 Linux 系统内核协议栈中网络层接收,发送以及转发数据包的流程进行简要介绍,同时对 Netfilter 数据包过滤框架的基本原理以及使用方式进行简单阐述。
内容如有理解错误而导致说明错误的地方,还请指正。如存在引用而没有添加说明的,也请及时告知,非常感谢!
2. 基础网络知识
2.1 网络分层模型
OSI 模型中将网络划分为七层,但在目前实际广泛使用的 TCP/IP 协议框架体系内,我们一般将网络划分为五层,从下到上依次为物理层,链路层,网络层,传输层以及应用层。两者的区别在于 OSI 模型在应用层对数据包做了更细致的划分。两者的关系如下图所示:
图片来源:
https://www.cnblogs.com/qishui/p/5428938.html
在 TCP/IP 协议框架体系的五层网络模型中,每一层负责处理的数据包协议或类型均存在差异,物理层主要负责在物理载体上的数据包传输,如 WiFi,以太网,光纤,电话线等;数据链路层主要负责链路层协议解析(主要为以太网帧,其他类型此处暂不考虑),网络层主要负责 IP 协议(包括 IPv4 和 IPv6)解析,传输层负责传输层协议解析(主要为 TCP,UDP 等),而传输层以上我们均归类为应用层,主要包括各类应用层协议,如我们常用的 HTTP,FTP,SMTP,DNS,DHCP 等。
在 TCP/IP 协议框架体系内,下层协议对上层协议透明,即上层协议无需关注下层协议的实现逻辑和机制。
2.2 数据包协议分层
在 TCP/IP 协议框架体系内,上层协议报文被作为下层协议的数据载荷(Data Payload),存储在下层协议的数据段区域中进行传输。结合这一特性,我们常见的几类网络协议嵌套关系如下图所示:
从上图我们可以清晰地看到各类协议之间的嵌套关系,如使用 HTTP 协议的应用 App1 在传输层封装在 TCP 协议中,TCP 协议在网络层又封装到 IP 协议中,最后交到数据链路层中。其他应用层 App 也类似。
网际报文控制协议(ICMP,使用该协议的 Ping 工具),以及网际组管理协议(IGMP,组播多播中的控制报文)是直接嵌套到 IP 数据包中,而不依赖于 TCP 或 UDP。
地址解析协议(ARP)和反解析协议(RARP)则是直接嵌套在数据链路层数据包中进行传输。
注:在本文中,我们只大概了解整体的网络框架,各协议的具体内容这里不做赘述。
2.3 sk_buff 结构
在 Linux 内核中,系统使用 sk_buff 数据结构对数据包进行存储和管理。在数据包接收过程中,该数据结构从网卡驱动收包开始,一直贯穿到内核网络协议栈的顶层,直到用户态程序从内核获取数据。使用图形表示 sk_buff 的结构如下:
在 sk_buff 数据结构中包含了诸多关于数据包存储,定位和管理的指针,数据包在网络协议栈各层次之间进行传输的过程中,内核通过操作指针的方式对数据包进行逐层解析,避免频繁的大数据段拷贝操作,从而提高数据包处理效率(但在某些特殊情况下依然会采用数据包拷贝操作)。
2.4 收发包整体框架
这里我们从客户端和服务端整体框架层面来看数据收发流程:
用户态(User Space)程序 Client 向另一台主机上的 Se