网络堆栈和驱动程序职责 | AI生成和翻译
问题:网卡 (NIC) 驱动程序和内核的网络堆栈通常处理哪些(除了 ARP 包之外)?
答案:
网卡驱动程序和内核的网络堆栈负责网络处理的最低层(主要是第 1 层和第 2 层,以及第 3 层的入口)。除了 ARP,它们通常为所有入站和出站流量处理以下任务:
入站数据包(接收路径)
- 物理层信令 – 网卡将电/光信号转换为原始位/字节。
- 帧接收和 DMA – 网卡驱动程序设置 DMA 环;网卡将收到的以太网帧(或 Wi-Fi 等)直接写入内核内存。
- 基本帧验证 – CRC/校验和卸载、VLAN 标签剥离(如果已配置)、最小/最大大小检查。
- 链路层解复用 – 基于以太网类型字段(或等效字段):
- 0x0800 → IPv4
- 0x86DD → IPv6
- 0x0806 → ARP(已提及)
- 0x888E → 802.1X/EAPOL
- 0x8917 → 802.1X PAE
- 0x88E5 → MACsec
- 0x8100 → VLAN 标记帧
- 其他(LLDP、PTP、FCoE 等)
- 硬件卸载(通常在驱动程序看到帧之前在 NIC 中完成):
- 校验和验证(IP 头、TCP/UDP/ICMP)
- 大型接收卸载(LRO)/通用接收卸载(GRO)
- RSS(接收侧扩展) – 将数据包分发到多个 CPU 核心
- TCP 分段卸载接收侧(罕见)
- 将数据包上交 – 驱动程序调用
netif_rx()或 NAPI (napi_gro_receive()) → 数据包作为sk_buff进入堆栈。
早期内核网络堆栈处理(在 netfilter/iptables/nftables 之前)
数据包进入堆栈后(仍处于 softIRQ 上下文):
- GRO(通用接收卸载) – 合并数据包
- 用于某些协议的早期解复用(例如,高优先级控制流量)
- netfilter PREROUTING 钩子 (NF_INET_PRE_ROUTING) – 这是 iptables/nftables 规则可以查看/丢弃数据包的最早点
- IP 堆栈处理(如果是 IP):IP 头验证、TTL 递减、分段重组、路由查找、本地交付或转发
- 进一步的 netfilter 钩子(LOCAL_IN, FORWARD 等)
出站数据包(发送路径)
- 堆栈构建 IP 数据包 → 调用邻居解析(如果需要 ARP/ND) → 构建以太网头部
- 校验和卸载、TSO(TCP 分段卸载)、GSO(通用分段卸载)
- 驱动程序将帧排队到网卡的 TX 环 → 网卡传输
驱动程序/早期堆栈级别处理的常见协议汇总表
| EtherType / 协议 | 网卡驱动程序/早期内核堆栈是否处理? | 备注 |
|---|---|---|
| ARP (0x0806) | 是 | 始终在防火墙之前 |
| IPv4 (0x0800) | 是 | 所有 IPv4 数据包 |
| IPv6 (0x86DD) | 是 | 所有 IPv6 数据包 |
| 802.1X/EAPOL (0x888E) | 是 | 认证,通常在 IP 之前 |
| LLDP (0x88CC) | 是 | 链路层发现 |
| PTP (0x88F7) | 是 | 精准时间协议 |
| Wake-on-LAN | 是(通常在硬件中) | 魔术包 |
| Neighbor Discovery (ICMPv6) | 是 | 在防火墙之前在内核中处理 |
| 任何其他有效以太网帧 | 是 | 即使是未知类型也会到达堆栈 |
关键点:基本上,通过基本硬件检查的每一个以太网帧都由网卡驱动程序处理并进入内核网络堆栈然后才应用任何防火墙 (netfilter) 规则。防火墙规则从 netfilter 钩子(PREROUTING 是最早的)开始,它在驱动程序和非常早期的堆栈处理之后。
因此,除了 ARP,网卡驱动程序和早期内核堆栈处理所有链路层流量——正常的 IP 流量、ICMP、TCP、UDP、VLAN、控制协议等——所有通过网络到达的流量。