Linux网络包发送(TX)路径与时间戳

用户空间

1. 应用程序

通过套接字(Socket) API,调用 send()sendmsg() 发送数据。

内核空间

2. 系统调用接口

CPU从用户态切换到内核态,拷贝数据并创建 sk_buff

3. 传输层 (TCP/UDP)

添加TCP或UDP头部。

4. 网络层 (IP)

添加IP头部。

🛡️ 5. Netfilter Hook 1: conntrack & 'OUTPUT' Chain

conntrack: 建立/更新连接状态 (e.g., NEW, ESTABLISHED)。
iptables: 应用 filter 表的 OUTPUT 链规则 (包过滤)。

6. 路由决策

内核根据路由表,决定数据包的下一跳和出口网络接口。

🛡️ 7. Netfilter Hook 2: 'POSTROUTING' Chain

iptables: 应用 nat 表的 POSTROUTING 链规则。这里是执行源地址转换(SNAT)的地方。

8. 链路层 (Neighbor)

ARP解析,添加以太网头部。

🚦 9. 流量控制 (Qdisc)

数据包进入与网卡关联的排队规则(Qdisc)等待发送。这里进行流量整形、调度和优先级管理。

📍 10. 软件时间戳捕获 (SOF_TIMESTAMPING_TX_SOFTWARE)

在数据包进入Qdisc后,传递给驱动前,内核获取当前时间,记录在 sk_buff 中。这是通用协议栈的最后一站。

11. 驱动程序处理

网卡驱动程序从Qdisc中取出数据包,准备通过DMA将其传输到网卡硬件的缓冲区。控制权即将移交硬件。

主要延迟来源 (µs级别): PCIe总线延迟, DMA传输, 网卡固件处理
硬件 (NIC)

12. DMA传输与硬件排队

网卡的DMA引擎从主机内存中抓取数据包,存放到网卡板载的FIFO发送队列中。

13. 物理层发送 (PHY)

数据包从FIFO队列取出,通过物理层(PHY)芯片编码,转换为电/光信号发送到网络介质上。

📍 14. 硬件时间戳捕获 (SOF_TIMESTAMPING_TX_HARDWARE)

位置: 当数据包的第一个比特位(Bit) 通过物理层(PHY) 芯片,正要被发送到网线/光纤上的那一精确瞬间,由网卡上的专用硬件时钟捕获。
这是物理层面的离开时刻。