3.2 Linux 系统收包流程

本节,我们了解数据包进入网卡(eth0)后,Linux 内核中各个模块是如何协作,对 Linux 系统的数据包处理机制有个系统的认识。

总结 Linux 系统收包流程,如图 3-1 所示。


图 3-1 Linux 系统收包流程

  1. 外部数据包到达主机时,首先由网卡 eth0 接收。
  2. 网卡通过 DMA(Direct Memory Access,直接内存访问)技术,将数据包拷贝到内核中的 RingBuffer(环形缓冲区)等待 CPU 处理。RingBuffer 是一种首尾相接的环形数据结构,它作为缓冲区,缓解网卡接收数据的速度快于 CPU 处理数据的速度问题。
  3. 接着,网卡产生 IRQ(Interrupt Request,硬件中断),通知内核有新的数据包到达。
  4. 内核调用中断处理函数,标记新数据到达。接着,唤醒 ksoftirqd 内核线程,执行软中断(SoftIRQ)处理。
  5. 软中断处理中,内核调用网卡驱动的 NAPI(New API)poll 接口,从 RingBuffer 中提取数据包,并转换为 skb(Socket Buffer)格式。skb 是描述网络数据包的核心数据结构,无论是数据包的发送、接收还是转发,Linux 内核都会以 skb 的形式来处理。
  6. skb 被传递到内核协议栈,在多个网络层次间处理:
    • 网络层(L3 Network layer):根据主机中的路由表,判断数据包路由到哪一个网络接口(Network Interface)。这里的网络接口可能是稍后介绍的虚拟设备,也可能是物理网卡 eth0 接口。
    • 传输层(L4 Transport layer):处理网络地址转换(NAT)、连接跟踪(conntrack)等。
  7. 内核协议栈处理完成后,数据包被传递到 socket 接收缓冲区。应用程序利用系统调用(如 Socket API)从缓冲区读取数据。至此,整个收包过程结束。

从上述流程可见,Linux 系统的数据包处理涉及多个网络层协议栈(如数据链路层、网络层、传输层和应用层),需要进行封包/解包操作,并频繁发生上下文切换(Context Switch)。在设计网络密集型系统时,Linux 内核瓶颈不可忽视,优化内核参数是不可或缺的环节。除了优化内核参数,业界还提出了“绕过内核”的解决方案,如图 3-1 所示的 XDP 和 DPDK 技术。笔者将在 3.4 节中详细介绍它们的原理与区别。

接下来,我们将继续深入 Linux 内核网络模块,研究 Linux 内核是如何过滤、修改和转发数据的。

总字数:676
Last Updated:
Contributors: isno