网络协议栈即OSI通信模型在linux内核的描述,又叫网络子系统。网络协议栈是实现客户端和服务端通信的基础。本文内容基于2.6.9版本,主要从报文收发的流程上一步步讲解应用层套接字发送的数据是如何发送给对端,以及如何从套接字上读取到数据的。
我们淡化OSI模型中的物理层以及应用层的处理流程,主要展开说明数据链路层到传输层的逻辑,如下图所示。
一、数据链路层接收处理报文
数据通过物理链路传输到网卡时,会存到网卡的内存空间内(每个网卡在内核中都对应一个网络设备,由net_device结构体表示),并且触发硬中断信号,内核收到信号后,开始执行硬中断处理函数。对于不支持NAPI机制的老网卡,通常调用netif_rx接口将报文存到CPU的接收队列(报文采用sk_buff结构来存储);支持NAPI的网卡,中断处理函数会将报文存储到napi结构的接收队列中。两种机制最终都会在硬中断处理函数中触发软中断,进入软中断处理流程。硬中断处理属于中断上半部,软中断处理逻辑属于中断下半部。
为了提升中断效率,内核采用中断+轮询的机制来处理报文,即软中断触发后,在软中断回调函数中,循环调用napi的轮询接口处理报文。在内核中,软中断是在网络设备初始化(net_dev_init)时,注册回调处理函数net_rx_action,该函数中会执行网卡的poll轮询接口处理网卡接收到的报文。最终调用netif_receive_skb接口(接收报文处理主函数)。
linux内核支持很多虚拟化技术ÿ