本页目录

Ethernet 与 MAC

以太网帧是"万物皆可封装"的起点——从 MAC 地址到 VLAN 到链路聚合,二层是所有上层协议的基础承载。理解帧结构和交换原理,就理解了"数据包怎么从一根线到另一根线"。

概述

Ethernet 是全球最广泛部署的局域网技术,从 1973 年 Bob Metcalfe 在 Xerox PARC 的 2.94Mbps 原型到现在的 800Gbps 光口,核心帧格式几乎没变。它工作在 OSI L2(数据链路层),负责在同一广播域内将帧从源 MAC 地址送到目标 MAC 地址。802.3 标准家族在此基础上扩展了 VLAN 隔离(802.1Q)、流控(802.3x PAUSE)、链路聚合(802.3ad LACP)等功能。Linux 内核通过 net/ethernet/drivers/net/ 提供协议处理与硬件驱动抽象。

802.3 帧格式

Ethernet 帧结构从 1980 年 DIX 规范至今几乎没有本质变化。唯一值得注意的演进是 802.1Q VLAN tag 的插入和 802.3ad LACP 的协商层。

Octet 0-6:   Preamble (7 × 0x55)
              PHY 层使用,用于时钟同步和 bit-locking。10Mbps 时极其重要
              (Manchester encoding),现代 SerDes 不需要但没有移除。

Octet 7:     SFD (Start Frame Delimiter = 0xD5)
              标记帧开始。最后一个 preamble byte 的低位不同 — 0x55 →
              0xD5 (bit 0: 1→1, bit 2: 1→0) — 硬件检测此跳变锁定字节边界。

Octet 8-13:  Destination MAC (6 bytes)
              Bit 0 of byte 0: 0 = unicast, 1 = multicast.
              全 1 (ff:ff:ff:ff:ff:ff) = broadcast — 交换机泛洪到所有端口。

Octet 14-19: Source MAC (6 bytes)

Octet 20-21: EtherType or Length (2 bytes)
              ≤ 1500 (0x05DC): 解释为 Length (802.3 raw mode, 极少用)
              ≥ 1536 (0x0600): 解释为 EtherType
              关键值:
                0x0800  IPv4
                0x0806  ARP
                0x8100  VLAN (802.1Q)
                0x86DD  IPv6
                0x88A8  Q-in-Q / Provider Bridge (802.1ad)
                0x8870  Jumbo frame (非标准, 某些驱动使用)
                0x8809  Slow Protocols (LACP, 802.3x PAUSE)

Octet 22+:   Payload
              标准: 46-1500 bytes (不含 VLAN tag)。
              不够 46 字节 → 填充到 46 (padding)。填充内容未定义 —
              Linux 用零填充, 其他驱动可能用随机数据。
              Padding 不计入 IP header 的 Total Length — 接收方
              通过 EtherType/Length 字段或 L3 header 的 length 区分。

CRC:         FCS (Frame Check Sequence, 4 bytes, CRC-32)
              多项式: x³² + x²⁶ + x²³ + x²² + x¹⁶ + x¹² + x¹¹ + x¹⁰ + x⁸ + x⁷ +
                       x⁵ + x⁴ + x² + x + 1
              计算范围: Destination MAC 到 Payload 末尾 (不含 Preamble/SFD/FCS 自身)
              硬件 (MAC controller) 计算和验证 → 错误帧由硬件丢弃,内核看不到。
              某些驱动可以配置"接收错误帧"模式 (ethtool -K rx-fcs on),
              用于调试 (tcpdump 可以看到 FCS 错误计数)。

Inter-Frame Gap (IFG):
  帧间间隔: 12 byte times (96 bit times) of idle.
  1000BASE-T: 96 ns
  10GBASE-R:  9.6 ns
  100GBASE-R: 0.96 ns
  高速率下 IFG 极紧 — 硬件必须在一个 IFG 内完成前帧处理并开始下一帧的 preamble
  detection。这也是为什么高速网卡需要 buffer descriptor ring 而不是逐帧中断。

MAC 地址结构

48 bits (6 bytes), IEEE 分配, 全球唯一 (理论上):

Byte 0, bit 0 (I/G bit):
  0: Unicast (individual address)
  1: Multicast (group address)
  → 这是 MAC 层判断"这个帧是不是给我的"第一步 — 网卡硬件检查

Byte 0, bit 1 (U/L bit):
  0: Universally Administered (厂商烧录的 OUI)
  1: Locally Administered (软件设置的, 如虚拟网卡、容器、MAC 随机化)

OUI (Organizationally Unique Identifier): bytes 0-2 = IEEE 分配
NIC-specific: bytes 3-5 = 厂商内部分配

Linux 操作:
  ip link set eth0 address aa:bb:cc:dd:ee:ff    ← 改 MAC (需要 down)
  ip link show eth0 | grep link/ether

802.1Q VLAN

VLAN tag (4 bytes) 插入在 Source MAC 之后、EtherType 之前:

Octet 0-1: TPID (Tag Protocol Identifier)
             0x8100 = Customer VLAN (C-VLAN)
             0x88A8 = Service Provider VLAN (S-VLAN, 802.1ad)
             0x9100 = 旧式 (被 0x88A8 取代)

Octet 2-3: TCI (Tag Control Information):
  Bits 0-2:    PCP (Priority Code Point, 802.1p)
               0 = Best Effort, 1 = Background, 2 = Spare, 3 = Excellent Effort,
               4 = Controlled Load, 5 = Video, 6 = Voice, 7 = Network Control
               → 映射到 sk_buff->priority → tc qdisc 的队列选择
  Bit 3:       DEI (Drop Eligible Indicator)
               1 = 拥塞时可优先丢弃 (与 IP DSCP 的 ECN 不是一回事)
  Bits 4-15:   VID (VLAN Identifier)
               有效值: 1-4094 (0 = no VLAN, 4095 = reserved)
               每个以太网接口可以属于多个 VLAN (trunk port)

Q-in-Q (802.1ad, Provider Bridge):
  双层 VLAN tag:
    [DA][SA][0x88A8][S-VLAN TCI][0x8100][C-VLAN TCI][EtherType][Payload]
  外层 (S-VLAN) = 运营商网络隔离
  内层 (C-VLAN) = 客户自用的 VLAN

  Linux:
    ip link add link eth0 name eth0.100 type vlan id 100
    ip link add link eth0.100 name eth0.100.200 type vlan id 200 proto 802.1ad

Jumbo Frames

标准 MTU 1500 字节是 10Mbps Ethernet 时代的妥协 — 小 MTU 意味着短的 slot time, 短的冲突检测窗口。切换到 switched Ethernet 后,物理上不再需要这个限制,但 标准 MTU 被所有上层协议假设为默认值。

Jumbo MTU: 通常 9000 bytes (非标准, 但广泛支持)

收益:
  - 减少中断: 1 × 9000B 帧 vs 6 × 1500B 帧 — 中断减少 6x
  - 减少 CPU 处理: 网卡 per-packet overhead (descriptor, DMA sync) 减小 6x
  - 减少 header 开销: 5 个额外帧的 (14B Eth + 20B IP + 20B TCP) × 5 = 270B 省了
  - NFS/iSCSI: 大部分 IO 是 4KB-64KB, jumbo 可以在一个帧内装下更多

代价:
  - 路径上所有设备 (交换机、路由器、NIC) 必须支持 jumbo
  - 不支持 jumbo 的设备: 静默丢弃 (no ICMP Frag Needed unless IP DF set)
    → "MTU black hole" — 最难排查的网络问题之一

配置:
  ip link set eth0 mtu 9000
  /etc/dhcpcd.conf 或 NetworkManager: 持久化 MTU
  注意: bridge 的 MTU 必须 ≥ 其所有 slave 的 min MTU

PAUSE (802.3x) 与 PFC (802.1Qbb)

802.3x PAUSE frame:
  EtherType: 0x8808
  MAC Control Opcode: 0x0001 (PAUSE)
  Pause Time: 2 bytes (in units of 512 bit times)
  发送到组播地址: 01:80:c2:00:00:01

  接收方: 发 PAUSE frame (pause_time=N)
  发送方: 在 N × 512 bit times 内停止发送
  问题: 一个 flow 的拥塞 → 整个链路的流量停止
        → 不适合多流量混合的场景 (数据中心用 PFC)

PFC (Priority-based Flow Control, 802.1Qbb):
  按 PCP (8 个优先级) 独立控制:
  只有拥塞的优先级被 pause → 其他优先级继续传输
  → RoCE (RDMA over Converged Ethernet) 的硬件基础

LACP (802.3ad / 802.1AX)

LACP 将多个物理口捆绑为一个逻辑链路:

LACPDU (Link Aggregation Control Protocol Data Unit):
  EtherType: 0x8809 (Slow Protocols)
  Subtype: 0x01 (LACP)
  每 30 秒 (slow) 或每秒 (fast) 发一次

LACPDU 内容:
  Actor: system_priority + system_id (MAC) + key + port_priority + port_number + state
  Partner: (同上, 远端信息)
  Collector: max_delay

State bits (关键的):
  LACP_Activity (bit 0): Active (主动发 LACPDU) vs Passive (只响应)
  LACP_Timeout (bit 1): Long (30s) vs Short (1s)
  Aggregation (bit 2): 此端口可以聚合
  Synchronization (bit 3): 此端口已同步 (准备转发)
  Collecting (bit 4): 入流量可以转发
  Distributing (bit 5): 出流量可以转发
  Defaulted (bit 6): 用默认参数 (partner 未响应)

Linux bonding modes:
  mode=0 (balance-rr): 轮询 — 不依赖 LACP, 只 load balance
  mode=1 (active-backup): 一主一备 — 不依赖 LACP
  mode=2 (balance-xor): 按 MAC hash — 需要交换机配合
  mode=4 (802.3ad): LACP 动态协商 — 交换机必须也开 LACP

参考

  • 802.3-2022: IEEE 标准 (P802.3 工作组)
  • 内核⁠: net/ethernet/eth.c (协议处理), drivers/net/bonding/ (LACP), net/8021q/ (VLAN)
  • LWN: "Jumbo frames and MTU in Linux"

关键词: Ethernet, 802.3, MAC address, 802.1Q, VLAN, Q-in-Q, jumbo frame, PAUSE, LACP, 802.3ad