首页 / 资讯中心 / 文章详情

数据链路层核心原理:MAC地址、以太网帧与交换机转发机制解析

数据链路层核心原理:MAC地址、以太网帧与交换机转发机制解析 ★ FEATURED ARTICLE
十年前我第一次在模拟器里敲下 show mac address-table看着那几行 MAC 和端口映射并不觉得数据链路层有什么特别。直到后来排障时发现很多网络“通了却不对”的问题根源都藏在这一层。数据链路层是连接物理传输与网络逻辑之间最容易被忽略的一环它管的是相邻设备之间的帧交付——怎么把一段 0 和 1 变成可靠的、可识别的数据单元并且能发现过程中是否出了错。这篇文章我就从自己的理解和排障经验出发把数据链路层的核心知识拆开讲清楚适合正在学计算机网络的人、准备面试的开发人员以及那些想真正理解交换机工作原理的运维新手。1. 数据链路层的定位物理链路之上最容易被忽略的交付环节1.1 为什么物理层“通了”数据还是传不对物理层的任务是把比特从一台设备送到另一台设备它不关心这些比特的含义。但实际工程里单纯把比特送出去是远远不够的。想象一下你让一个人去传话他确实把话传到对面了可对面怎么知道一段话从哪里开始、从哪里结束怎么确认中间没有被噪音干扰导致几个字听错了这就是数据链路层要解决的问题。数据链路层工作在网络层之下、物理层之上它的输入是网络层下发的 IP 数据报输出是封装好的帧。帧是数据链路层的基本传输单位由首部、数据和尾部组成。首部通常放目的地址、源地址尾部放校验字段。物理层只负责把帧里的比特串逐个发出去而数据链路层负责把比特组织成帧并让接收方能够识别帧的边界、验证帧的内容。学习这一层时最容易产生的误区是觉得它“只是加个头部而已”。实际上数据链路层承担了相当多的工作组帧、定界、透明传输处理、差错检测、介质访问控制还有 MAC 地址寻址。一个数据从 A 主机到 B 主机中间每经过一条链路、一台交换机或路由器数据链路层都会在对应链路上重新封装成帧逐段完成交付。1.2 “链路”和“数据链路”的边界到底在哪有两组概念经常被混用。一组是链路link与数据链路data link另一组是 MAC 子层与 LLC 子层。链路就是一条无源的点到点物理线路中间没有任何交换节点。而数据链路是物理链路加上实现通信协议的硬件和软件概念上相当于“能跑协议的链路”。打个比方物理链路是修好的公路数据链路是公路加上交通规则、信号灯和交警光有路还跑不起来。在这个基础上IEEE 802 标准把数据链路层拆成了两个子层LLC逻辑链路控制子层面向网络层负责和上层“对话”包括帧的复用与分用、流量控制等。它在实际硬件中体现不明显更多是规范层面的抽象。MAC介质访问控制子层面向物理层负责封装成帧、差错检测和介质访问控制。我们平时说的 MAC 地址就归属于这一子层。这个拆分解释了为什么同一块网卡可以支持多种上层协议LLC 层做协议标识和分发MAC 层负责具体的帧收发。理解了这个分层后面看 Ethernet 帧里的 EtherType 字段就很顺理成章了。2. 三个基本功封装成帧、透明传输、差错检测到底在防什么2.1 封装成帧帧定界和 MTU 的由来封装成帧就是在数据前后加上首部和尾部使接收方可以从比特流中切分出一个个帧。教材里提到用 SOHStart of Header和 EOTEnd of Transmission来做帧定界那是早期串行链路的标准思路。但现代以太网并不靠特殊字符定界它的帧边界靠物理层前导码和帧间隙来识别帧内还带有长度字段。这里要特意说明教材讲的是通用原理工程实现往往不同。帧的数据部分不是无限大的。以太网 V2 标准规定数据部分最小 46 字节、最大 1500 字节这个 1500 字节就是常见的 MTU。为什么有下限因为以太网是最小帧长 64 字节的设计首部 14 字节加尾部 4 字节数据不足 46 字节时需要填充否则无法在冲突检测机制下正常工作。为什么有上限限制单帧长度可以减少传输错误的影响范围也方便缓冲区管理。如果上层数据超过 MTU网络层的 IP 分片就会把数据拆成多个 IP 数据报再由数据链路层分别封装成帧发送。2.2 透明传输当数据里出现了“定界符”透明传输指的是无论数据部分是什么比特组合都应该能正确、透明地被传输接收方不应把数据里的内容误认为是控制信息。经典做法有两种。第一种是面向字节的链路采用字节填充也叫字符填充。当数据中出现帧定界符的比特组合时发送方在它前面插入一个转义字符接收方收到转义字符后知道下一个字符是数据而非控制符于是将其删除。第二种是面向比特的链路采用零比特填充。以 HDLC 为例帧的首尾都用 01111110 作为标志数据部分若出现连续 5 个 1发送方自动在后面补一个 0接收方检测到连续 5 个 1 后若第 6 位是 0就删除这个 0 并恢复原始数据。这样01111110 就不会在数据区“冒充”帧边界。实际排障时透明传输问题主要出现在串口通信、HDLC/PPP 封装的广域网链路中。以太网因为本身不依赖标志字节定界受这个问题的困扰很小。2.3 差错检测CRC 校验背后的数学逻辑和工程取舍数据在物理链路上传输会受到干扰、衰减、瞬断等影响出现比特翻转。数据链路层要做的不是保证不出错而是能在接收时发现错误。最常用的手段是 CRC循环冗余校验。CRC 的原理是用模 2 除法代替普通算术除法。发送方把数据看作一个二进制多项式左移若干位后除以一个约定的生成多项式取余数作为 FCS帧检验序列附加在数据后面。接收方把数据和 FCS 一起除以同一个生成多项式若余数为 0则认为没有检测到差错。这里要强调“没有检测到”而不是“没有发生”因为任何校验都不可能覆盖所有错误模式。以以太网为例采用的是 CRC-32生成多项式里最高次项达到 32。它能检测出所有长度不大于多项式阶数的突发错误对更长的突发错误漏检率也很低。有人问为什么不用纠错。数据链路层的选择很务实检错比重传成本低误码率不高时帧出错后直接丢弃并要求重传更合理而纠错编码冗余大、开销高只有像无线链路这种误码率高的场景才考虑前向纠错。3. MAC 地址与 IP 地址一条链路上的两张“身份凭证”3.1 MAC 地址结构为什么说它是“硬件身份证”MAC 地址是数据链路层寻址的依据长度 48 位6 字节通常写成 00:1A:2B:3C:4D:5E 这种格式。它的前 24 位是 OUI组织唯一标识符由 IEEE 分配给厂商后 24 位由厂商自行分配。理论上网卡出厂时 MAC 地址是唯一的因此常被称作“硬件地址”。但严格说MAC 地址并不完全等于硬件。第一很多网卡支持在驱动层修改 MAC 地址第二虚拟化环境里虚拟机网卡的 MAC 由虚拟机管理程序分配第三交换机等设备拥有多个 MAC 地址分别对应不同接口。所以更准确的说法是MAC 地址是链路层接口的标识重点在于它是“接口维度”的地址而不是“节点维度”的地址。MAC 地址有三个特殊位需要留意单播/组播位和全局/本地位。目的地址最低字节的最低位为 0 时是单播地址为 1 时是组播地址全 1 的 FF:FF:FF:FF:FF:FF 是广播地址只能作为目的地址。这些细节在抓包时非常有用。3.2 IP 地址与 MAC 地址的分工逻辑IP 地址和 MAC 地址最大的区别是结构。IPv4 地址是分层次的由网络号加主机号构成适合路由汇总和查找MAC 地址是扁平结构没有网络号与主机号的划分因此不可聚合也基本无法在大型网络中做高效路由。两者配合方式很明确IP 地址负责“到网段”MAC 地址负责“到接口”。数据从 A 主机发给 B 主机时IP 地址在整个传输过程中基本保持不变而 MAC 地址每经过一条链路都会重新封装。网络层只关心下一跳的 IP数据链路层只关心下一跳的 MAC。这种分工有点像快递IP 地址是收件人的姓名和所在城市MAC 地址是具体小区和门牌号。快递每到一座城市都需要在当地换成“精确到门牌”的派送信息但收件人始终是那个人。那 IP 怎么找到 MAC靠 ARP 协议。主机想发数据给同一链路内的某个 IP 时先在 ARP 缓存表里找对应 MAC找不到就发广播询问“谁的 IP 是 192.168.1.1请把你的 MAC 告诉我”。目标主机收到后单播回复随后双方进入正常通信。3.3 以太网帧格式从字节层面看懂一帧数据以太网 V2 帧格式如下字段长度说明前导码7 字节物理层同步用不属于 MAC 帧帧开始定界符SFD1 字节标记帧开始目的 MAC 地址6 字节接收方接口地址源 MAC 地址6 字节发送方接口地址类型/长度2 字节0x0800 表示 IPv40x86DD 表示 IPv60x0806 表示 ARP数据载荷46-1500 字节上层协议数据FCS4 字节CRC-32 校验结果这个表看起来简单但有两点非常实用。第一类型字段的值决定了上层协议所以抓包时只要看到 0x0806基本就是 ARP 报文跟 IP 无关。第二FCS 只覆盖从目的 MAC 到数据载荷的部分不包括前导码。分析抓包时看到损坏帧或 FCS 错误通常说明物理链路或网卡有问题而不是协议配置有问题。4. 以太网与交换机从“总线吵架”到“自学习查表”4.1 半双工时代的 CSMA/CD为什么现在很少提了早期的以太网是总线型拓扑所有设备共享同一个冲突域。两台设备同时发送数据时信号在总线上叠加产生冲突导致数据作废。为了解决这个问题以太网设计了 CSMA/CD载波监听多点接入/碰撞检测协议。它的规则可以总结为“先听后发、边发边听、冲突停发、随机重发”。发送前先监听信道信道空闲后开始发送发送过程中同时监听一旦检测到冲突立即停止并发送一个强化冲突信号让其他站点知道然后等待一段随机退避时间再重试。为了保证冲突能被检测到帧必须足够长以太网因此规定最小帧长为 64 字节并设计了一个争用期 51.2 微秒的概念。现在为什么很少提因为交换机组网后每个端口都是一个独立的冲突域全双工模式下同时收发互不干扰CSMA/CD 在双绞线交换网络中基本不需要工作。所以现在检测到大量冲突计数往往不是协议问题而是物理接口双工不匹配导致的。4.2 交换机自学习一张 MAC 地址表是怎么填满的交换机工作在数据链路层核心能力是转发但它的转发不是盲目的。交换机内部维护一张 MAC 地址表记录 MAC 地址、所属 VLAN、关联端口和老化时间。这张表不是手工配置出来的而是通过自学习得来的。自学习过程分三步。第一收到帧后把帧的源 MAC 地址和接收端口对应起来写入地址表。第二查目的 MAC 地址如果表里有就从对应端口精确转发如果表里没有则向除接收端口外的所有端口泛洪Flooding也可以理解为“我不知道目的方向那就问所有人”。第三如果目的设备回包交换机又能从回包中学习到它的位置后续转发就变得精确了。这里有个容易被误解的点交换机查表查的是 MAC 地址不是端口号。地址表的本质是“去往某个 MAC 的设备应该从哪个端口出去”所以它的转发决策在逻辑上是一个查找过程。每一条新学习到的表项都有老化时间默认 300 秒左右设备长期不说话后表项消失避免因设备迁移而保留过期路径。4.3 广播域与交换机的“能力边界”交换机可以隔离冲突域但隔离不了广播域。广播帧会被泛洪到同一广播域的所有端口广播域越大广播开销越高。如果网络中出现了二层环路广播帧会在环路里无限循环形成广播风暴瞬间打满交换机 CPU 和链路带宽。这也是为什么生产环境必须启用 STP生成树协议来逻辑上阻断冗余链路只保留一条无环路径。STP 本身不是数据链路层的“显眼”内容但它是理解交换机能力边界的关键交换机只关心链路层可达性它不对全网拓扑做集中计算必须靠协议避免环路。初学者容易把交换机和路由器混在一起。交换机工作在二层认识 MAC 地址不解析 IP 报文头不修改帧内容路由器工作在三层按 IP 路由表做最长前缀匹配转发时会重写 MAC 地址。分清这两个边界比记住一堆配置命令更重要。5. 从 VLAN 到链路聚合真实组网里的数据链路层调优5.1 VLAN 的本质在二层给广播域“画圈”默认情况下一台交换机上所有端口在同一个广播域里广播帧会被泛洪到整台设备。如果接入设备数量多广播报文造成的 CPU 中断和链路占用相当可观同时所有设备二层互通也带来安全隐患。VLAN虚拟局域网就是用来在二层隔离广播域的。VLAN 的核心思想是把一台交换机在逻辑上切成多台。每个 VLAN 是一个独立的广播域VLAN 内的广播不会跨 VLAN 传播。不同 VLAN 之间的通信必须经过三层设备路由器或三层交换机也就是说VLAN 划分把“二层互通”和“三层互访”做了明确区分。配置 VLAN 时要理解两种端口角色。Access 端口只属于一个 VLAN一般接终端设备发出的帧不带 VLAN 标签。Trunk 端口默认放行多个 VLAN用于交换机之间级联帧上通常带着 802.1Q 标签。这样一来VLAN 信息才能在多台交换机之间传递同一 VLAN 的设备跨交换机通信时交换机能够识别数据属于哪个 VLAN。5.2 802.1Q 标签这 4 个字节插在哪、怎么读802.1Q 标准给以太网帧增加了一个 4 字节的 VLAN 标签插在源 MAC 地址和类型/长度字段之间。很多人第一次看到带有 VLAN 标签的帧时会发现类型字段不再直接是 0x0800而变成 0x8100这就是识别 VLAN 帧的关键标志。802.1Q 标签结构如下字段长度说明TPID2 字节固定 0x8100表示这是一个带 VLAN 标签的帧PCP3 位优先级用于 QoS 服务级别映射DEI1 位丢弃可指示位拥塞时优先丢弃低优先级帧VID12 位VLAN 编号范围 0-4095实际可用 1-4094接终端设备的 Access 口发送帧前会剥离标签确保终端不认识 VLAN 也不影响通信Trunk 口则保留标签因为跨交换机必须靠 VID 区分广播域。看抓包时如果帧里出现 0x8100先判断是不是 Trunk 口抓的不要误以为协议出了问题。5.3 链路聚合把多条物理链路当成一条逻辑链路链路聚合Link Aggregation是把多条物理以太网链路捆绑成一条逻辑链路的技术业内常称 port-channel 或 bond。它的价值有两块带宽叠加和链路冗余。两条 1G 链路聚合后逻辑上呈现为一条 2G 链路但实际负载分担不是简单的“各走一半”而是根据报文的哈希因子源 MAC、目的 MAC、源 IP、目的 IP、端口号等计算后分配到某条物理链路。因此带宽上限取决于流数量而不是单条流被分成两半。聚合还有一个隐藏价值成员链路之间互为备份。某条物理链路断开时流量会自动通过其余链路转发对上层协议基本透明。配置时要注意两端设备的聚合模式、速率和双工必须一致否则会出现丢包。对于纯二层场景不少厂商的静态聚合不支持跨成员间的负载均衡负载均衡算法一致性问题这里建议实际测试后再上线。6. 学习数据链路层最常见的三个误解6.1 “数据链路层不路由”不等于不查表、不决策很多人说交换机是“傻瓜转发”这是一个误区。交换机不参与 IP 路由选择确实不做最长前缀匹配但它的转发过程有明确的决策逻辑查 MAC 地址表、比较 VLAN、处理未知单播、处理广播包。这些动作都属于数据链路层的转发决策。区别在于路由是基于全网拓扑计算路径而二层交换只基于本地 MAC 表做逐跳转发。在现实场景里三层交换机会同时做二层交换和三层路由但这不意味着二层转发过程变简单了。帧进来后先判断目的 MAC 是否是本机接口的 MAC是则剥掉帧头交给三层处理不是则查二层转发表。这个判定过程也是数据链路层的核心工作。6.2 交换机转发时改不改 MAC 地址许多初学者把“路由器会改 MAC”和“所有设备都会改 MAC”混在一起。事实上交换机转发帧时不会修改帧里的源 MAC 和目的 MAC。它只做一件事根据目的 MAC 查表然后从合适的端口原样复制转发帧。这也是为什么抓包时在同一个二层域内看到帧的源和目的 MAC 始终不变。但跨网段通信时帧经过路由器后源 MAC 和目的 MAC 都会改变源 MAC 变成路由器出接口的 MAC目的 MAC 变成下一跳设备的 MAC。而 IP 地址不变。所以如果抓包发现某一个报文的 MAC 和 IP 对不上先别急着怀疑 ARP可能是经过了三层设备帧被重新封装了。6.3 CRC 与 TCP 校验和作用范围完全不同数据链路层的 FCSCRC-32校验范围是本帧内容它保证的是“这一条链路上传输的帧没有检测到错误”。IP 数据报跨越多个链路时每一段链路的帧都会被重新封装重新计算 FCS也就是说数据链路层的差错检测是逐段的。TCP 的校验和则是从应用层数据到 TCP 头部的端到端校验中间任何一段出错TCP 都能发现。这个区别解释了数据链路层的一个关键定位它保证的不是端到端的可靠传输而是链路级交付质量。端到端的重传、排序、按序交付是传输层的工作。学习时把“链路内检错”和“端到端确认”分开很多协议设计逻辑就顺了。数据链路层是几层模型里技术细节最密集、也最贴近硬件的一层。学的时候不要只看教材里的抽象流程有条件就用抓包工具看一眼真实的 ARP 请求、VLAN 标签和以太网帧头感受一下物理世界和逻辑世界的交界处发生了什么。这些底层细节在实际排障中非常值钱。
阅读完成 · 觉得有帮助?
咨询建站