以太网帧、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 接口速率
| 名字 | 数据宽度 | 时钟 | 总线带宽 | 用途 |
|---|---|---|---|---|
| MII | 4 bit | 2.5 MHz | 100 Mbps | 100BASE-TX |
| GMII | 8 bit | 125 MHz | 1000 Mbps | 1000BASE-T |
| RGMII | 4 bit DDR | 125 MHz | 1000 Mbps | 板内 1G |
| XGMII | 32 bit | 156.25 MHz | 10 Gbps | 10GBASE-* |
| XLAUI | 4×10g serdes | — | 40 Gbps | 40GBASE-R |
| CAUI | 10×10g serdes | — | 100 Gbps | 100GBASE-CR4 |
| XFI | 1×10g serdes | — | 10 Gbps | 10GBASE-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 10G | 1e-10 量级 |
| OM4 多模 100G-DR4 | 1e-12 (预计温漂高时变 1e-10) |
| 单模 100G-ZR 80km | 1e-9 (FEC 关捞回来) |
| RoCEv2 PFC 期间 | 类似 1e-12 |
| 5G 无线 | 1e-6 (高层 HARQ / RLC 重传兜底) |
工业上无线链路与光纤链路 BER 相差 6 个数量级,所以上层重传策略完全不同——这就是为什么 4G/5G 用 HARQ + RLC + PDCP 三层捆绑重传。
真实生产事故参考
- Equinix 2020:某客户接入 Cisco Nexus 9332 配置一端强制
speed 10000 duplex full,对端 auto → duplex mismatch → 吞吐只有预期 50%、大量 late collision。教训:所有接入端口启用 auto-negotiation,不要禁用。 - 2019 上海某数据中心:单一天空调故障后机房内温度从 23°C 升到 65°C → SFP 光模块温度跨越工作点 → 大量 CRC 错误,部分链路自动 down。后续部署温度+光功率联监控(laser bias current + receiving optical power 长期趋势)就能在硬件崩塌前 24h 预警。
- 2017 某 IDC jumbo 坑:所有 ToR-Spine 配 9000 MTU 但有一个机架接入 leaf 误配 1500 → 大包不能转发 → 上层 TCP 重试,最终表现为 MapReduce shuffle 间隔 5-10s 一次的 fixed 延迟峰。教训:所有设备厂商默认 MTU 必须配置管理,新机柜上线时先做全路径 ping -M do -s 8972 验证。
这一章带走的东西
- 帧每段都是为时钟恢复 / 寻址 / 上层封装 / 检错专门设计;64 字节最小帧是 10 Mbps 下冲突窗口的物理痕迹
- CSMA/CD 退避算法 = 二进制指数 + slot time;现代全双工链路已不使用但保留作兼容
- MII/GMII/XGMII 是 MAC↔PHY 接口分层,只对硬件工程师有意义——名字里的 X/S/L/R 是 IEEE 802.3 clause 的语义
- CRC-32 检错 ≠ 完整性签名,链路层做到 BER 1e-12 后端到端必须用 TLS MAC / IPsec ESP
- 巨型帧 9000 在数据中心 5-10% 性能收益,但跨互联网会触发 PMTUD 黑洞
下一节 → 光纤、波分复用、机房布线