插件窝 干货文章 Linux中一个网络包的发送/接收流程

Linux中一个网络包的发送/接收流程

缓冲区 中断 内核 数据 983    来源:    2025-05-13

在Linux系统中,网络包的发送和接收流程涉及内核协议栈、网络设备驱动及硬件协作。以下是详细流程分析:


一、网络包接收流程(RX)

  1. 硬件接收(NIC)

    • 网卡通过DMA将数据包写入内核分配的环形缓冲区(rx_ring
    • 触发硬件中断(IRQ),通知CPU有数据到达
  2. 中断处理(驱动层)

    • 驱动通过NAPI(New API)混合中断和轮询机制:
      • 硬中断快速响应,关闭后续中断并调度软中断(NET_RX_SOFTIRQ
      • 软中断中轮询rx_ring批量处理数据包
  3. 协议栈处理(内核层)

    • 链路层:检查帧完整性(CRC),剥离以太网头,识别协议类型(如IPv4/IPv6)
    • 网络层
      • IP层校验和验证,解析目标IP是否为本机
      • 若需转发则走netfilter/iptables,否则上传传输层
    • 传输层
      • TCP/UDP处理(端口绑定、序列号校验等)
      • 将数据放入Socket接收缓冲区(sk_buff
  4. 用户态交付

    • 应用通过系统调用(如recv())从Socket缓冲区拷贝数据到用户空间
    • 若使用epoll等异步机制,由内核通知应用就绪事件

二、网络包发送流程(TX)

  1. 用户态发起

    • 应用调用send()等API,数据通过系统调用进入内核
  2. 协议栈封装(内核层)

    • 传输层:TCP添加头部(序列号、窗口等),UDP封装端口
    • 网络层:IP层选路(通过路由表)、分片(若超过MTU)、设置TTL
    • 链路层:ARP查询下一跳MAC地址,封装以太网头
  3. 队列管理与驱动处理

    • 数据包放入QDisc(排队规则,如pfifo_fast)队列
    • 驱动通过tx_ring获取数据包,触发DMA传输到网卡
  4. 硬件发送(NIC)

    • 网卡处理物理层封装(如添加前导码、CRC),通过PHY发送
    • 发送完成后触发硬中断释放缓冲区

三、关键优化技术

  1. 接收方向优化

    • RSS(多队列网卡):将流量分散到不同CPU核心
    • XDP(eXpress Data Path):在驱动层早期处理数据包,避免协议栈开销
  2. 发送方向优化

    • TSO(TCP Segmentation Offload):由网卡分片TCP大包
    • UFO(UDP Fragmentation Offload):类似TSO但用于UDP
  3. 零拷贝技术

    • sendfile()/splice()减少用户态与内核态拷贝
    • AF_XDP绕过内核协议栈直接访问网卡队列

四、常见问题排查工具

场景 工具/命令
接收丢包 ethtool -S eth0(查看rx_missed_errors
发送队列积压 ip -s link show eth0(TX dropped计数)
协议栈统计 netstat -snstat -az
数据包追踪 tcpdumpbpftrace
中断均衡 cat /proc/interrupts

五、深度调优建议

  1. 调整缓冲区大小

    # 接收缓冲区
    sysctl -w net.core.rmem_max=16777216
    # 发送缓冲区
    sysctl -w net.core.wmem_max=16777216
    
  2. 启用多队列

    ethtool -L eth0 combined 8
    
  3. 关闭反向路径过滤(如需高性能):

    sysctl -w net.ipv4.conf.all.rp_filter=0
    

理解此流程可帮助诊断网络延迟、丢包等问题,并根据场景选择优化策略(如低延迟场景关闭NAPI,高吞吐启用TSO)。