
做网络这一行做久了我养成了一个习惯不管排查什么问题第一件事永远是打开抓包工具瞄一眼链路层。很多人不理解说你查TCP重传、看应用层超时跟链路层有什么关系但我的经验恰恰相反——TCP/IP协议栈里的链路层也叫数据链路层、Layer 2是最多人不重视、却最容易出问题的环节。大家聊起IP地址、TCP三次握手、HTTP状态码都头头是道但一问到MAC地址怎么来的、以太网帧头部那14个字节是什么、MTU为什么偏偏是1500很多人就含糊了。尤其现在做物联网、工业控制的朋友天天跟MQTT、Modbus、CAN协议打交道这些协议再怎么花哨最终都要落到链路层的帧上才能传到对端。你要是链路层的基本功不扎实上层调得再熟练出了问题照样抓瞎。这篇东西不打算照抄教科书我想用我这些年实际抓包和排障的经验把链路层重新捋一遍。看完你至少能回答三个问题链路层到底负责什么、以太网帧里每个字段有什么用、碰上链路层故障该从哪儿下手。1. 链路层到底在干什么先把它放到整个协议栈里看明白1.1 用寄快递的类比理解链路层职责TCP/IP协议栈通常被分成四层或者五层链路层在最底下。很多人学的时候总喜欢从应用层往下背背到链路层就草草带过这是一个很大的误区。我用寄快递来打个比方。应用层是你手里要寄的东西可能是网页请求、MQTT消息或者一段Modbus报文传输层TCP/UDP是运单上的单号和收寄件人信息解决这份货该交给哪个应用的问题网络层IP是运输路线规划解决货从哪个城市送到哪个城市的问题而链路层就是那辆货车、那条公路、那个驿站解决的只有一个朴素的问题——两个直接相连的接口之间怎么把数据正确搬过去。注意直接相连这四个字。IP层可以管你从北京到广州的路由但实际传输时数据是一跳一跳走的北京的路由器到天津的路由器天津到济南济南到广州。每一跳之间都是两个接口的直接通信这就是链路层的管辖范围。它不关心你的货最终给谁不关心路线怎么选只关心我这辆车这一段路怎么把货稳妥送到下一站。从数据流的角度看链路层做的事情非常机械网络层把IP报文datagram交给它它把报文封装成一个帧frame加上帧头、帧尾然后通过物理介质网线、光纤、无线电波发出去。对端收到帧拆开帧头把里面的IP报文原封不动交给网络层。这个封装再解封装的过程就是链路层的日常。1.2 链路层要解决的三个核心问题把链路层的职责拆开看核心问题就三个。第一个是封装格式问题。我这一包数据发出去对端怎么知道从哪里开始、到哪里结束怎么知道里面装的是IPv4报文还是ARP报文这就需要一套统一的帧格式规定了帧头、负载、帧尾怎么排。以太网II帧格式就是现在最通用的答案后面我会逐字段拆。第二个是寻址问题。同一个物理网络里可能挂了十几台、上百台设备你发一个帧出去怎么让对方知道这是发给它的怎么让网卡判断这个帧是不是自己的这就引出了MAC地址。MAC地址媒体访问控制地址是每个以太网接口烧录的物理地址48位全球唯一理论上。正是靠它同一个网络里的设备才能精确地收发数据。第三个是差错检测问题。数据在物理链路上传输免不了受干扰、出噪声怎么发现一帧数据坏了以太网在帧尾放了一个FCS字段帧校验序列用CRC32算法对整个帧做校验。接收方算一遍对不上就把帧扔了。这个动作是在硬件层面完成的所以很多时候你根本感知不到但它的作用极其重要。除了这三个核心问题链路层还管一些你可能没注意过的事流量控制防止发送太快把对端冲垮、错误通知上层可能需要知道链路断了、以及半双工模式下的冲突检测CSMA/CD虽然交换机组网后基本用不到了但老工程师都知道这个概念。这里插一句很多人分不清二层和物理层。物理层一层管的是电压、光信号、线序、接口形状这些最底层的物理特性链路层二层管的是把物理层传过来的原始比特流组织成有意义的帧。学习抓包时看到的都是链路层及以上的内容物理层的东西一般看不到。2. 以太网帧链路层最绕不开的格式2.1 帧结构逐字段拆解在TCP/IP网络里以太网II帧也叫DIX帧是绝对的主流。它的结构简单到令人发指但就是这份简洁让它高效运行了几十年。一个完整的以太网帧长这样目的MAC地址6字节、源MAC地址6字节、EtherType2字节、负载46到1500字节、FCS帧校验4字节。先说MAC地址。48位的MAC地址前24位是OUI由IEEE分配给各厂商比如华为、思科、Intel都有自己的号段后24位由厂商自己分配保证同一个厂商出厂的网卡不重复。所以看到MAC地址的前三位基本就能猜到设备是谁家生产的。注意MAC地址里还有几个特殊位第一个字节的最低位是I/G位0代表单播地址、1代表组播或广播地址广播地址是全F也就是FF:FF:FF:FF:FF:FF表示这个帧要发给同一链路里的所有设备。然后是EtherType这个字段特别关键它决定了帧负载里装的什么协议。0x0800是IPv40x0806是ARP0x86DD是IPv6。抓包的时候Wireshark就是靠这个字段判断下一步怎么解析的。为什么需要它因为同一个链路上可能同时跑着好几种协议没有这个标签接收方就不知道该把负载交给谁。最后是FCS4字节的CRC32校验。发送时硬件算好填进去接收时硬件重新算一遍不一致就丢弃。注意网卡在硬件层就把校验做了校验失败的帧根本不会交给操作系统所以你在Wireshark里几乎看不到坏帧——不是网络上没有错误而是都被网卡默默扔了。这里有个很有趣的细节以太网规定最小帧长是64字节不含前导码。如果负载太短比如你发一个只有40字节的小包网卡会在负载后面自动补0到46字节数据不足时补齐凑够64字节。这个规定是当年CSMA/CD半双工时代传下来的为了保证一个站点在最短时间内把帧发完从而在冲突发生前就能检测到。以10Mbps以太网为例最远距离往返传播延迟大约需要51.2微秒的时隙这段时间内能发512bit也就是64字节。到了全双工交换网络时代这个限制理论上可以放宽但为了兼容性至今仍然保留。2.2 MTU为什么重要1500这个数字是全网的隐形规则以太网帧负载上限是1500字节这个最大传输单元MTU值大概是整个互联网最重要的隐形规则之一。任何IP报文如果长度超过下一跳的MTU就会触发分片一个大的IP报文被切成多个小碎片分别发送接收端再重组。这看着不难但分片会导致性能下降而且某些网络设备对分片包处理有bug可能直接丢弃。更麻烦的是如果IP报文的DF位不允许分片标志被置1那超长的报文根本发不出去只会收到一个ICMP错误消息需要分片但禁止分片。那TCP是怎么配合MTU的这就是MSS最大报文段长度的来历。TCP建立连接时双方在SYN包里交换MSS选项MSS的典型值就是MTU减去IP头部20字节再减去TCP头部20字节。标准以太网环境下MSS就是1460。如果中途有个PPPoE拨号链路MTU从1500变成1492PPP头部占了8字节MSS协商就应该调成1452。要是协商对不上就会出现一个经典怪症状小包畅通无阻大包死活过不去传文件卡死、网页加载一半。我处理过一个真实案例某项目的视频监控画面间歇性卡顿ping小包正常但ping -s 1472 -M do测试1500字节的大包在某个跳数之后就不通了。查了一路MTU发现中间有个隧道封装多占了8字节但路径上的ICMP不可达消息被防火墙吞了。TCP双方完全不知道路径MTU已经变小还在按1460的MSS发大包隧道封装后超过链路MTU被静默丢弃。后来在出口路由器上做了MSS钳制把TCP SYN里的MSS选项强制改小问题立刻消失。这就是典型的链路层参数影响传输层表现。顺便说一句巨帧Jumbo Frame。数据中心和存储网络iSCSI、NFS经常把MTU调到9000减少帧数量、降低CPU开销大文件传输性能提升明显。但巨帧有个前提整条链路上的所有设备包括交换机、网卡都必须开启相同或更大的MTU有一个不配合就会丢包。我见过不止一次为了性能开巨帧忘了广播域里还有台老打印机不支持结果全网传输出现诡异的偶发丢包。我的建议是不是所有业务都能开巨帧混合流量环境里更要谨慎别为了性能给自己埋雷。2.3 VLAN标签和802.1Q4字节带来的连锁变化标准以太网帧只有14字节的头部但交换机组网之后光靠MAC地址转发已经不够用了。你不想让所有部门的主机都在一个广播域里互相干扰怎么办VLAN虚拟局域网技术应运而生而它在链路层的实现就是802.1Q标签。802.1Q在源MAC地址和EtherType之间插了4个字节2字节的TPID固定是0x8100表示我是VLAN标签另外2字节主要包含12位的VLAN ID0到4095其中0和4095保留和3位优先级802.1p。注意插了这4字节之后原来的EtherType被往后推了4个字节整个帧的最大长度也变成了1522字节FCS重算。这就是为什么有些交换机的MTU配置里会有1518和1522两种数值——前者不带VLAN后者带。工程里常遇到的坑一个是Trunk口配置。交换机之间的Trunk链路要放行多个VLAN每个帧都要打上标签好让对端知道这个帧属于哪个VLAN。如果Trunk配置漏了VLAN ID或者PVID端口默认VLAN设置不一致就会出现某些VLAN能通、某些VLAN不通的诡异现象。另一个坑是抓包时看不到VLAN标签用普通PC网卡抓Trunk口多数网卡默认不识别带tag的帧需要开启混杂模式promiscuous mode并且Wireshark里要勾选正确的VLAN解析选项否则帧会被当作损坏数据丢弃或者解析错位。3. ARP链路层和网络层的桥梁3.1 ARP原理与完整交互流程说完以太网帧不得不讲ARP地址解析协议。它是链路层和网络层之间的粘合剂也是日常排障时绕不开的常客。ARP解决的是个非常实际的问题我知道对方的IP地址192.168.1.2但这个IP跟我之间怎么发数据以太网帧里不认IP地址只认MAC地址。所以必须想办法把IP地址翻译成MAC地址。这就好比你知道朋友的姓名但寄快递必须填他的门牌号你得先查一下门牌号是多少。完整流程是这样的主机A要给192.168.1.2发IP包先查自己的ARP缓存表Windows里用arp -a查看Linux也一样。缓存里有就直接用对应的MAC地址封装帧。缓存里没有怎么办A发送一个ARP请求帧目的MAC填广播地址FF:FF:FF:FF:FF:FF负载内容是谁是192.168.1.2请回复192.168.1.1——注意括号里填的是请求者的IP和MAC。这个广播会送到同一链路上的所有设备每台设备收到后都要看一眼问的是不是我的IP不是就默默丢弃。主机B发现问的正是自己就回一个ARP应答帧这次目的MAC是A的MAC单播内容是192.168.1.2的MAC地址是XX:XX:XX:XX:XX:XX。A收到后把映射写进ARP缓存然后才开始发真正的IP数据包。关键点在大写加粗ARP请求是广播ARP应答是单播ARP报文不经过IP层封装它直接坐在以太网帧的负载里EtherType0x0806。这个细节决定了抓包时看到的现象ARP帧里只有一个IP头部的影子都没有它就是纯粹的二层协议。3.2 ARP缓存、免费ARP、ARP欺骗ARP缓存老化时间不同系统差别不小。Windows动态ARP条目老化时间大概是15到45秒取决于最后一次使用时间Linux的gc_staletime默认是60秒。长期通信的条目会被刷新续期但如果你发现某个条目长时间不更新就要引起警惕了。免费ARPGratuitous ARP是ARP家族里一个有意思的角色。设备启动并配置好IP后会主动发一个ARP请求广播我的IP是X我的MAC是Y你们谁也别跟我抢。它的作用有两个一是通告全网我来了请更新你们的ARP缓存这在主备切换、服务器迁移场景里很常见二是地址冲突检测——如果同一网段里有人回复说你IP重复了说明冲突了操作系统会提示。但免费ARP也是一把双刃剑ARP欺骗靠的就是它。攻击者发送伪造的免费ARP宣称网关的IP对应的MAC是我全网主机的ARP缓存立刻被污染所有本来要发往网关的帧都被发给了攻击者。这种攻击在局域网里极其常见且难察觉因为IP通信看起来还是正常的只是流量全被截走了。防御手段一是做IP-MAC静态绑定二是交换机开DAIDynamic ARP Inspection配合DHCP Snooping使用让所有ARP报文都经过合法性校验。如果你的网络环境安全等级要求高这两件事值得认真对待。这里还要澄清一个很多初学者搞不懂的误区跨网段通信时ARP请求的对象不是最终目的主机而是网关。你ping对端网段的IP本机先发送的ARP请求问的是网关的MAC是多少而不是目的主机的MAC。帧头的目的MAC填的是网关的MAC到了网关再重新封装下一跳的帧。所以网络层地址与链路层地址的映射关系永远是当前这一跳的映射而不是全局的。这个理解不到位分析路径上的数据包就很容易晕。3.3 抓包实战亲手看一眼ARP帧长什么样看再多理论不如亲手抓一把。Linux下用tcpdumptcpdump -i eth0 arpWindows下用Wireshark过滤器直接写arp你会看到两条记录一条广播的ARP请求目的MAC是FF:FF:FF:FF:FF:FF一条单播的ARP应答。点开请求帧可以看到操作码是1request发送端MAC是主机自己的MAC发送端IP是自己的IP目标MAC全0目标IP是你正在解析的IP。应答帧的操作码是2reply四元组信息反过来填。报文总长28字节加上以太网帧头14字节和FCS 4字节整个帧也就46字节小得可怜。我排障时还常用一个技巧手动清空ARP缓存再抓包观察解析瞬间的交互能直接看出大网里有没有人在插手ARP。有一次我清完缓存 ping 网关发现应答帧的来源MAC不对一查才知道是某台设备中了招把网关的ARP条目给污染了。后来做了绑定问题根除。另外提一句交换机的ARP表show arp和三层的设备ARP表也可以查排查网关漂移、负载均衡故障时经常要用到。4. 链路层的其他成员不只是以太网4.1 点对点链路上的PPP和PPPoE以太网统治了局域网但链路层协议远不止它一个。点对点协议PPP就是另一个重要成员当年的拨号上网就是PPP大显身手的地方。PPP解决的是两个设备直接相连一条线路、一对接口场景下的链路层通信。它有两层工作先是链路控制协议LCP负责建立、配置、测试链路包括协商MRU最大接收单元、认证方式然后是网络控制协议NCP比如IPCP负责给拨号客户端分配IP地址。整个流程走下来链路才算真正可用。拨号时代PPP还流行过PAP和CHAP两种认证方式CHAP用挑战-应答机制密码不以明文传输安全性好得多。PPP的继任场景是PPPoEPPP over Ethernet目前很多宽带接入还在用。PPPoE把PPP帧封装进以太网帧里多出来的8字节开销导致PPPoE链路的MTU只有1492这就是前文讲MSS时提到的经典问题源头。现在运营商普遍通过PPPoE拨号下发IPv4和IPv6碰到这种环境你要牢牢记住1492这个数字很多大包不通的故障都跟它有关。4.2 无线网络中的802.11链路层无线局域网Wi-Fi的链路层和有线以太网差别很大。IEEE 802.11定义了复杂的帧体系除了数据帧之外还有管理帧Beacon信标、Probe探测、Association关联/解除关联和控制帧ACK确认、RTS/CTS。无线介质是共享的谁都能收到信号所以无线链路层要额外处理冲突避免CSMA/CA、隐藏节点问题靠RTS/CTS缓解、以及每个数据帧的链路层确认——注意Wi-Fi里的ACK是链路层确认跟TCP的确认完全不是一个概念。当你用Wireshark抓无线包时看到的管理帧数量通常比数据帧还多。那些Beacon帧每隔100毫秒就在那广播宣告SSID和支持的速率集。这意味着无线链路的开销比有线大得多也是为什么同等链路速率下无线实际吞吐远低于有线的原因之一。做无线排障时先扫信道干扰再看管理帧交互是否正常链路这一层不干净上层速率和延迟都会受影响。4.3 工业现场总线里的CAN与Modbus这几年物联网和工业自动化火起来之后CAN协议、Modbus协议的搜索量一直居高不下。很多人问我这些协议跟TCP/IP有关系吗我的回答是它们跟链路层的关系千丝万缕只是各自有不同的链路承载方式。CANController Area Network总线是典型的二层协议符合OSI的物理层和链路层定义。它跑在双绞线上不依赖以太网帧结构里有仲裁ID判断优先级、DLC数据长度、数据段、CRC。CAN的精髓是带优先级的总线仲裁多个节点同时发数据时ID小的帧自动获胜这个机制全在链路层完成效率极高。汽车、机器人、医疗设备里到处是CAN。如果你日常调试CAN看到的就是帧而不是包这就是链路层的视角。Modbus的情况更有代表性。Modbus RTU走串口RS-232/485在串口上自己定义帧格式地址码、功能码、数据、CRC校验。这种模式下没有以太网帧它自己的帧结构就充当链路层。而Modbus TCP把报文直接封装进TCP载荷底层走标准以太网帧。所以同样是ModbusRTU和TCP两种形态下链路层的差异巨大。学的时候不要混用的时候更要想清楚你手里的设备是在什么链路上跑的。顺带一提MQTT是应用层协议依赖TCP/IP。你在Wireshark里抓MQTT包往下拆就是TCP、IP、以太网帧。链路层基础不打牢你到底在哪个环节丢了数据根本分析不出来。5. 链路层故障排查实录踩过的坑和排查套路5.1 链路层排查的标准思路先物理再链路再网络干网络这行最忌讳一上来就翻应用配置、怀疑服务器代码。我的排查顺序从来都是物理层、链路层、网络层、传输层、应用层一层层往上走。先看物理链路端口指示灯是否正常用ethtool查看协商速率和双工模式ethtool eth0再查接口错误计数器看有没有超过正常范围的CRC错误、FCS错误、runts小于64字节的帧、giants超过1522字节的帧ip -s link show eth0交换机上对应命令是show interface show interface counters。如果CRC错误持续增长基本可以断定网线老化、线序不对、接头松动或者双工不匹配。双工不匹配是老生常谈但至今依然存在。一边是千兆全双工另一边协商成了百兆半双工链路显示up但延迟极高、丢包率吓人。检查双工状态是链路层排障的必修课。链路up但ping不通的时候先别急着看路由先把双工和错误计数看了再说。然后是抓包分析。抓包的目的是确认帧本身是否正常MAC地址对不对VLAN标签对不对有没有大量重传ARP交互是否正常如果抓包看到的帧干净利落问题大概率在上一层如果看到不断地重复ARP可能是IP冲突或者网关问题如果全是TCP重传链路层八成有丢包或乱序。5.2 三个典型故障案例分析先说案例一大包不通小包正常。某次客户报服务器同步数据经常中断ping网关64字节全通但ping -s 1472 -M do立即失败超时。按MTU链路排查的思路逐步降包大小发现在1400字节左右能通、1472字节不通。最后定位到中间有个隧道封装增加了8字节开销而路径上分片需要的通知被防火墙拦截TCP双方无法自动探测路径MTU。处理方案是在路由设备上做TCP MSS clamping强制把MSS钳到1400以内。问题消失传输恢复正常。这个案例最值得记住的一句话是MTU问题往往表现为TCP能建连但大块数据死活传不过去。再说案例二MAC地址漂移。某园区网频繁出现部分终端掉线交换机日志里刷屏MAC address 000c.29xx.xxxx has moved from GigabitEthernet0/1 to GigabitEthernet0/2。这就是MAC漂移同一个MAC地址在两个端口之间跳。可能的原因包括设备配置了双网卡绑定但聚合配置错误、交换机间存在环路生成树没拦住、虚拟机迁移后没有清老MAC地址表项。定位方法是在交换机上查mac-address-table确认漂移的MAC对应哪台设备然后沿数据路径逐跳排查。那次是客户新装了一台服务器部署了双网卡绑定绑定模式配错导致交换机看到两个端口都在发相同MAC的帧改掉绑定模式后清净了。第三个案例是ARP表里网关MAC异常。全网突然大面积断网物理链路和交换机端口都是正常的。一查客户端ARP表网关IP对应的是一个陌生的MAC地址——典型的ARP欺骗。临时先把网关IP静态绑定到正确MAC上恢复业务然后顺着接入交换机查DHCP Snooping和端口安全策略找出违规接入的设备收掉端口。事后在核心和接入交换机上启用了DAIDynamic ARP Inspection配合DHCP Snooping的绑定表对所有ARP报文做合法性校验这个隐患基本就堵死了。在很多无防护的局域网环境里ARP欺骗是中招最多的攻击方式之一不要觉得离自己很远。5.3 链路层排查知识点速查表症状可能原因检查方法解决办法小包通、大包不通MTU不一致、中间隧道封装、分片被禁ping -s 1472 -M do 逐次降包测试统一MTU、做MSS钳制延迟高且丢包双工不匹配、CRC错误累积ethtool 查速率/双工查接口错误计数强制双工、换线帧很小却反复消失网线过长、干扰、接头不良抓包看FCS错误可能被网卡丢弃换线、换模块、检查接地ARP表异常冲突、欺骗、缓存未刷新arp -a 对比正确网关MAC静态绑定、启用DAIMAC地址在两个端口反复出现环路、聚合配置错、虚拟机迁移show mac address-table 观察检查生成树、改绑定模式带VLAN的帧抓不到Trunk口配置、本机网卡不支持tag确认交换机端口类型开混杂模式配置正确的Trunk/PVID调整抓包模式这张表看着简单但每一条背后都是实打实的故障现场。我建议大家把这张表打印出来贴在工位上下次碰到网络问题先对号入座能少走很多弯路。最后说句实在话。链路层的东西门槛不高但水很深。帧结构、MTU、ARP每一个概念单独拿出来都不难难的是在真实的复杂环境里把它们串联起来。我做网络越久越觉得链路层是整个协议栈的地基——地基不稳上层再高级的技术也白搭。你不需要记住每一个过时的技术细节但一定要建立链路层意识通了不代表链路没问题延迟高可能不是服务器慢大包传不过去先查MTU。下次遇到疑难杂症不妨先打开抓包工具从最底下的链路层看起你会发现很多答案其实都写在那里。