链路层不只是 MAC:以太网帧、ARP 与 802.1Q VLAN 的逐跳拆解
链路层的很多故障,表现出来却是「IP 配得没问题却 ping 不通」:同网段主机互相 ping 不通、抓包看到的目的地址是一串 ff 广播、换了个交换机端口又突然恢复。真正的问题往往不在 IP,而在帧里的 MAC 与 VLAN 标签。
只背熟 IP、子网掩码和端口是不够的。地址解析靠 ARP 缓存、帧转发靠交换机学习、广播隔离靠 VLAN 标签,这些都发生在看不见的二层,不理解就只能靠重启和换线碰运气。
本文分享一套能把二层问题一次讲透并落地的做法:MAC 位级拆解 + 802.1Q 帧剖析 + 端口模式与网关配置,可直接照着抓包和配交换机。
一、链路层定位:帧转发与子网边界
先明确链路层在整个协议栈里的职责边界:
- 向上交付封装:网络层给出 IP 报文,链路层负责把它包装成一条链路上能跑的帧,处理成帧、寻址与差错检测。
- 只管逐跳投递:MAC 寻址的有效范围被限制在同一个广播域内,跨网段必须交给路由器或三层交换机。
一句话记住:IP 负责端到端选路,MAC 负责逐跳交付,两者在网关处交接。
核心结论: 链路层解决的是「这一帧该从哪个口发出去」,而不是「这个包最终到哪台机器」。

二、MAC 地址拆解:48 位里的厂商与类型
一个 48 位的 MAC 地址里到底藏了哪些信息:
| 字段 | 位数 | 含义 |
|---|---|---|
| OUI | 24 | 厂商向 IEEE 申请的组织标识 |
| NIC 序号 | 24 | 厂商自行分配的网卡编号 |
| I/G 位 | 1 | 第一字节最低位,为 1 表示组播或广播 |
| U/L 位 | 1 | 第一字节次低位,为 1 表示本地管理地址 |
- 本地管理位的用法:虚拟化与容器场景经常改写 MAC,把 U/L 位置 1 就声明这是人工指定的地址,可避免与真实网卡冲突。
- 现场辨识:
ip link输出里的link/ether字段就是 MAC,广播地址恒为ff:ff:ff:ff:ff:ff。
核心结论: 前半段认厂商、后半段认网卡,两个控制位决定它是单播还是组播、真实还是虚拟。
三、以太网帧结构:从目的地址到 FCS
一帧数据在线缆上究竟是怎么排布的:
- 固定头部 14 字节:目的 MAC(6) + 源 MAC(6) + 类型(2),类型
0x0800是 IPv4、0x0806是 ARP、0x86DD是 IPv6。 - 载荷与校验:载荷 46~1500 字节,不足补 padding,超出则交给上层处理;末尾 4 字节 FCS 用 CRC32 校验,校验失败的帧直接丢弃。
下面这段 Python 把一段十六进制帧字节拆开,看清头部各字段的位置,适用于任何抓包导出的原始帧:
import struct
frame = bytes.fromhex('aabbccddeeff11223344556608004500001c')
dst, src = frame[0:6], frame[6:12]
ethertype = struct.unpack('>H', frame[12:14])[0]
print('dst =', ':'.join(f'{b:02x}' for b in dst))
print('src =', ':'.join(f'{b:02x}' for b in src))
print(f'ethertype = 0x{ethertype:04x}')
print('payload =', frame[14:])
类型字段一变上层协议就换,抓包时先看它再看内容。
四、ARP 解析:IP 到 MAC 的地址映射
拿到 IP 之后,主机怎么知道帧该发给谁:
- 两步闭环:先查本地 ARP 缓存,未命中就广播一条 ARP 请求(目的 MAC 全 F),持有该 IP 的主机单播回一条 ARP Reply。
- 缓存会老化:条目通常 20~30 秒过期,过期后重新广播,可用
arp -n随时查看。
抓取一问一答最直接的办法就是下面这段命令,适用于 Linux 主机定位「同网段 ping 不通」:
# 抓取本机网卡上的 ARP 请求与响应
sudo tcpdump -ni eth0 'arp' -c 6
# 查看本地 ARP 缓存
arp -n | head -5
ARP 是二三层之间唯一的翻译器,没有它 IP 报文根本落不到线上。

五、交换机学习:MAC 表的构建与泛洪
交换机凭什么知道该从哪个口发帧:
- 源地址学习:帧每进入一个端口,就把它的源 MAC 与端口号写入 MAC 表,并刷新老化时间(默认 300 秒)。
- 目的地址转发:查表命中就精准转发到对应端口,查不到就向除入端口外的所有端口泛洪。
源 MAC 学习 → 查目的 MAC → 命中单播 → 未命中泛洪 → 表项超时老化
核心结论: 交换机没有魔法,全靠「看源地址记账、按目的地址查账」这一条规则。
六、广播域痛点:为何单靠交换机不够
一台交换机撑起整个网络会出什么问题:
- 问题: 广播帧被复制到每一个端口,ARP 请求、DHCP Discover 与未知单播叠加起来,带宽和设备 CPU 被白白消耗,一处环路就能拖垮整网。
- 治理: 用 VLAN 把一台交换机在逻辑上拆成多台,广播只在本 VLAN 内传播,物理布线一根不动。
核心结论: 冲突域已经由交换机按端口隔离,剩下的广播域只能靠 VLAN 切开。

七、802.1Q:给帧打上 VLAN 标签
交换机怎么在帧里知道自己属于哪个 VLAN:
- 插入 4 字节标签:在源 MAC 与类型字段之间插入 TPID(
0x8100) + PCP(3 bit) + DEI(1 bit) + VID(12 bit),帧长上限因此从 1500 变为 1504。 - 12 位 VID 的边界:可用 VLAN 为 1~4094,0 与 4095 保留,0 通常表示这是一帧无标签数据。
这段 Python 用 Scapy 构造并解析一个带 802.1Q 标签的帧,适合在本机验证标签字段:
from scapy.layers.l2 import Dot1Q, Ether
pkt = Ether(dst='ff:ff:ff:ff:ff:ff') / Dot1Q(vlan=10) / 'payload'
pkt = Ether(bytes(pkt)) # 模拟抓包后重新解析
print('ethertype =', hex(pkt.type))
print('vlan id =', pkt[Dot1Q].vlan)
TPID 0x8100 是识别 VLAN 帧的唯一指纹,抓包时先认它再读 VID。

八、端口模式:Access、Trunk 与 PVID
三种端口模式到底差在哪,一张表看清楚:
| 模式 | 收到无标签帧 | 发出帧的处理 | 典型用途 |
|---|---|---|---|
| Access | 打上端口 PVID | 去掉标签发送 | 直连 PC、服务器、打印机 |
| Trunk | 按本征 PVID 处理 | 保留标签发送 | 交换机互联、接虚拟化宿主机 |
| Hybrid | 打上 PVID | 按允许列表决定去留 | 厂商扩展,灵活混用 |
- PVID 负责进门换牌:无标签帧进入 Access 或 Trunk 口时被打上的 VLAN 编号。
- 允许列表负责出门验牌:Trunk 口维护
allowed vlan清单,不在清单里的 VLAN 帧直接不放行。
核心结论: 收方向只看 PVID,发方向看端口类型加允许列表,两端配不齐就是「能学到 MAC 却不通」。
九、VLAN 间通信:三层交换与子网落地
分了 VLAN 之后,10 和 20 怎么还能互相访问:
- VLAN 即子网:每个 VLAN 配一个网关地址(交换机上叫 vlanif / SVI),网关在本设备终结二层、转到三层查路由。
- 三层交换优于外接路由器:硬件一次路由、之后按流交换,VLAN 间流量不用绕出设备。
在 Linux 上验证同样的网关行为,可以给网卡挂一个 VLAN 子接口充当 vlanif,适用于容器网络与虚拟交换机实验:
# 创建 VLAN 10 子接口并配置网关地址
sudo ip link add link eth0 name eth0.10 type vlan id 10
sudo ip addr add 192.168.10.1/24 dev eth0.10
sudo ip link set eth0.10 up && ip -d link show eth0.10
先划 VLAN、再配子网、最后挂网关,三步做完跨 VLAN 才通。

十、抓包排错:常见二层故障定位清单
二层出问题时按什么顺序查最省时间:
| 现象 | 抓包/命令特征 | 定位与处理 |
|---|---|---|
| 同网段 ping 不通 | 有 ARP 请求却无应答 | 查对端 IP 冲突、VLAN 是否一致 |
| 通一下断一下 | 出现错误 FCS 或错 VID 帧 | 查链路质量、Trunk 允许列表 |
| 网络整体变慢 | ARP 与未知单播大量泛洪 | 查环路,确认 STP 已启用 |
| 跨 VLAN 不通 | 网关上查不到 ARP 表项 | 查 vlanif 是否 UP、有无路由 |
- 三板斧顺序:
ip -d link show看本机 VLAN,arp -n看解析结果,tcpdump -nei eth0看真实帧头。 - 排查铁律:先二层后三层,帧都过不去时看路由表毫无意义。
核心结论: 二层故障的证据永远写在帧头的 MAC、VID 与 FCS 上,抓包比猜配置更快。
结语
把 MAC 地址的位级结构、以太网帧与 802.1Q 标签、交换机的学习与泛洪、端口模式与三层网关串起来,就能建立起一条完整的二层认知链:从「这一帧从哪来」到「这一帧往哪去」再到「跨网段时在哪一层交接」,每一跳都有可抓、可看、可验证的证据。
落到日常运维上,这套东西可以直接复用:新建业务先划 VLAN 和子网,接入前确认端口模式与 PVID,故障时按抓包三板斧从帧头往下查。别再让二层的问题伪装成三层的故障。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)