Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

以太网帧、CSMA/CD、PHY/MAC

TL;DR

深入拆 802.3 以太网:帧格式每一段为什么这么贴、CSMA/CD 算法细节、PHY 与 MAC 芯片实际怎么分块、为什么 100M 时代叫 MII、1000M 叫 GMII、10G 叫 XGMII——名字背后真实都是 IEEE 802.3 clause 的硬件 IP 切分边界。

思维链

应用层以为 Ethernet 是个抽象概念,但每个开关 + 编码 + 物理标准都是真实硬件

你的 sysctl 设 MTU=1500 → 内核 skb data 大小 = 1514 (含 MAC header)
   -> 网卡驱动 prep 渲染页 + pre-pad VLAN tag + 加 EtherType
   -> MAC 重新组帧:Preamble(7) + SFD(1) + Header(14) + Payload(1500) + FCS(4)
   -> PCS 编 64b/66b + 扰码
   -> PMA 串并转换并把 8 通道并行 (10G) 转换成 4 通道 25Gbps serdes
   -> PMD 把 25Gbps 电信号变光(laser driver)打向光纤

每个步骤背后都是 IEEE 802.3 标准的某个 clause + 各厂商芯片 IP。每个 PorV/Vendor 自己的 SDK 大小写参数都没调好就是出工程师连夜加班的根因。

帧格式的每一字节

    7        1         6        6        2       46-1500      4      12
+---------+---------+-------+--------+--------+-----------+-------+------+
|Preamble | SFD     |  DA    |   SA    | EtherType|  Payload   |  FCS  | IFG  |
|10101010×|10101011 |48bit MAC| 48bit   | 16 bit  |  上层协议  |CRC-32 | 9.6 µs|
|   7     |         |        |        |         |            |       |(Gbps用减少到1B) |
+---------+---------+-------+--------+--------+-----------+-------+------+
  • Preamble 7 字节:收端时钟恢复用,让 PLL 锁定相位。共享介质时代所有节点靠这 7 字节"时基对齐"。10G 全双工后理论上 Preamble 可省,但所有以太网帧都保留作兼容。
  • SFD 1 字节10101011 标记帧起点(与 Preamble 的最后一位相反)。
  • DA/SA:MAC 地址 6 字节,前 24 bit 是 IEEE OUI(厂商代码),后 24 bit 厂商自分配。FF:FF:FF:FF:FF:FF 是广播、首字节 bit0=1 是组播。
  • EtherType:< 1536 是 length(802.3 raw 格式,几乎绝迹),≥ 1536 标识上层(0x0800 IPv4, 0x86dd IPv6, 0x0806 ARP, 0x88cc LLDP, 0x8906 RoCEv2, 0x8915 NSH)。
  • Payload 46-1500:< 46 字节要 padding 凑 64 字节最小帧。
  • FCS 4 字节:CRC-32 多项式 0x04C11DB7
  • IFG 12 字节:帧间间隔(9.6 µs @10M,1.2 µs @1G),10G+ 可缩到 0.096 µs(1 字节时间)。这是物理层强制间隔,给收端腾出"处理一帧"的时间。

巨型帧(Jumbo Frame)

9000 字节 payload 用于 SAN / 大数据 Shuffle / RoCE:

  • 1500 MTU: 4 KB 文件 = 2.7 个包 → 协议头开销 18/1518 ≈ 1.19%
  • 9000 MTU: 4 KB 文件 = 0.45 个包 → 协议头开销 18/9018 ≈ 0.20%
  • 减少 NIC 中断 → CPU 占用降 30-50%
  • Spark / Flink 网络洗牌用 jumbo 后 CPU 利用率有 10-20% 的下降

但跨互联网必须 PMTUD 路径发现,否则 jumbo 在普通路由器上触发分片丢包。AWS 内 VPC、Azure 内、自建数据中心可以全部 9000;跨云不要用。


CSMA/CD 完整算法

发送:

1. 监听介质 (carrier sense),忙 -> 等待空闲
2. 开始发送
3. 边发边听:
   - 检测到冲突 -> 立即停止 -> 发 32 bit jam signal
   - -> 二进制指数退避
4. 退避次数 K <- min(10, retry_count)
   - backoff_time = random() % (2^K) × slot_time
   - 10 Mbps slot_time = 51.2 µs (512 bit 时间)
5. 16 次失败 -> 抛弃帧

为什么退避最大 10 而不是更大?2^10 × 51.2 µs = 26 ms 已经远超冲突窗口,再大无意义。

全双工模式

交换机的每端口是点对点链路,无共享介质、无冲突检测。所以 CSMA/CD 实际不启用。半双工(同轴 / Hub)才用得上。所有现代以太网都是全双工。


MAC 体系

MII / GMII / XGMII 接口速率

名字数据宽度时钟总线带宽用途
MII4 bit2.5 MHz100 Mbps100BASE-TX
GMII8 bit125 MHz1000 Mbps1000BASE-T
RGMII4 bit DDR125 MHz1000 Mbps板内 1G
XGMII32 bit156.25 MHz10 Gbps10GBASE-*
XLAUI4×10g serdes40 Gbps40GBASE-R
CAUI10×10g serdes100 Gbps100GBASE-CR4
XFI1×10g serdes10 Gbps10GBASE-SR/LR

每个都以 8b/10b 或 64b/66b 编码传输。MAC 与 PHY 之间的片内总线 → 这些 MII/XGMII 的存在是为了让 MAC vendor 和 PHY vendor 可以独立 IP 授权,让 ASIC 集成度可以增长。

note

名字里的 X/XG/S/X/SR/LR 这些前缀其实就是 IEEE 802.3 clause 编号区分:

  • X = 10G
  • S = Short Reach (<100m, 多模)
  • L = Long Reach (<10km, 单模)
  • R = Extended Reach
  • CR = Copper (直连铜)

PHY 内部:千万级门电路

10GBASE-KR PHY 内部数字部分:

MAC 8B  ||  TX_PMA  <-  TX_PCS  <-  64b/66b enc  <-  GMII
      ||                                ↑
      ||                            scramble + LDPC/BCH
MKD ||  RX_PMA   ->  RX_PCS  ->  64b/66b dec  ->  GMII
  • PCS: 64b/66b 编码 + Lane skew 对齐(多 lane)/ FEC
  • PMA: 串并转换 + CDR (Clock Data Recovery)
  • PMD: 激光驱动 / 铜驱动

Auto-Negotiation 与 FEC

10G、25G 等速率需要 RS-FEC(528/514 子编码)来纠正 BER 让光模块尺寸可以缩到 1U:

  • 25G Base-R: FEC on/off 由 link partner 能力决定
  • 25G RS-FEC: 528 symbol 中 514 信息 + 14 校验 → BER 1e-5 → 1e-12

启动时 AN 协商 FEC on/off,开 FEC 多 4%-5% 带宽开销但能纠错,关 FEC 反之。


CRC-32 检错不是签名

FCS 是 CRC-32 IEEE 802.3:

def crc32_eth(data):
    crc = 0xFFFFFFFF
    for b in data:
        crc ^= b << 24
        for _ in range(8):
            crc = (crc << 1) ^ (0x04C11DB7 if crc & 0x80000000 else 0)
            crc &= 0xFFFFFFFF
    return crc ^ 0xFFFFFFFF
  • 能检出所有 ≤ 31 bit 突发错(突发错 = 连续 bit 错误)
  • 能检出双 bit 错(2 bit distance 的多项式构造保证)
  • 漏检概率 ≈ 2^-32 ≈ 2.3e-10
  • 不是密码学哈希:恶意攻击者可构造碰撞 → 所以不能用于完整性校验在已被人工修改的场景

但实际硬件线上:CRC32 + 距离 ~4 是非常够用了,因为线上 bit flip 来自信道噪声而非攻击者。链路层做到 BER 1e-12,端到端的 TLS MAC(HMAC SHA-256)和 IPsec ESP 才负责"完整性防伪"。


物理层中的误码 (BER)

不同介质的典型残留 BER:

介质残留 BER
Cat6A 10G1e-10 量级
OM4 多模 100G-DR41e-12 (预计温漂高时变 1e-10)
单模 100G-ZR 80km1e-9 (FEC 关捞回来)
RoCEv2 PFC 期间类似 1e-12
5G 无线1e-6 (高层 HARQ / RLC 重传兜底)

工业上无线链路与光纤链路 BER 相差 6 个数量级,所以上层重传策略完全不同——这就是为什么 4G/5G 用 HARQ + RLC + PDCP 三层捆绑重传。


真实生产事故参考

  1. Equinix 2020:某客户接入 Cisco Nexus 9332 配置一端强制 speed 10000 duplex full,对端 auto → duplex mismatch → 吞吐只有预期 50%、大量 late collision。教训:所有接入端口启用 auto-negotiation,不要禁用
  2. 2019 上海某数据中心:单一天空调故障后机房内温度从 23°C 升到 65°C → SFP 光模块温度跨越工作点 → 大量 CRC 错误,部分链路自动 down。后续部署温度+光功率联监控(laser bias current + receiving optical power 长期趋势)就能在硬件崩塌前 24h 预警。
  3. 2017 某 IDC jumbo 坑:所有 ToR-Spine 配 9000 MTU 但有一个机架接入 leaf 误配 1500 → 大包不能转发 → 上层 TCP 重试,最终表现为 MapReduce shuffle 间隔 5-10s 一次的 fixed 延迟峰。教训:所有设备厂商默认 MTU 必须配置管理,新机柜上线时先做全路径 ping -M do -s 8972 验证。

这一章带走的东西

  1. 帧每段都是为时钟恢复 / 寻址 / 上层封装 / 检错专门设计;64 字节最小帧是 10 Mbps 下冲突窗口的物理痕迹
  2. CSMA/CD 退避算法 = 二进制指数 + slot time;现代全双工链路已不使用但保留作兼容
  3. MII/GMII/XGMII 是 MAC↔PHY 接口分层,只对硬件工程师有意义——名字里的 X/S/L/R 是 IEEE 802.3 clause 的语义
  4. CRC-32 检错 ≠ 完整性签名,链路层做到 BER 1e-12 后端到端必须用 TLS MAC / IPsec ESP
  5. 巨型帧 9000 在数据中心 5-10% 性能收益,但跨互联网会触发 PMTUD 黑洞

下一节 → 光纤、波分复用、机房布线