linux tcp数据包从网卡到应用的处理路径为:网卡中断→软中断net_rx_softirq→ip层ip_rcv()→tcp_v4_rcv()→tcp状态机处理→快速/慢速路径分流,全程依托sk_buff传递与协议分层剥离。

Linux 中 TCP 数据包从网卡进入内核,最终被应用程序读取,整个过程在协议栈中逐层流转、校验、分发。路径清晰但细节繁多,核心在于数据结构 sk_buff 的传递与各层协议处理函数的协作。
1. 从网卡到协议栈入口:接收中断与软中断处理
当网卡收到以太网帧,触发硬件中断,驱动将数据通过 DMA 拷贝至内核内存,并封装为 sk_buff 结构体。随后调用 netif_receive_skb() 将数据包送入协议栈上层。
- 驱动需设置
skb->protocol(如ETH_P_IP),供后续识别网络层协议 - 该函数会触发软中断
NET_RX_SOFTIRQ,避免长时间占用 CPU - 关键目标是快速完成初步分类,不在此阶段解析 TCP 内容
2. 网络层处理:IP 层路由与交付判断
数据包到达 IP 层后,由 ip_rcv() 函数处理。它解析 IP 头部,验证校验和、TTL,并决定是否本机接收。
- 若目的 IP 不匹配本机地址且未开启转发,则丢弃
- 匹配时调用
ip_local_deliver(),进一步检查协议字段(iph->protocol == IPPROTO_TCP) - 确认为 TCP 后,交由传输层入口函数
tcp_v4_rcv()
3. 传输层处理:TCP 状态机与首部校验
tcp_v4_rcv() 是 TCP 接收主入口,它根据连接状态(LISTEN/ESTABLISHED/CLOSE_WAIT 等)分发处理逻辑。
- 先做基础校验:序列号范围、ACK 号有效性、窗口值、首部长度
- 调用
tcp_rcv_state_process()或tcp_rcv_synsent_state_process()进入状态机分支 - 对 ESTABLISHED 连接,重点处理数据段入队(
tcp_data_queue())、ACK 更新发送窗口(tcp_ack_update_window())、乱序重排等
4. 快速路径与慢速路径分流
为提升性能,内核对常规数据流启用“快速路径”——跳过部分冗余检查,前提是满足严格条件。
- 前提包括:无乱序包、接收窗口充足、内存未受限、TCP 首部预测标记
pred_flags匹配 - 匹配成功则走
tcp_prequeue_process()等轻量流程,直接入 socket 接收队列 - 任一条件不满足即回落至慢速路径,执行完整状态检查、SACK 解析、拥塞控制更新等
整个路径依赖 sk_buff 携带元信息贯穿各层,每层只关心本层协议字段,剥离首部后移交上层。理解这个“剥洋葱”式分用过程,是分析丢包、延迟或连接异常的关键切入点。











