说出来你可能不信,我第一次在ensp里做VLAN间通信实验时,花了两个多小时才把两台PC ping通。拓扑简单到不能再简单:一台交换机,一台路由器,两台PC,VLAN 10和VLAN 20。可就是这组配置,让我把交换机的端口模式、Trunk放行、子接口封装、ARP广播全部踩了个遍。今天就把单臂路由这件事彻底讲清楚。
单臂路由(Router-on-a-Stick)是计算机网络课程里跨VLAN通信的经典方案,也是很多人的“第一个跨三层实验”。它解决的问题非常具体:当一台二层交换机上划分了多个VLAN,这些VLAN之间默认是完全隔离的,二层设备交换不了跨VLAN的帧,于是我们需要引入路由器作为三层网关,用一条物理链路承载所有VLAN的流量,让数据在VLAN之间转发。适合谁看?正在复习计算机网络期末的学生,准备网络工程师认证的在考生,或者工作中第一次接触跨VLAN组网、想搞明白底层原理的新人。文章会从原理讲到配置,再讲到抓包验证和排错,保证你看完能自己复现一遍。
1. 为什么划分了VLAN之后,同一台交换机上的PC反而不通了
1.1 VLAN隔离的本质:广播域被切成了几块
要理解单臂路由,先得把VLAN给理解透。VLAN,虚拟局域网,本质上就是把一台物理交换机在逻辑上切成几台“虚拟交换机”。设备在同一个VLAN内,行为就像接在同一台普通交换机上一样,能互相通信、共享广播;设备在不同VLAN里,即使物理上插着同一台设备,彼此也“看不见”。
这里有个初学者最容易忽略的点:VLAN隔离的不只是广播,而是整个二层转发域。广播帧、组播帧、未知单播帧,统统只能在同一个VLAN内部泛洪。VLAN 10里的ARP请求,VLAN 20的端口根本收不到;VLAN 20里有人发一个全F的广播帧,VLAN 10的PC也无感知。这就是“广播域隔离”的真实含义。
但隔离的不只是广播。它的设计初衷确实是为了缩小广播域、提升安全性,可是副作用也很明显——不同VLAN之间如果需要通信,二层交换机自己搞不定。这个“搞不定”不是技术上的小缺陷,而是架构上的必然选择。
1.2 二层交换机做不了跨VLAN转发,根子在“三层决策”
我们来看一个具体的例子:交换机上有两台PC,PC1在VLAN 10,接的是G0/0/2口,IP是192.168.10.2/24;PC2在VLAN 20,接的是G0/0/3口,IP是192.168.20.2/24。两台PC插在同一台交换机上,线序全对,PC1去ping PC2,结果是请求超时。
为什么?因为二层交换机的转发依据是MAC地址表。PC1发出一个目的IP为192.168.20.2的数据包,它发现这个IP和自己不在同一个网段(192.168.10.0/24 vs 192.168.20.0/24),于是它会把数据包交给默认网关。可问题来了——PC1压根没有网关,因为所有设备都挂在二层交换机下面,没有人给它提供三层出口。就算PC1强行把数据包发给某个MAC地址,交换机查MAC表时发现目的MAC不在VLAN 10的任何端口上,它也不会把帧从一个VLAN“搬”到另一个VLAN。
说得再直白一点:跨VLAN通信的本质是跨网段通信,而跨网段通信需要IP路由决策。二层交换机没有路由表,不关心IP头里的目的地址,它只认识帧头和MAC。要让数据在VLAN之间流动,必须有一个三层设备参与,干一件事——给每个VLAN提供一个网关地址,然后根据目的IP做路由转发。
这个“必须有三层设备参与”的观念,是整个单臂路由实验的起点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 单臂路由是怎么把“一条物理链路”玩出多个网段的
2.1 “单臂”的含义:为什么要让一个口干多个口的活
在没有单臂路由之前,最笨的办法是这么做的:路由器上准备两个物理接口,一个接到交换机的VLAN 10 Access口,另一个接到交换机的VLAN 20 Access口,然后在两个物理接口上分别配IP作为两个VLAN的网关。数据从一个VLAN进来,路由器转发到另一个物理接口出去。这种方案能不能跑通?能,但蠢。VLAN一多就露馅了——10个VLAN需要10个物理接口加10根网线,20个VLAN就需要20个接口,交换机上还得给每个VLAN预留一个独立的Access口,这既不经济也不现实。
单臂路由的思路就巧妙在这里:路由器和交换机之间只保留一条物理链路,所有VLAN的流量都在这条链路上“挤”过去。交换机这一侧把连接路由器的端口配成Trunk口,允许放行多个VLAN;路由器这一侧在一个物理接口上创建多个子接口,每个子接口对应一个VLAN,并配置该VLAN网段的网关IP。整个设备看起来只有“一条手臂”伸到交换机上,却同时管理者多个VLAN的三层通信,所以叫单臂路由,英文叫Router-on-a-Stick。
每次讲到这里我都会用一个类比:单臂路由就像一栋楼只有一个大门,但楼里的每个单元在大门内都有自己的信报箱。快递员从大门进来,根据包裹上的单元号投到对应的信报箱,不用每个单元单独开一个门。VLAN的tag就是包裹上的单元号。
2.2 子接口、802.1Q终结、ARP广播:三个概念必须连起来看
单臂路由的实现有几根支柱,缺一根整个结构就塌。第一根是Trunk链路。交换机和路由器之间的链路必须是Trunk模式,否则交换机会把从路由器收到的帧当成普通Access帧,强行打上PVID对应的VLAN tag,或者把tag剥掉,导致VLAN信息丢失。只有Trunk口才能完整保留802.1Q标签在链路上传输。
第二根是子接口。路由器的物理接口默认只能识别不带tag的普通帧,它自己并不知道802.1Q里的VLAN ID是什么意思。子接口的作用就是让路由器能“理解和区分”不同VLAN的帧。华为设备上创建子接口后,必须用 dot1q termination vid 10 声明这个子接口终结哪个VLAN。路由器从物理口收到一个带tag的帧,通过识别VID,把它交给对应的子接口处理,然后剥掉tag,还原成普通IP报文,交给上层协议栈。这个过程叫“VLAN终结”。思科设备上对应的配置是 encapsulation dot1Q 10,概念完全一样,命令长得不一样而已。
第三根最容易被忽略,就是ARP广播。子接口是逻辑接口,很多人以为配完IP就能响应ARP,但在华为ensp里如果不额外配置 arp broadcast enable,PC发往网关的ARP请求会“石沉大海”。原因在于子接口默认对收到的广播ARP请求不做响应,必须显式开启ARP广播处理。这一点在真机上有些平台默认是开的,但ensp里非常坑,经常是“配置全对,就是ping不通网关”的幕后黑手。
2.3 为什么单臂路由现在还没被淘汰
一定会有人问:现在生产网里不都用三层交换机VLANIF做网关吗?单臂路由是不是过时了?三层交换机在性能上确实碾压单臂路由,这个我们不抬杠。我用一张表把两者的区别总结一下:
| 对比项 | 单臂路由 | 三层交换机VLANIF |
|---|---|---|
| 三层转发主体 | 路由器CPU软件转发 | 交换芯片硬件转发 |
| 性能上限 | 低,受CPU和单链路带宽限制 | 高,可线速转发 |
| 链路利用率 | 所有VLAN共享一条Trunk链路 | 通常随架构灵活分布 |
| 适用场景 | 实验学习、小型网络、临时组网 | 生产网、中大型园区网 |
| 配置复杂度 | 低,概念清晰 | 中,需要理解VLANIF与路由表结合 |
但单臂路由一直没有被淘汰,有三个原因。第一,学习价值高。它把VLAN tag、Trunk、子接口、ARP、路由这几个核心概念串联在一条完整的数据流里,是理解后面所有网络技术的地基。第二,成本优势。在一些小型分支机构、实验环境,一台旧路由器加一台二层交换机就能完成跨VLAN互通,没必要上三层交换机。第三,这种“一个物理口拆多个逻辑子接口”的玩法,在很多软路由、家庭网关、单线复用场景里广泛使用,搞懂单臂路由,再去看那类配置就是一通百通。
3. 用ensp完整复现单臂路由:交换机和路由器的配置命令逐条拆解
3.1 拓扑和地址规划:动手之前先想清楚“谁是谁的网关”
实验拓扑非常经典,也推荐大家照着搭:一台AR2220路由器,一台S5700二层交换机,两台PC。PC1接在交换机的G0/0/2口,属于VLAN 10,IP地址192.168.10.2,掩码255.255.255.0,网关192.168.10.1;PC2接在交换机的G0/0/3口,属于VLAN 20,IP地址192.168.20.2,掩码255.255.255.0,网关192.168.20.1。交换机的G0/0/1口连接路由器的G0/0/0口,链路类型为Trunk,放行VLAN 10和20。
这里有几个设计层面的细节需要提前说清楚。网关地址一定不能和PC地址冲突,也不能随便乱填,它必须落在路由器子接口上,并且和PC在同一网段。比如VLAN 10的网关是192.168.10.1,那么路由器的子接口G0/0/0.10就必须配192.168.10.1/24,两者一一对应。如果网关和子接口网段对不上,PC会一直认为网关不可达。
还有一个容易忽略的点:Trunk口的PVID。华为交换机上Trunk口默认PVID为1,且默认放行VLAN 1。做单臂路由实验时,我强烈建议不要修改Trunk口的PVID,保持默认。如果你手贱把PVID改成10,那么从交换机发出的不带tag的帧全部会被打上VLAN 10的tag,路由器子接口收到这些帧时会用VLAN 10去匹配,一旦帧的来源不属于VLAN 10,就会产生莫名其妙的通信故障。
3.2 交换机侧配置:VLAN划分和Trunk放行
打开ensp,启动设备后先在交换机上完成基础配置。命令行如下:
code复制system-view
sysname SW1
vlan batch 10 20
interface GigabitEthernet0/0/1
port link-type trunk
port trunk allow-pass vlan 10 20
interface GigabitEthernet0/0/2
port link-type access
port default vlan 10
interface GigabitEthernet0/0/3
port link-type access
port default vlan 20
每条命令我拆开解释一下。vlan batch 10 20 是批量创建VLAN,如果不执行这一步,后面Trunk口想放行VLAN 10和20就是无源之水。port link-type trunk 把连接路由器的口设为Trunk,port trunk allow-pass vlan 10 20 表示允许VLAN 10和VLAN 20的帧通过这条链路。这里有个概念要拎清:Trunk口默认只放行VLAN 1,如果不显式allow-pass,其他VLAN的帧会被交换机丢弃,这是实验里最常踩的坑之一。
连接PC的两个口就简单多了,Access口加上默认VLAN就完事。port default vlan 10 的意思是:这个Access口收到的所有无tag帧都打上VLAN 10的tag,发送时再把tag剥掉送给PC。PC是感知不到VLAN tag的,它只认为自己在一个普通的局域网里。
配置完成后可以用 display vlan 查看VLAN 10和20是否存在、端口成员是否正确,再用 display port vlan 看一下G0/0/1口的链路类型、PVID和放行VLAN列表,确认无误后再去配路由器。
3.3 路由器侧配置:子接口、dot1q终结和网关地址
路由器这台设备,物理接口是G0/0/0,我们不需要在这个物理口上配IP,直接在上面创建子接口。完整配置如下:
code复制system-view
sysname R1
interface GigabitEthernet0/0/0.10
dot1q termination vid 10
ip address 192.168.10.1 255.255.255.0
arp broadcast enable
interface GigabitEthernet0/0/0.20
dot1q termination vid 20
ip address 192.168.20.1 255.255.255.0
arp broadcast enable
注意几个关键点。第一,子接口编号可以自己定,比如G0/0/0.10里的“10”和VLAN ID保持对应纯粹是为了可读性,你写成G0/0/0.1、G0/0/0.100都不影响通信,但建议保持一致,方便日后维护。第二,dot1q termination vid 10 是子接口的灵魂,它告诉路由器这个逻辑接口处理哪个VLAN的帧,必须和交换机侧划分的VLAN ID对得上。第三,ip address 必须是对应VLAN网段的网关地址,注意子网掩码是24位,PC的掩码也是24位,两者的网段才能匹配上。
最后,arp broadcast enable 这一行千万不能省。在ensp的AR路由器上,子接口默认不对ARP广播请求进行响应,如果不开启,PC ping网关时会一直显示请求超时。这不是配置错误,是模拟器对子接口ARP行为的默认限制。很多人在这一步卡住,反复检查IP、VLAN、Trunk都没问题,最后发现就是少了这条命令。
3.4 用display命令验证基础配置
配置完成后不要急着去ping,先做三件事。第一,在路由器上执行 display ip interface brief,查看子接口状态是否为Up,IP地址是否生效。第二,执行 display arp interface GigabitEthernet0/0/0.10,看子接口10是否学习到了PC1的ARP表项。如果这里已经有了,说明PC1和路由器之间的二层链路是通的。第三,回到交换机上执行 display vlan,确认所有端口都在正确的VLAN里。
这套“先看状态,再测连通”的习惯,能帮你省下大量盲目排错的时间。状态不正常时,任何ping的结果都是不可信的。
4. 抓包看一次真正的跨VLAN通信:从ARP请求到ICMP回包
4.1 抓包前必须先想通的两个“反转”
当你配置全部完成,PC1能ping通PC2之后,建议你打开ensp的抓包功能,在交换机和路由器之间的Trunk链路上抓一次包。抓包之前,有两个容易把人绕晕的点必须先想明白。
第一个反转发生在ARP阶段。很多人以为跨VLAN通信时,ARP请求会跨VLAN去找对端PC,其实完全不是。PC1要访问192.168.20.2,但它发现目标和自己不在同一网段,于是它只发一个ARP请求:询问192.168.10.1的MAC地址,也就是网关的MAC。这个ARP请求只在VLAN 10内广播,不会跑到VLAN 20去。PC1拿到网关MAC后,把IP数据包封装在以太网帧里,目的MAC写的是网关的MAC,目的IP写的是PC2的IP。这里的“二层目的MAC”和“三层目的IP”不一致,正是跨网段通信的典型特征。
第二个反转发生在路由器出口。路由器从子接口10收到帧,剥掉VLAN 10的tag,做完路由决策后,要把数据包从子接口20发出去。这时它会先查ARP表,找PC2的MAC地址;如果没找到,它会以子接口20的IP地址为源,发一个ARP请求,询问192.168.20.2的MAC。注意,这个ARP请求是路由器发出的,它在VLAN 20内广播,由交换机泛洪给PC2。也就是说,单臂路由的过程中,至少有两段ARP交互,一段在源VLAN,一段在目的VLAN。
4.2 PC1 ping PC2的完整数据流:七步走
把整个过程串成七步,每一步在抓包里都能看得到:
- PC1判断192.168.20.2与自己不在同一网段,将数据包交给网关192.168.10.1。
- PC1发送ARP广播,请求192.168.10.1的MAC。交换机将请求在VLAN 10内泛洪,并通过Trunk口送给路由器。
- 路由器子接口G0/0/0.10响应ARP应答,告知自己的MAC。PC1的ARP表新增一条记录:192.168.10.1对应的MAC。
- PC1封装ICMP请求帧,源MAC为自身,目的MAC为网关MAC,交换机收到后打上VLAN 10的tag,经Trunk口发给路由器。
- 路由器匹配子接口10,剥离VLAN tag,还原IP包,查询路由表,发现192.168.20.0/24是子接口20的直连网段。
- 路由器检查ARP缓存,没有PC2的MAC就发ARP请求,拿到后可封装新帧,源MAC改为子接口20的MAC,目的MAC改为PC2的MAC,并打上VLAN 20的tag,经Trunk口送回交换机。
- 交换机剥掉VLAN 20 tag,从G0/0/3口将帧送给PC2,PC2回ICMP响应,整个流程反向再来一遍。
在Trunk链路抓包时,你会看到ICMP请求帧的802.1Q头里VID是10,ICMP应答帧的VID是20。这里要提醒一下:tag只存在于Trunk链路上。如果你抓PC1的Access口,抓到的帧是干干净净没有任何VLAN字段的;只有到了交换机和路由器之间的Trunk段,VLAN tag才会出现。很多新手在这里容易犯迷糊,看到PC1口上抓不到VLAN信息就以为自己配错了,其实不是,Access口本来就不带tag。
4.3 真机上的一个额外提醒:子接口MAC机制
在ensp里你可能注意不到,单臂路由的数据包经过路由器时,源MAC会被改写为出接口对应子接口的MAC。华为设备的子接口默认共用物理接口的MAC地址,所以从子接口10进来、子接口20出去的帧,源MAC会从“网关的MAC”被改成“同一个物理口的MAC”。这在实际抓包时会看到源MAC和目的MAC都在变化,不要觉得是异常的环路或重复帧。思科设备上子接口同样共用物理MAC,基于MAC做安全过滤时要注意这一点。
5. 单臂路由高频率翻车场景与排查思路
5.1 场景一:VLAN 20的帧永远到不了路由器
最典型的现象是PC1能ping通自己的网关192.168.10.1,但ping不通192.168.20.1,更ping不通PC2。能通网关,说明PC1到路由器子接口10的链路是完好的,问题大概率出在VLAN 20相关的那段链路上。
我按经验列出几个高频原因。一是交换机上忘记创建VLAN 20,display vlan 里只有VLAN 10,Trunk口放行列表里即使显示允许VLAN 20,实际上VLAN 20也不存在,帧无法处理。二是Trunk口只放行了VLAN 10,没有 port trunk allow-pass vlan 20,带VLAN 20 tag的帧一进入Trunk口就被丢弃。三是路由器子接口20的 dot1q termination vid 写错了,比如写成 vid 200,路由器根本认不出VLAN 20的帧。四是子接口20的IP地址网段和PC2不在同一段,比如子接口配的是192.168.30.1,PC2的网段是192.168.20.0/24,那路由器即使收到了帧也无法把它路由给PC2。
排查建议:在路由器上执行 display ip interface brief 确认子接口都是Up且有正确IP;再到交换机执行 display vlan 和 display port vlan 确认VLAN和放行列表都对得上。整个过程从交换机Trunk口一步步往路由器侧捋,很快就能定位。
5.2 场景二:PC能ping通网关,却ping不通对端PC
这是个很有迷惑性的故障,因为“网关能通”让你误以为网络是通的,但对端PC就是没反应。这时候要冷静下来,沿着数据流的后半段查。
先查路由器的ARP表,display arp interface GigabitEthernet0/0/0.20,看有没有学到PC2的MAC。没学到,说明路由器发出的ARP请求没能到达PC2,问题可能出在交换机的Trunk放行或者PC2的网线连接上。学到了但ping不通,问题可能出在PC2本身。最常见的情况是PC2没有配置网关,PC2收到ICMP请求后,想回包时发现自己算不出回程路由——源IP是192.168.20.2,目标IP是192.168.10.2,不在同一网段,它想把回包交给网关,但网关是空的,于是只能把包丢弃。所以,跨VLAN通信的两台PC都必须配置网关,网关指向各自VLAN的路由器子接口IP,这步千万不能漏。
还有一个真实环境中经常碰到的情况:PC2的防火墙拦截了ICMP。Windows系统默认允许ping,但有些安全软件会拦,测试的时候可以先临时关掉防火墙再试,避免在网络上白白排查半天。
5.3 场景三:ensp里子接口ARP不通,所有配置看着都对
如果你在ensp里发现PC一直ping不通网关,路由器子接口的ARP表也是空的,但配置逐条比对都没问题,优先检查两件事。第一,子接口下有没有 arp broadcast enable,这个前面已经反复强调,是ensp模拟器最常见的坑。第二,路由器的物理接口是不是被shutdown了。有些时候在拖拽设备、连线的时候,物理口会进入Down状态,子接口配置得再漂亮,物理口起不来一切都是空的。
再补充一个容易忽略的操作层面问题:PC的IP配置完成后,Windows系统会缓存网关的ARP信息,如果你改过路由器的MAC地址或者调整过子接口配置,建议在PC上执行 arp -d 清一下缓存再重新ping,否则可能出现“配置明明改了但行为还是旧的一样”的假象。
5.4 场景四:真机上单臂路由“时通时断”,性能越用越差
在ensp里一般不会遇到性能问题,但在真机上单臂路由有一个天然的瓶颈:所有VLAN的流量都挤在同一条物理链路、同一个物理接口上,并且全部经过路由器CPU软转发。当VLAN数量多、流量大时,这根“单臂”很容易成为性能瓶颈,表现为通信延迟变大、丢包率上升,甚至时通时断。
如果你在真实网络中一定要用单臂路由,我有几个建议。第一,物理链路至少要百兆起步,千兆更好,不然很难撑住多VLAN的汇聚流量。第二,路由器的CPU型号和转发性能要有富余,低端路由器跑单臂路由非常吃力。第三,如果VLAN数量超过十几个、流量又比较规律,建议尽早切换到三层交换机VLANIF方案,或者采用“网关下移”的思路,把三层网关放到汇聚交换机上,路由器只干它擅长的上联NAT和策略控制。单臂路由在小规模实验和临时组网里非常好用,但别把它硬扛到一个大流量生产网上,那是在给自己埋雷。
最后再说一个我自己的实操习惯。每次做完单臂路由实验或者排查完跨VLAN故障,我都会顺手把PC上的ARP缓存清掉,然后在路由器上执行 reset arp all,再从头ping一遍。很多“时好时坏”的假故障,其实都是ARP表缓存了过期的MAC映射导致的。把缓存清干净,让整个数据流重新从ARP开始跑一遍,你才能看到最真实的结果。这个习惯帮我省过无数次的冤枉路,建议你也试试。
