解封装(控制流+数据流)

121 阅读3分钟

网络数据解封装全流程详解(控制流+数据流)


一、控制流阶段(建立通信管道)

目标:注册接口、分配资源,为解封装铺路

方向:自上而下(应用层 → 硬件层)

层级核心操作接口类型关键接口示例
应用层注册数据到达回调回调注册接口epoll_ctl(EPOLL_CTL_ADD)
内核协议栈向驱动注册协议处理函数协议处理接口netdev_ops.ndo_start_xmit
驱动层配置DMA缓冲区,注册硬件中断硬件控制接口request_irq()iowrite32()
硬件层启用接收电路寄存器配置NIC寄存器写入(如RX_ENABLE

流程示例:

  1. 应用调用epoll_create() → 内核分配事件监听结构体
  2. 驱动加载时调用register_netdev() → 内核记录网卡操作函数集
  3. 硬件初始化时配置DMA描述符环 → 网卡开始监听物理信号

二、数据流阶段(执行解封装)

目标:自底向上剥离协议头,提交有效载荷

方向:自下而上(硬件层 → 应用层)

接口类型:强制解封装接口(下层调用上层注册的接口)

层级核心操作调用接口协议头处理
硬件层剥离前导码/CRC,写入DMA缓冲区硬件自动完成去除物理层冗余信息
驱动层读取DMA数据,校验MAC帧netif_receive_skb()剥离MAC头(14字节)
内核协议栈IP校验、分片重组,TCP/UDP解析ip_rcv()tcp_rcv()剥离IP头(20字节)→ TCP头(20字节)
应用层从Socket缓冲区读取裸数据epoll回调获取HTTP/FTP等应用数据

流程示例:

  1. 网卡收包 → 触发中断 → 驱动调用netif_receive_skb(skb)
  2. 内核IP层校验后调用tcp_v4_rcv(skb) → 剥离TCP头存入Socket缓冲区
  3. 内核通过epoll回调通知应用层调用recv()读取数据

三、关键接口对比

接口类型控制流接口数据流接口
调用方向上层→下层注册下层→上层调用
典型代表register_netdev()epoll_ctl()netif_rx()tcp_rcv()
作用阶段系统初始化/资源分配数据到达时实时处理
是否强制可选(按需注册)必须调用(否则丢包)

四、全流程图示

控制流(初始化):
应用层 → epoll_ctl() → 内核 → register_netdev() → 驱动 → request_irq() → 硬件

数据流(解封装):
硬件 → 中断 → 驱动 → netif_rx() → 内核 → ip_rcv() → tcp_rcv() → epoll回调 → 应用层


五、设计原则总结

  1. 控制流先于数据流:
    • 没有注册epoll回调,应用无法获知数据到达;没有注册netdev_ops,驱动无法提交数据。
  2. 解封装不可逆:
    • 必须按MAC → IP → TCP → 应用数据顺序剥离,驱动不能跳过IP层直接提交给应用。
  3. 分层隔离:
    • 驱动层不知道tcp_rcv()的实现细节,只需按协议调用接口。

该设计是Linux内核(5.15+)、DPDK和硬件Offload的通用规范。