Linux 数据链路层详解以太网帧、MAC 地址、MTU 与 ARP 协议摘要数据链路层解决的是相邻节点之间如何传递数据的问题。网络层负责规划端到端路径而数据链路层负责把数据交给“下一跳”。本文围绕以太网展开讲清以太网帧格式、MAC 地址、MTU 对 IP/UDP/TCP 的影响以及 ARP 如何完成 IP 地址到 MAC 地址的映射。前言前面理解网络层时我们经常说“路由器把 IP 数据包转发给下一跳”。但这里还有一个更具体的问题下一跳知道了网卡到底把这一帧发给谁这就是数据链路层要解决的问题。网络层关注的是从源主机到目标主机的整体路径数据链路层关注的是同一种链路上相邻设备之间的一段传递。换句话说IP 地址描述的是“整段旅程”的起点和终点MAC 地址描述的是“每一小段路”的起点和终点。一、数据链路层负责什么数据链路层用于两个相邻设备之间传递数据。这里的相邻不一定表示两台设备物理上挨着而是指它们处在同一种链路技术可以直接通信的范围内。可以把一次跨网络通信拆成这样源主机路由器 A路由器 B目标主机从网络层看目标是把数据从源 IP 送到目的 IP从数据链路层看每一跳都需要重新封装链路层帧视角关注点网络层源 IP、目的 IP、路由选择数据链路层源 MAC、目的 MAC、相邻节点传输所以IP 地址一般在端到端过程中保持方向意义而 MAC 地址会随着每一跳转发不断变化。二、认识以太网以太网不是某一个具体网络而是一套局域网技术标准。它既包含数据链路层的内容也涉及部分物理层内容例如网络拓扑、访问控制方式、传输速率、线缆规范等。常见以太网速率包括10M、100M、1000M以太网是当前非常常见的局域网技术。和它并列的还可以有令牌环网、无线 LAN 等其他技术。三、以太网帧格式以太网传输的基本单位叫帧。典型以太网帧结构如下------------------------------------------------- | 目的 MAC | 源 MAC | 类型 | 数据 | CRC | ------------------------------------------------- | 6 字节 | 6 字节 |2字节 | 46~1500 字节 |4字节| -------------------------------------------------各字段含义字段长度作用目的 MAC 地址6 字节表示这一帧要交给哪个相邻节点源 MAC 地址6 字节表示这一帧从哪个相邻节点发出类型2 字节标识上层协议如 IP、ARP、RARP数据46~1500 字节承载上层数据CRC4 字节用于帧校验类型字段常见取值类型值含义0x0800IP 数据报0x0806ARP 请求/应答0x8035RARP 请求/应答以太网帧中的数据部分有最小长度要求。如果上层数据不足 46 字节需要填充到最小长度。四、MAC 地址相邻节点的硬件地址MAC 地址用于识别数据链路层中相连的节点。它长度为 48 位也就是 6 字节通常用十六进制加冒号表示08:00:27:03:fb:19一般情况下MAC 地址在网卡出厂时就被固化通常具有唯一性。不过虚拟机中的 MAC 地址可能并不是真实硬件地址也可能出现冲突部分网卡也允许用户手动配置 MAC 地址。MAC 地址和 IP 地址的区别很多初学者会把 MAC 地址和 IP 地址混在一起。它们的定位完全不同对比项IP 地址MAC 地址所属层次网络层数据链路层作用范围描述端到端通信方向描述当前链路上的相邻节点是否逐跳变化通常不随每一跳变化每经过一跳都会重新封装典型问题数据包最终去哪里当前这一帧交给谁举个直观例子从家里寄快递到外地IP 地址像最终收件地址MAC 地址像每一段运输交接时的站点地址。快递最终目的地不变但每一段交给谁会变。五、MTU一帧最多能装多少数据MTU 是 Maximum Transmission Unit最大传输单元。它描述某种链路层网络一次最多能承载多少上层数据。以太网中数据字段最大是 1500 字节所以常见以太网 MTU 是1500 字节可以把 MTU 理解成快递包裹尺寸限制。不同链路技术的限制可能不同。如果一个数据包从以太网转发到 MTU 更小的链路就可能需要分片。查看网卡地址和 MTUifconfig新系统中也常用iplink六、MTU 对 IP 的影响由于链路层 MTU 限制较大的 IP 数据报可能需要分片。分片过程大致如下较大的 IP 数据报按 MTU 切成多个分片每个分片带相同 16 位标识通过标志位和分片偏移描述位置接收端按顺序重组IP 分片会用到 IP 首部中的几个字段字段作用16 位标识同一个原始数据报的多个分片使用相同标识标志字段表示是否允许分片、是否还有更多分片分片偏移表示当前分片在原始数据报中的位置需要特别注意只要任意一个分片丢失接收端重组就会失败。而 IP 层本身不负责重传这会把问题继续交给上层处理。七、MTU 对 UDP 的影响UDP 本身面向数据报如果 UDP 携带的数据太大就可能在网络层被拆成多个 IP 分片。以常见以太网 MTU 1500 为例最大 UDP 载荷 1500 - 20(IP 首部) - 8(UDP 首部) 1472 字节如果 UDP 携带的数据超过 1472 字节就可能被拆成多个 IP 数据报。任意一个分片丢失整个 UDP 数据报都无法被正确重组。这也是为什么实际写 UDP 程序时不建议把单个 UDP 包做得太大。报文越大分片概率越高整体丢失概率也越高。八、MTU 对 TCP 的影响TCP 的数据段也不能无限大同样受 MTU 限制。TCP 中有一个和 MTU 密切相关的概念MSS。MSS 是 Maximum Segment Size表示 TCP 单个报文段中应用数据的最大长度。在以太网 MTU 为 1500 的常见情况下如果不考虑额外选项MSS 1500 - 20(IP 首部) - 20(TCP 首部) 1460 字节TCP 建立连接时双方会在 SYN 报文中写入自己支持的 MSS 值。通信双方得知彼此的 MSS 后通常选择较小值作为最终 MSS。这个设计的目标是尽量让 TCP 段在发送时不触发 IP 分片从而降低重组失败和性能损耗。概念含义MTU链路层一次可承载的最大上层数据长度MSSTCP 单个报文段可承载的最大应用数据长度关系MSS 通常受 MTU 约束九、ARP 协议从 IP 找到 MAC在发送网络数据时应用程序通常知道目的 IP 和端口但网卡真正发送以太网帧时需要目的 MAC 地址。问题来了我知道对方 IP怎么知道对方 MACARP 就是为了解决这个问题。它建立主机 IP 地址和 MAC 地址之间的映射关系。ARP 介于网络层和数据链路层之间。它服务于 IP 通信但发送时又依赖以太网帧广播。十、ARP 工作流程假设源主机想知道192.168.0.1对应的 MAC 地址流程如下目标主机本地网段源主机目标主机本地网段源主机ARP 请求谁是 192.168.0.1广播到本地网段ARP 应答我的 MAC 是 xx:xx:xx:xx:xx:xxARP 请求使用广播 MAC 地址FF:FF:FF:FF:FF:FF本地网段内所有主机都能收到这个广播但只有 IP 地址匹配的主机会回复 ARP 应答。每台主机都会维护 ARP 缓存表可以通过命令查看arp-aARP 缓存表中的条目有过期时间。这样做有两个原因避免每次通信都广播 ARP 请求提高效率防止网络环境变化后长期使用过期映射。十一、ARP 报文格式ARP 报文中包含硬件类型、协议类型、地址长度、操作类型、发送端地址、目标地址等字段。简化结构如下-------------------------------- | 硬件类型 | 协议类型 |硬长 |协长 | -------------------------------- | op | 发送端 MAC 地址 | ----------------------------------- | 发送端 IP 地址 | ----------------------------------- | 目的 MAC 地址 | ----------------------------------- | 目的 IP 地址 | -----------------------------------关键字段字段含义硬件类型链路层网络类型1表示以太网协议类型要转换的地址类型0x0800表示 IP 地址硬件地址长度以太网地址为 6 字节协议地址长度IPv4 地址为 4 字节op1表示 ARP 请求2表示 ARP 应答在以太网环境中源 MAC、目的 MAC 会同时出现在以太网首部和 ARP 报文中看起来有些重复。但 ARP 不是只为以太网设计的在其他链路层网络中这些字段仍然有意义。十二、常见问题与易错点1. 认为 MAC 地址能跨网络定位目标主机MAC 地址只解决当前链路上的相邻节点通信。跨网络通信时真正规划路径的是 IP 和路由表。2. 把 MTU 和 MSS 混为一谈MTU 是链路层限制MSS 是 TCP 数据长度限制。MSS 通常由 MTU 推导出来但二者不在同一层。3. UDP 包过大导致丢失概率升高UDP 数据一旦触发 IP 分片只要任意分片丢失整个数据报就无法重组。写 UDP 程序时要控制单包大小。4. 忽略 ARP 缓存过期ARP 缓存不是永久有效。网络变化、网卡替换、虚拟机迁移等情况都可能导致旧映射失效。5. 误以为 ARP 能跨网段广播ARP 请求广播只在本地网段内传播。访问外网时主机通常解析的是网关的 MAC 地址而不是远端服务器的 MAC 地址。总结数据链路层负责相邻节点之间的数据传递。以太网通过帧格式封装目的 MAC、源 MAC、类型、数据和 CRCMAC 地址用于标识当前链路上的节点MTU 限制单帧可承载的数据大小并影响 IP 分片、UDP 报文大小和 TCP MSSARP 则负责在本地网段内根据 IP 地址获取 MAC 地址。把它和网络层放在一起看就很清楚了IP 决定数据包最终去哪里路由决定下一跳是谁数据链路层再把这一跳封装成以太网帧发出去。每经过一跳链路层首部都会重新封装而 IP 层的端到端方向仍然保持不变。